Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vdpa/virtio: Add support for virtio-blk for vdpa driver #4

Merged
merged 2 commits into from
Jul 4, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions drivers/common/virtio/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@ deps += ['pci', 'bus_pci', 'ethdev']
sources += files(
'virtio.c',
'virtio_pci.c',
'virtio_pci_net.c',
'virtio_pci_blk.c',
)

2 changes: 2 additions & 0 deletions drivers/common/virtio/virtio.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef _VIRTIO_H_
#define _VIRTIO_H_
#include "virtio_net.h"
#include "virtio_blk.h"

/*
* Do we get callbacks when the ring is completely used,
Expand Down Expand Up @@ -107,6 +108,7 @@ struct virtio_hw {
uint8_t weak_barriers;
uint8_t intr_lsc;
uint16_t max_queue_pairs;
uint16_t num_queues_blk;
struct virtnet_ctl *cvq;
struct rte_pci_device *pci_dev;
const struct virtio_ops *virtio_ops;
Expand Down
141 changes: 141 additions & 0 deletions drivers/common/virtio/virtio_blk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) 2022 NVIDIA Corporation & Affiliates
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also include this file in virtio.h, just like virtio_net.h

*/

#ifndef _VIRTIO_BLK_H
#define _VIRTIO_BLK_H

/* Feature bits */
#define VIRTIO_BLK_F_SIZE_MAX 1 /* Indicates maximum segment size */
#define VIRTIO_BLK_F_SEG_MAX 2 /* Indicates maximum # of segments */
#define VIRTIO_BLK_F_GEOMETRY 4 /* Legacy geometry available */
#define VIRTIO_BLK_F_RO 5 /* Disk is read-only */
#define VIRTIO_BLK_F_BLK_SIZE 6 /* Block size of disk is available */
#define VIRTIO_BLK_F_TOPOLOGY 10 /* Topology information is available */
#define VIRTIO_BLK_F_MQ 12 /* support more than one vq */
#define VIRTIO_BLK_F_DISCARD 13 /* DISCARD is supported */
#define VIRTIO_BLK_F_WRITE_ZEROES 14 /* WRITE ZEROES is supported */

/* Legacy feature bits */
#ifndef VIRTIO_BLK_NO_LEGACY
#define VIRTIO_BLK_F_BARRIER 0 /* Does host support barriers? */
#define VIRTIO_BLK_F_SCSI 7 /* Supports scsi command passthru */
#define VIRTIO_BLK_F_FLUSH 9 /* Flush command supported */
#define VIRTIO_BLK_F_CONFIG_WCE 11 /* Writeback mode available in config */
/* Old (deprecated) name for VIRTIO_BLK_F_FLUSH. */
#define VIRTIO_BLK_F_WCE VIRTIO_BLK_F_FLUSH
#endif /* !VIRTIO_BLK_NO_LEGACY */

#define VIRTIO_BLK_ID_BYTES 20 /* ID string length */

struct virtio_blk_config {
/* The capacity (in 512-byte sectors). */
uint64_t capacity;
/* The maximum segment size (if VIRTIO_BLK_F_SIZE_MAX) */
uint32_t size_max;
/* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */
uint32_t seg_max;
/* geometry of the device (if VIRTIO_BLK_F_GEOMETRY) */
struct virtio_blk_geometry {
uint16_t cylinders;
uint8_t heads;
uint8_t sectors;
} geometry;

/* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */
uint32_t blk_size;

/* the next 4 entries are guarded by VIRTIO_BLK_F_TOPOLOGY */
/* exponent for physical block per logical block. */
uint8_t physical_block_exp;
/* alignment offset in logical blocks. */
uint8_t alignment_offset;
/* minimum I/O size without performance penalty in logical blocks. */
uint16_t min_io_size;
/* optimal sustained I/O size in logical blocks. */
uint32_t opt_io_size;

/* writeback mode (if VIRTIO_BLK_F_CONFIG_WCE) */
uint8_t wce;
uint8_t unused;

/* number of vqs, only available when VIRTIO_BLK_F_MQ is set */
uint16_t num_queues;

/* the next 3 entries are guarded by VIRTIO_BLK_F_DISCARD */
/*
* The maximum discard sectors (in 512-byte sectors) for
* one segment.
*/
uint32_t max_discard_sectors;
/*
* The maximum number of discard segments in a
* discard command.
*/
uint32_t max_discard_seg;
/* Discard commands must be aligned to this number of sectors. */
uint32_t discard_sector_alignment;

/* the next 3 entries are guarded by VIRTIO_BLK_F_WRITE_ZEROES */
/*
* The maximum number of write zeroes sectors (in 512-byte sectors) in
* one segment.
*/
uint32_t max_write_zeroes_sectors;
/*
* The maximum number of segments in a write zeroes
* command.
*/
uint32_t max_write_zeroes_seg;
/*
* Set if a VIRTIO_BLK_T_WRITE_ZEROES request may result in the
* deallocation of one or more of the sectors.
*/
uint8_t write_zeroes_may_unmap;

uint8_t unused1[3];
} __attribute__((packed));

/*
* Command types
*
* Usage is a bit tricky as some bits are used as flags and some are not.
*
* Rules:
* VIRTIO_BLK_T_OUT may be combined with VIRTIO_BLK_T_SCSI_CMD or
* VIRTIO_BLK_T_BARRIER. VIRTIO_BLK_T_FLUSH is a command of its own
* and may not be combined with any of the other flags.
*/

/* These two define direction. */
#define VIRTIO_BLK_T_IN 0
#define VIRTIO_BLK_T_OUT 1

#ifndef VIRTIO_BLK_NO_LEGACY
/* This bit says it's a scsi command, not an actual read or write. */
#define VIRTIO_BLK_T_SCSI_CMD 2
#endif /* VIRTIO_BLK_NO_LEGACY */

/* Cache flush command */
#define VIRTIO_BLK_T_FLUSH 4

/* Get device ID command */
#define VIRTIO_BLK_T_GET_ID 8

/* Discard command */
#define VIRTIO_BLK_T_DISCARD 11

/* Write zeroes command */
#define VIRTIO_BLK_T_WRITE_ZEROES 13

#ifndef VIRTIO_BLK_NO_LEGACY
/* Barrier before this op. */
#define VIRTIO_BLK_T_BARRIER 0x80000000
#endif /* !VIRTIO_BLK_NO_LEGACY */

/* And this is the final byte of the write scatter-gather list. */
#define VIRTIO_BLK_S_OK 0
#define VIRTIO_BLK_S_IOERR 1
#define VIRTIO_BLK_S_UNSUPP 2
#endif /* _LINUX_VIRTIO_BLK_H */

34 changes: 5 additions & 29 deletions drivers/common/virtio/virtio_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "virtio_pci.h"
#include "virtio_logs.h"
#include "virtqueue.h"
#include "virtio_blk.h"

/*
* Following macros are derived from linux/pci_regs.h, however,
Expand Down Expand Up @@ -442,32 +443,6 @@ modern_get_queue_size(struct virtio_hw *hw, uint16_t queue_id)
return rte_read16(&dev->common_cfg->queue_size);
}

static uint16_t
modern_net_get_queue_num(struct virtio_hw *hw)
{
uint16_t nr_vq;

if (virtio_with_feature(hw, VIRTIO_NET_F_MQ) ||
virtio_with_feature(hw, VIRTIO_NET_F_RSS)) {
VIRTIO_OPS(hw)->read_dev_cfg(hw,
offsetof(struct virtio_net_config, max_virtqueue_pairs),
&hw->max_queue_pairs,
sizeof(hw->max_queue_pairs));
} else {
PMD_INIT_LOG(DEBUG,
"Neither VIRTIO_NET_F_MQ nor VIRTIO_NET_F_RSS are supported");
hw->max_queue_pairs = 1;
}

nr_vq = hw->max_queue_pairs * 2;
if (virtio_with_feature(hw, VIRTIO_NET_F_CTRL_VQ))
nr_vq += 1;

PMD_INIT_LOG(DEBUG, "Virtio net nr_vq is %d", nr_vq);
return nr_vq;

}

static uint16_t
modern_get_queue_num(struct virtio_hw *hw)
{
Expand Down Expand Up @@ -596,9 +571,8 @@ static const struct virtio_ops virtio_dev_pci_modern_ops = {
.dev_close = modern_dev_close,
};

const struct virtio_dev_specific_ops virtio_net_dev_pci_modern_ops = {
.get_queue_num = modern_net_get_queue_num,
};
extern const struct virtio_dev_specific_ops virtio_net_dev_pci_modern_ops;
extern const struct virtio_dev_specific_ops virtio_blk_dev_pci_modern_ops;

static void *
get_cfg_addr(struct rte_pci_device *dev, struct virtio_pci_cap *cap)
Expand Down Expand Up @@ -777,6 +751,8 @@ virtio_pci_dev_init(struct rte_pci_device *pci_dev, struct virtio_pci_dev *dev)
VIRTIO_OPS(hw) = &virtio_dev_pci_modern_ops;
if (pci_dev->id.device_id == VIRTIO_PCI_MODERN_DEVICEID_NET)
hw->virtio_dev_sp_ops = &virtio_net_dev_pci_modern_ops;
else if (pci_dev->id.device_id == VIRTIO_PCI_MODERN_DEVICEID_BLK)
hw->virtio_dev_sp_ops = &virtio_blk_dev_pci_modern_ops;
else {
rte_pci_unmap_device(pci_dev);
PMD_INIT_LOG(ERR, "device id 0x%x not supported", pci_dev->id.device_id);
Expand Down
1 change: 1 addition & 0 deletions drivers/common/virtio/virtio_pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ struct virtnet_ctl;
#define VIRTIO_PCI_VENDORID 0x1AF4
#define VIRTIO_PCI_LEGACY_DEVICEID_NET 0x1000
#define VIRTIO_PCI_MODERN_DEVICEID_NET 0x1041
#define VIRTIO_PCI_MODERN_DEVICEID_BLK 0x1042

/* VirtIO ABI version, this must match exactly. */
#define VIRTIO_PCI_ABI_VERSION 0
Expand Down
35 changes: 35 additions & 0 deletions drivers/common/virtio/virtio_pci_blk.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) 2022 NVIDIA Corporation & Affiliates
*/
#ifdef RTE_EXEC_ENV_LINUX
#include <dirent.h>
#include <fcntl.h>
#endif

#include <rte_io.h>
#include <rte_bus.h>

#include "virtio_pci.h"
#include "virtio_logs.h"
#include "virtqueue.h"
#include "virtio_blk.h"

static uint16_t
modern_blk_get_queue_num(struct virtio_hw *hw)
{
if (virtio_with_feature(hw, VIRTIO_BLK_F_MQ)) {
VIRTIO_OPS(hw)->read_dev_cfg(hw,
offsetof(struct virtio_blk_config, num_queues),
&hw->num_queues_blk,
sizeof(hw->num_queues_blk));
} else {
hw->num_queues_blk = 1;
}
PMD_INIT_LOG(DEBUG, "Virtio blk nr_vq is %d", hw->num_queues_blk);

return hw->num_queues_blk;
}

const struct virtio_dev_specific_ops virtio_blk_dev_pci_modern_ops = {
.get_queue_num = modern_blk_get_queue_num,
};
42 changes: 42 additions & 0 deletions drivers/common/virtio/virtio_pci_net.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) 2022 NVIDIA Corporation & Affiliates
*/
#ifdef RTE_EXEC_ENV_LINUX
#include <dirent.h>
#include <fcntl.h>
#endif

#include <rte_io.h>
#include <rte_bus.h>

#include "virtio_pci.h"
#include "virtio_logs.h"
#include "virtqueue.h"

static uint16_t
modern_net_get_queue_num(struct virtio_hw *hw)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cut down this routine. it was overkill from the beginning.

struct virtio_pci_common_cfg {} structure has num_queues field for all the device types including net and blk.
This needs to reflect the maximum queue value regardless of device type.

Use it uniformly for net and blk.
and put in common code.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

num_queue include control queue and admin queue.
VDPA driver use this to get how many IO queue device can support.
so, shoule only return number of IO queue.
So, blk and net is different also.
we should keep this code , but only remove admin queue and controler queue logic.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kailiangz1 the logic should be in get_vqs_num() callbkc to be,

get_hw_num_vqs() -1 for net cvq.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should not like this, get_hw_num_vqs to get from common config's num_queues is hard to judge
whether the number include cvq or admin vq.
Directly get from virtio_net_config obey the spec and do need to calculate.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kailiangz1 num_vqs is generic for all the protocols regardless of device type. This is the virtio pci layer provides.
vdpa net and block layer can derive its own value from low layer.

This is simple math. no need to judge/guess anything.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to judge whether cvq is enabled and whether admin vq is enabled.

{
uint16_t nr_vq;

if (virtio_with_feature(hw, VIRTIO_NET_F_MQ) ||
virtio_with_feature(hw, VIRTIO_NET_F_RSS)) {
VIRTIO_OPS(hw)->read_dev_cfg(hw,
offsetof(struct virtio_net_config, max_virtqueue_pairs),
&hw->max_queue_pairs,
sizeof(hw->max_queue_pairs));
} else {
PMD_INIT_LOG(DEBUG,
"Neither VIRTIO_NET_F_MQ nor VIRTIO_NET_F_RSS are supported");
hw->max_queue_pairs = 1;
}

nr_vq = hw->max_queue_pairs * 2;

PMD_INIT_LOG(DEBUG, "Virtio net nr_vq is %d", nr_vq);
return nr_vq;

}

const struct virtio_dev_specific_ops virtio_net_dev_pci_modern_ops = {
.get_queue_num = modern_net_get_queue_num,
};
4 changes: 2 additions & 2 deletions drivers/vdpa/virtio/meson.build
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#SPDX-License-Identifier: BSD-3-Clause
#Copyright (c) 2022 NVIDIA Corporation & Affiliates

deps += 'common_virtio'
sources = files('virtio_vdpa.c')
deps += ['common_virtio']
sources = files('virtio_vdpa.c','virtio_vdpa_net.c','virtio_vdpa_blk.c')
Loading