DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework
@ 2021-01-19 21:24 Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 01/44] bus/vdev: add helper to get vdev from eth dev Maxime Coquelin
                   ` (43 more replies)
  0 siblings, 44 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

Thanks Chenbo, David & Adrian for your review contribution to
the V1. This V2 should implement all the changes you requested,
and fix a few regressions caught while testing.

This series significantly rework Virtio PMD to improve
the Virtio-user PMD and its backends integration.

First part of the series removes the dependency of
Virtio-user ethdev on Virtio PCI, by creating generic
files, adding per-bus meta data, ...

Main (if not single) functionnal change of this first
part is to remove the hack for Virtio-user to work in
IOVA as PA mode, this hack being very fragile.

Second part of the series reworks Virtio-user internal,
by reworking the requests handling so that vDPA and Kernel
backends no more hack into being Vhost-user backend. It
implies implementing new ops for all the request types.
Also, all the backend specific actions are moved from the
virtio_user_dev.c and virtio_user_ethdev.c to their
backend files.

Only functionnal change in this second part is making the
Vhost-user server mode blocking at init time, as long as
a client is not connected. The goal of this change is to
make the Vhost-user support much more robust, as without
blocking, the driver has to assume features that are going
to be supported by the client, which is very fragile and
error prone. As a side-effect, it also simplifies the
logic nin several place of the virtio-user PMD.

Main changes in v2:
===================
- Introduce vdev driver flag for drivers to require IOVA VA mode
- Rebase on top of -rc1 changes
- Fix regressions introduced in V1 (vhost-kernel broken, vhost-user reconnect...)
- Various minor issues & typos fixed
- Fix status feature issue introduced in v20.11, only reproduceable now that server
  mode is made blocking
- Improve failure handling in Virtio-user
- Improve logging

Testing coverage (All passed)
=============================
- Virtio-pci PMD
 * Virtio PMD in guest with Vhost-user backend in host
 * Virtio PMD in guest with Vhost-kernel backend in host
- Virtio-user PMD with Vhost-user backend
 * Vhost-user PMD server <-> Virtio-user client PMD IO loopback
 * Vhost-user PMD client <-> Virtio-user server PMD IO loopback
 * Vhost-user PMD client <-> Virtio-user server PMD reconnect
- Virtio-user PMD with Vhost-kernel backend
 * iperf test case
 * Txonly testpmd
- Virtio-user PMD with Vhost-vDPA backend
 * vdpa-sim (IO loopback)
 * CX-6 DX Kernel vDPA (Tx only)

Maxime Coquelin (44):
  bus/vdev: add helper to get vdev from eth dev
  bus/vdev: add driver IOVA VA mode requirement
  net/virtio: fix getting old status on reconnect
  net/virtio: introduce Virtio bus type
  net/virtio: refactor virtio-user device
  net/virtio: introduce PCI device metadata
  net/virtio: move PCI device init in dedicated file
  net/virtio: move PCI specific dev init to PCI ethdev init
  net/virtio: move MSIX detection to PCI ethdev
  net/virtio: force IOVA as VA mode for Virtio-user
  net/virtio: store PCI type in Virtio device metadata
  net/virtio: add callback for device closing
  net/virtio: validate features at bus level
  net/virtio: remove bus type enum
  net/virtio: move PCI-specific fields to PCI device
  net/virtio: pack virtio HW struct
  net/virtio: move legacy IO to Virtio PCI
  net/virtio: introduce generic virtio header
  net/virtio: move features definition to generic header
  net/virtio: move virtqueue defines in generic header
  net/virtio: move config definitions to generic header
  net/virtio: make interrupt handling more generic
  net/virtio: move vring alignment to generic header
  net/virtio: remove last PCI refs in non-PCI code
  net/virtio: make Vhost-user req sender consistent
  net/virtio: add Virtio-user ops to set owner
  net/virtio: add Virtio-user features ops
  net/virtio: add Virtio-user protocol features ops
  net/virtio: add Virtio-user memory tables ops
  net/virtio: add Virtio-user vring setting ops
  net/virtio: add Virtio-user vring file ops
  net/virtio: add Virtio-user vring address ops
  net/virtio: add Virtio-user status ops
  net/virtio: remove useless request ops
  net/virtio: improve Virtio-user errors handling
  net/virtio: move Vhost-user reqs to Vhost-user backend
  net/virtio: make server mode blocking
  net/virtio: move protocol features to Vhost-user
  net/virtio: introduce backend data
  net/virtio: move Vhost-user specifics to its backend
  net/virtio: move Vhost-kernel data to its backend
  net/virtio: move Vhost-vDPA data to its backend
  net/virtio: improve Vhost-user error logging
  net/virtio: handle Virtio-user setup failure properly

 drivers/bus/vdev/rte_bus_vdev.h               |   6 +
 drivers/bus/vdev/vdev.c                       |  31 +
 drivers/net/virtio/meson.build                |   6 +-
 drivers/net/virtio/virtio.c                   |  71 ++
 drivers/net/virtio/virtio.h                   | 246 +++++
 drivers/net/virtio/virtio_ethdev.c            | 457 +++------
 drivers/net/virtio/virtio_ethdev.h            |   6 +-
 drivers/net/virtio/virtio_pci.c               | 449 +++++----
 drivers/net/virtio/virtio_pci.h               | 286 +-----
 drivers/net/virtio/virtio_pci_ethdev.c        | 226 +++++
 drivers/net/virtio/virtio_ring.h              |   2 +-
 drivers/net/virtio/virtio_rxtx.c              |  90 +-
 drivers/net/virtio/virtio_rxtx_packed.h       |  10 +-
 drivers/net/virtio/virtio_rxtx_packed_avx.h   |  10 +-
 drivers/net/virtio/virtio_rxtx_packed_neon.h  |  10 +-
 drivers/net/virtio/virtio_rxtx_simple.h       |   3 +-
 drivers/net/virtio/virtio_user/vhost.h        |  79 +-
 drivers/net/virtio/virtio_user/vhost_kernel.c | 461 ++++++---
 .../net/virtio/virtio_user/vhost_kernel_tap.c |  25 +-
 .../net/virtio/virtio_user/vhost_kernel_tap.h |   1 +
 drivers/net/virtio/virtio_user/vhost_user.c   | 896 ++++++++++++++----
 drivers/net/virtio/virtio_user/vhost_vdpa.c   | 323 +++++--
 .../net/virtio/virtio_user/virtio_user_dev.c  | 514 +++++-----
 .../net/virtio/virtio_user/virtio_user_dev.h  |  20 +-
 drivers/net/virtio/virtio_user_ethdev.c       | 301 +-----
 drivers/net/virtio/virtqueue.c                |   6 +-
 drivers/net/virtio/virtqueue.h                |  45 +-
 27 files changed, 2704 insertions(+), 1876 deletions(-)
 create mode 100644 drivers/net/virtio/virtio.c
 create mode 100644 drivers/net/virtio/virtio.h
 create mode 100644 drivers/net/virtio/virtio_pci_ethdev.c

-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 01/44] bus/vdev: add helper to get vdev from eth dev
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-20  0:56   ` Thomas Monjalon
  2021-01-21  8:58   ` Xia, Chenbo
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 02/44] bus/vdev: add driver IOVA VA mode requirement Maxime Coquelin
                   ` (42 subsequent siblings)
  43 siblings, 2 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch adds an helper macro to get the rte_vdev_device
pointer from a rte_eth_dev pointer.

This is similar to RTE_ETH_DEV_TO_PCI().

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
Reviewed-by: David Marchand <david.marchand@redhat.com>
---
 drivers/bus/vdev/rte_bus_vdev.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/bus/vdev/rte_bus_vdev.h b/drivers/bus/vdev/rte_bus_vdev.h
index d14eeb41b0..f99a41f825 100644
--- a/drivers/bus/vdev/rte_bus_vdev.h
+++ b/drivers/bus/vdev/rte_bus_vdev.h
@@ -34,6 +34,8 @@ struct rte_vdev_device {
 #define RTE_DEV_TO_VDEV_CONST(ptr) \
 	container_of(ptr, const struct rte_vdev_device, device)
 
+#define RTE_ETH_DEV_TO_VDEV(eth_dev)	RTE_DEV_TO_VDEV((eth_dev)->device)
+
 static inline const char *
 rte_vdev_device_name(const struct rte_vdev_device *dev)
 {
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 02/44] bus/vdev: add driver IOVA VA mode requirement
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 01/44] bus/vdev: add helper to get vdev from eth dev Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-20 15:32   ` David Marchand
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 03/44] net/virtio: fix getting old status on reconnect Maxime Coquelin
                   ` (41 subsequent siblings)
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch adds driver flag in vdev bus driver so that
vdev drivers can require VA IOVA mode to be used, which
for example the case of Virtio-user PMD.

The patch implements the .get_iommu_class() callback, that
is called before devices probing to determine the IOVA mode
to be used.

It also adds a check right before the device is probed to
ensure compatible IOVa mode has been selected.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/bus/vdev/rte_bus_vdev.h |  4 ++++
 drivers/bus/vdev/vdev.c         | 31 +++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/drivers/bus/vdev/rte_bus_vdev.h b/drivers/bus/vdev/rte_bus_vdev.h
index f99a41f825..c8b41e649c 100644
--- a/drivers/bus/vdev/rte_bus_vdev.h
+++ b/drivers/bus/vdev/rte_bus_vdev.h
@@ -113,8 +113,12 @@ struct rte_vdev_driver {
 	rte_vdev_remove_t *remove;       /**< Virtual device remove function. */
 	rte_vdev_dma_map_t *dma_map;     /**< Virtual device DMA map function. */
 	rte_vdev_dma_unmap_t *dma_unmap; /**< Virtual device DMA unmap function. */
+	uint32_t drv_flags;                /**< Flags RTE_VDEV_DRV_*. */
 };
 
+/** Device driver needs IOVA as VA and cannot work with IOVA as PA */
+#define RTE_VDEV_DRV_NEED_IOVA_AS_VA 0x0001
+
 /**
  * Register a virtual device driver.
  *
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index acfd78828f..56f15e8201 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -189,6 +189,7 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
 {
 	const char *name;
 	struct rte_vdev_driver *driver;
+	enum rte_iova_mode iova_mode;
 	int ret;
 
 	if (rte_dev_is_probed(&dev->device))
@@ -199,6 +200,14 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
 
 	if (vdev_parse(name, &driver))
 		return -1;
+
+	iova_mode = rte_eal_iova_mode();
+	if ((driver->drv_flags & RTE_VDEV_DRV_NEED_IOVA_AS_VA) && (iova_mode == RTE_IOVA_PA)) {
+		VDEV_LOG(ERR, "%s requires VA IOVA mode but current mode is PA, not initializing",
+				name);
+		return -1;
+	}
+
 	ret = driver->probe(dev);
 	if (ret == 0)
 		dev->device.driver = &driver->driver;
@@ -594,6 +603,27 @@ vdev_unplug(struct rte_device *dev)
 	return rte_vdev_uninit(dev->name);
 }
 
+static enum rte_iova_mode
+vdev_get_iommu_class(void)
+{
+	const char *name;
+	struct rte_vdev_device *dev;
+	struct rte_vdev_driver *driver;
+
+	TAILQ_FOREACH(dev, &vdev_device_list, next) {
+		name = rte_vdev_device_name(dev);
+		if (!name)
+			continue;
+		if (vdev_parse(name, &driver))
+			continue;
+
+		if (driver->drv_flags & RTE_VDEV_DRV_NEED_IOVA_AS_VA)
+			return RTE_IOVA_VA;
+	}
+
+	return RTE_IOVA_DC;
+}
+
 static struct rte_bus rte_vdev_bus = {
 	.scan = vdev_scan,
 	.probe = vdev_probe,
@@ -603,6 +633,7 @@ static struct rte_bus rte_vdev_bus = {
 	.parse = vdev_parse,
 	.dma_map = vdev_dma_map,
 	.dma_unmap = vdev_dma_unmap,
+	.get_iommu_class = vdev_get_iommu_class,
 	.dev_iterate = rte_vdev_dev_iterate,
 };
 
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 03/44] net/virtio: fix getting old status on reconnect
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 01/44] bus/vdev: add helper to get vdev from eth dev Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 02/44] bus/vdev: add driver IOVA VA mode requirement Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-21  7:12   ` Xia, Chenbo
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 04/44] net/virtio: introduce Virtio bus type Maxime Coquelin
                   ` (40 subsequent siblings)
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand
  Cc: Maxime Coquelin, stable

This patch fixes getting reset status from the restarted
vhost-user backend in case of reconnection, instead of the
status at the time of the disconnection.

This issue was not spotted earlier because Vhost-user
protocol status feature was disabled in server mode.

Fixes: 47235f16505f ("net/virtio-user: set status on socket reconnect")
Cc: stable@dpdk.org

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_user_ethdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index 241808cd8f..7abba1f1ee 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -77,7 +77,7 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev)
 		return -1;
 
 	dev->vhostfd = connectfd;
-	old_status = vtpci_get_status(hw);
+	old_status = dev->status;
 
 	vtpci_reset(hw);
 
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 04/44] net/virtio: introduce Virtio bus type
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (2 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 03/44] net/virtio: fix getting old status on reconnect Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 05/44] net/virtio: refactor virtio-user device Maxime Coquelin
                   ` (39 subsequent siblings)
  43 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch is preliminary work for introducing a bus layer
in Virtio PMD, in order to improve Virtio-user integration.

A new bus type is added to provide a unified way to distinguish
which bus type is used (PCI modern, PCI legacy or Virtio-user).

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c      | 40 +++++++++++++------------
 drivers/net/virtio/virtio_pci.c         |  4 +--
 drivers/net/virtio/virtio_pci.h         |  9 +++++-
 drivers/net/virtio/virtio_user_ethdev.c |  2 +-
 4 files changed, 32 insertions(+), 23 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 92a3d4efa5..0ba10c274a 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -592,9 +592,9 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
 	 * we use virtual address. And we need properly set _offset_, please see
 	 * VIRTIO_MBUF_DATA_DMA_ADDR in virtqueue.h for more information.
 	 */
-	if (!hw->virtio_user_dev)
+	if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY || hw->bus_type == VIRTIO_BUS_PCI_MODERN) {
 		vq->offset = offsetof(struct rte_mbuf, buf_iova);
-	else {
+	} else if (hw->bus_type == VIRTIO_BUS_USER) {
 		vq->vq_ring_mem = (uintptr_t)mz->addr;
 		vq->offset = offsetof(struct rte_mbuf, buf_addr);
 		if (queue_type == VTNET_TQ)
@@ -746,13 +746,13 @@ virtio_dev_close(struct rte_eth_dev *dev)
 	virtio_free_queues(hw);
 
 #ifdef RTE_VIRTIO_USER
-	if (hw->virtio_user_dev)
+	if (hw->bus_type == VIRTIO_BUS_USER)
 		virtio_user_dev_uninit(hw->virtio_user_dev);
 	else
 #endif
 	if (dev->device) {
 		rte_pci_unmap_device(RTE_ETH_DEV_TO_PCI(dev));
-		if (!hw->modern)
+		if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY)
 			rte_pci_ioport_unmap(VTPCI_IO(hw));
 	}
 
@@ -1299,7 +1299,7 @@ virtio_intr_unmask(struct rte_eth_dev *dev)
 	if (rte_intr_ack(dev->intr_handle) < 0)
 		return -1;
 
-	if (!hw->virtio_user_dev)
+	if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY || hw->bus_type == VIRTIO_BUS_PCI_MODERN)
 		hw->use_msix = vtpci_msix_detect(RTE_ETH_DEV_TO_PCI(dev));
 
 	return 0;
@@ -1313,7 +1313,7 @@ virtio_intr_enable(struct rte_eth_dev *dev)
 	if (rte_intr_enable(dev->intr_handle) < 0)
 		return -1;
 
-	if (!hw->virtio_user_dev)
+	if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY || hw->bus_type == VIRTIO_BUS_PCI_MODERN)
 		hw->use_msix = vtpci_msix_detect(RTE_ETH_DEV_TO_PCI(dev));
 
 	return 0;
@@ -1327,7 +1327,7 @@ virtio_intr_disable(struct rte_eth_dev *dev)
 	if (rte_intr_disable(dev->intr_handle) < 0)
 		return -1;
 
-	if (!hw->virtio_user_dev)
+	if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY || hw->bus_type == VIRTIO_BUS_PCI_MODERN)
 		hw->use_msix = vtpci_msix_detect(RTE_ETH_DEV_TO_PCI(dev));
 
 	return 0;
@@ -1368,13 +1368,13 @@ virtio_negotiate_features(struct virtio_hw *hw, uint64_t req_features)
 	PMD_INIT_LOG(DEBUG, "features after negotiate = %" PRIx64,
 		hw->guest_features);
 
-	if (hw->modern && !vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) {
+	if (hw->bus_type == VIRTIO_BUS_PCI_MODERN && !vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) {
 		PMD_INIT_LOG(ERR,
 			"VIRTIO_F_VERSION_1 features is not enabled.");
 		return -1;
 	}
 
-	if (hw->modern || hw->virtio_user_dev) {
+	if (hw->bus_type == VIRTIO_BUS_PCI_MODERN || hw->bus_type == VIRTIO_BUS_USER) {
 		vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_FEATURES_OK);
 		if (!(vtpci_get_status(hw) & VIRTIO_CONFIG_STATUS_FEATURES_OK)) {
 			PMD_INIT_LOG(ERR,
@@ -1709,7 +1709,7 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 
 	hw->weak_barriers = !vtpci_with_feature(hw, VIRTIO_F_ORDER_PLATFORM);
 
-	if (!hw->virtio_user_dev)
+	if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY || hw->bus_type == VIRTIO_BUS_PCI_MODERN)
 		pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
 
 	/* If host does not support both status and MSI-X then disable LSC */
@@ -1856,7 +1856,7 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 static int
 virtio_remap_pci(struct rte_pci_device *pci_dev, struct virtio_hw *hw)
 {
-	if (hw->modern) {
+	if (hw->bus_type == VIRTIO_BUS_PCI_MODERN) {
 		/*
 		 * We don't have to re-parse the PCI config space, since
 		 * rte_pci_map_device() makes sure the mapped address
@@ -1872,7 +1872,7 @@ virtio_remap_pci(struct rte_pci_device *pci_dev, struct virtio_hw *hw)
 			PMD_INIT_LOG(DEBUG, "failed to map pci device!");
 			return -1;
 		}
-	} else {
+	} else if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY) {
 		if (rte_pci_ioport_map(pci_dev, 0, VTPCI_IO(hw)) < 0)
 			return -1;
 	}
@@ -1884,14 +1884,16 @@ static void
 virtio_set_vtpci_ops(struct virtio_hw *hw)
 {
 #ifdef RTE_VIRTIO_USER
-	if (hw->virtio_user_dev)
+	if (hw->bus_type == VIRTIO_BUS_USER)
 		VTPCI_OPS(hw) = &virtio_user_ops;
 	else
 #endif
-	if (hw->modern)
+	if (hw->bus_type == VIRTIO_BUS_PCI_MODERN)
 		VTPCI_OPS(hw) = &modern_ops;
-	else
+	else if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY)
 		VTPCI_OPS(hw) = &legacy_ops;
+
+	return;
 }
 
 /*
@@ -1919,7 +1921,7 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 	eth_dev->rx_descriptor_done = virtio_dev_rx_queue_done;
 
 	if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
-		if (!hw->virtio_user_dev) {
+		if (hw->bus_type != VIRTIO_BUS_USER) {
 			ret = virtio_remap_pci(RTE_ETH_DEV_TO_PCI(eth_dev), hw);
 			if (ret)
 				return ret;
@@ -1950,7 +1952,7 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 	/* For virtio_user case the hw->virtio_user_dev is populated by
 	 * virtio_user_eth_dev_alloc() before eth_virtio_dev_init() is called.
 	 */
-	if (!hw->virtio_user_dev) {
+	if (hw->bus_type != VIRTIO_BUS_USER) {
 		ret = vtpci_init(RTE_ETH_DEV_TO_PCI(eth_dev), hw);
 		if (ret)
 			goto err_vtpci_init;
@@ -1982,9 +1984,9 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 	return 0;
 
 err_virtio_init:
-	if (!hw->virtio_user_dev) {
+	if (hw->bus_type == VIRTIO_BUS_PCI_MODERN || hw->bus_type == VIRTIO_BUS_PCI_LEGACY) {
 		rte_pci_unmap_device(RTE_ETH_DEV_TO_PCI(eth_dev));
-		if (!hw->modern)
+		if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY)
 			rte_pci_ioport_unmap(VTPCI_IO(hw));
 	}
 err_vtpci_init:
diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index d6b950ee69..1692268f30 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -697,7 +697,7 @@ vtpci_init(struct rte_pci_device *dev, struct virtio_hw *hw)
 	if (virtio_read_caps(dev, hw) == 0) {
 		PMD_INIT_LOG(INFO, "modern virtio pci detected.");
 		virtio_hw_internal[hw->port_id].vtpci_ops = &modern_ops;
-		hw->modern = 1;
+		hw->bus_type = VIRTIO_BUS_PCI_MODERN;
 		return 0;
 	}
 
@@ -716,7 +716,7 @@ vtpci_init(struct rte_pci_device *dev, struct virtio_hw *hw)
 	}
 
 	virtio_hw_internal[hw->port_id].vtpci_ops = &legacy_ops;
-	hw->modern   = 0;
+	hw->bus_type = VIRTIO_BUS_PCI_LEGACY;
 
 	return 0;
 }
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index ab61e911b8..6388f0a74d 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -243,7 +243,15 @@ struct virtio_pci_ops {
 
 struct virtio_net_config;
 
+enum virtio_bus_type {
+	VIRTIO_BUS_UNKNOWN,
+	VIRTIO_BUS_PCI_LEGACY,
+	VIRTIO_BUS_PCI_MODERN,
+	VIRTIO_BUS_USER,
+};
+
 struct virtio_hw {
+	enum virtio_bus_type bus_type;
 	struct virtnet_ctl *cvq;
 	uint64_t    req_guest_features;
 	uint64_t    guest_features;
@@ -253,7 +261,6 @@ struct virtio_hw {
 	uint16_t    vtnet_hdr_size;
 	uint8_t	    vlan_strip;
 	uint8_t	    use_msix;
-	uint8_t     modern;
 	uint8_t     use_vec_rx;
 	uint8_t     use_vec_tx;
 	uint8_t     use_inorder_rx;
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index 7abba1f1ee..441721b6ca 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -629,7 +629,7 @@ virtio_user_eth_dev_alloc(struct rte_vdev_device *vdev)
 	 * Here just pretend that we support msix.
 	 */
 	hw->use_msix = 1;
-	hw->modern   = 0;
+	hw->bus_type = VIRTIO_BUS_USER;
 	hw->use_vec_rx = 0;
 	hw->use_vec_tx = 0;
 	hw->use_inorder_rx = 0;
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 05/44] net/virtio: refactor virtio-user device
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (3 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 04/44] net/virtio: introduce Virtio bus type Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 06/44] net/virtio: introduce PCI device metadata Maxime Coquelin
                   ` (38 subsequent siblings)
  43 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch moves the virtio_hw structure into the virtio_user_dev
structure, with the goal of making virtio_hw bus-agnostic.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c            |  2 +-
 drivers/net/virtio/virtio_pci.h               |  1 -
 .../net/virtio/virtio_user/virtio_user_dev.h  |  1 +
 drivers/net/virtio/virtio_user_ethdev.c       | 64 ++++++++-----------
 4 files changed, 29 insertions(+), 39 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 0ba10c274a..c8a01a46df 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -747,7 +747,7 @@ virtio_dev_close(struct rte_eth_dev *dev)
 
 #ifdef RTE_VIRTIO_USER
 	if (hw->bus_type == VIRTIO_BUS_USER)
-		virtio_user_dev_uninit(hw->virtio_user_dev);
+		virtio_user_dev_uninit(dev->data->dev_private);
 	else
 #endif
 	if (dev->device) {
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 6388f0a74d..b35a596169 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -277,7 +277,6 @@ struct virtio_hw {
 	uint16_t    *notify_base;
 	struct virtio_pci_common_cfg *common_cfg;
 	struct virtio_net_config *dev_cfg;
-	void	    *virtio_user_dev;
 	/*
 	 * App management thread and virtio interrupt handler thread
 	 * both can change device state, this lock is meant to avoid
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h b/drivers/net/virtio/virtio_user/virtio_user_dev.h
index 3b5b6bc3ae..b3776cc7a0 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
@@ -24,6 +24,7 @@ struct virtio_user_queue {
 };
 
 struct virtio_user_dev {
+	struct virtio_hw hw;
 	enum virtio_user_backend_type backend_type;
 	/* for vhost_user backend */
 	int		vhostfd;
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index 441721b6ca..620ecb126c 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -26,13 +26,13 @@
 #include "virtio_user/virtio_user_dev.h"
 #include "virtio_user/vhost.h"
 
-#define virtio_user_get_dev(hw) \
-	((struct virtio_user_dev *)(hw)->virtio_user_dev)
+#define virtio_user_get_dev(hwp) container_of(hwp, struct virtio_user_dev, hw)
 
 static void
-virtio_user_reset_queues_packed(struct rte_eth_dev *dev)
+virtio_user_reset_queues_packed(struct rte_eth_dev *eth_dev)
 {
-	struct virtio_hw *hw = dev->data->dev_private;
+	struct virtio_user_dev *dev = eth_dev->data->dev_private;
+	struct virtio_hw *hw = &dev->hw;
 	struct virtnet_rx *rxvq;
 	struct virtnet_tx *txvq;
 	uint16_t i;
@@ -48,14 +48,14 @@ virtio_user_reset_queues_packed(struct rte_eth_dev *dev)
 	rte_delay_ms(1);
 
 	/* Vring reset for each Tx queue and Rx queue. */
-	for (i = 0; i < dev->data->nb_rx_queues; i++) {
-		rxvq = dev->data->rx_queues[i];
+	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
+		rxvq = eth_dev->data->rx_queues[i];
 		virtqueue_rxvq_reset_packed(rxvq->vq);
-		virtio_dev_rx_queue_setup_finish(dev, i);
+		virtio_dev_rx_queue_setup_finish(eth_dev, i);
 	}
 
-	for (i = 0; i < dev->data->nb_tx_queues; i++) {
-		txvq = dev->data->tx_queues[i];
+	for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
+		txvq = eth_dev->data->tx_queues[i];
 		virtqueue_txvq_reset_packed(txvq->vq);
 	}
 
@@ -69,7 +69,7 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev)
 {
 	int ret, connectfd, old_status;
 	struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->port_id];
-	struct virtio_hw *hw = eth_dev->data->dev_private;
+	struct virtio_hw *hw = &dev->hw;
 	uint64_t protocol_features;
 
 	connectfd = accept(dev->listenfd, NULL, NULL);
@@ -605,21 +605,15 @@ virtio_user_eth_dev_alloc(struct rte_vdev_device *vdev)
 	struct virtio_hw *hw;
 	struct virtio_user_dev *dev;
 
-	eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*hw));
+	eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*dev));
 	if (!eth_dev) {
 		PMD_INIT_LOG(ERR, "cannot alloc rte_eth_dev");
 		return NULL;
 	}
 
 	data = eth_dev->data;
-	hw = eth_dev->data->dev_private;
-
-	dev = rte_zmalloc(NULL, sizeof(*dev), 0);
-	if (!dev) {
-		PMD_INIT_LOG(ERR, "malloc virtio_user_dev failed");
-		rte_eth_dev_release_port(eth_dev);
-		return NULL;
-	}
+	dev = eth_dev->data->dev_private;
+	hw = &dev->hw;
 
 	hw->port_id = data->port_id;
 	dev->port_id = data->port_id;
@@ -634,17 +628,13 @@ virtio_user_eth_dev_alloc(struct rte_vdev_device *vdev)
 	hw->use_vec_tx = 0;
 	hw->use_inorder_rx = 0;
 	hw->use_inorder_tx = 0;
-	hw->virtio_user_dev = dev;
+
 	return eth_dev;
 }
 
 static void
 virtio_user_eth_dev_free(struct rte_eth_dev *eth_dev)
 {
-	struct rte_eth_dev_data *data = eth_dev->data;
-	struct virtio_hw *hw = data->dev_private;
-
-	rte_free(hw->virtio_user_dev);
 	rte_eth_dev_release_port(eth_dev);
 }
 
@@ -653,11 +643,12 @@ virtio_user_eth_dev_free(struct rte_eth_dev *eth_dev)
  * Returns 0 on success.
  */
 static int
-virtio_user_pmd_probe(struct rte_vdev_device *dev)
+virtio_user_pmd_probe(struct rte_vdev_device *vdev)
 {
 	struct rte_kvargs *kvlist = NULL;
 	struct rte_eth_dev *eth_dev;
 	struct virtio_hw *hw;
+	struct virtio_user_dev *dev;
 	enum virtio_user_backend_type backend_type = VIRTIO_USER_BACKEND_UNKNOWN;
 	uint64_t queues = VIRTIO_USER_DEF_Q_NUM;
 	uint64_t cq = VIRTIO_USER_DEF_CQ_EN;
@@ -672,8 +663,10 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev)
 	char *mac_addr = NULL;
 	int ret = -1;
 
+	RTE_BUILD_BUG_ON(offsetof(struct virtio_user_dev, hw) != 0);
+
 	if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
-		const char *name = rte_vdev_device_name(dev);
+		const char *name = rte_vdev_device_name(vdev);
 		eth_dev = rte_eth_dev_attach_secondary(name);
 		if (!eth_dev) {
 			PMD_INIT_LOG(ERR, "Failed to probe %s", name);
@@ -687,12 +680,12 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev)
 		}
 
 		eth_dev->dev_ops = &virtio_user_secondary_eth_dev_ops;
-		eth_dev->device = &dev->device;
+		eth_dev->device = &vdev->device;
 		rte_eth_dev_probing_finish(eth_dev);
 		return 0;
 	}
 
-	kvlist = rte_kvargs_parse(rte_vdev_device_args(dev), valid_args);
+	kvlist = rte_kvargs_parse(rte_vdev_device_args(vdev), valid_args);
 	if (!kvlist) {
 		PMD_INIT_LOG(ERR, "error when parsing param");
 		goto end;
@@ -832,14 +825,15 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev)
 		}
 	}
 
-	eth_dev = virtio_user_eth_dev_alloc(dev);
+	eth_dev = virtio_user_eth_dev_alloc(vdev);
 	if (!eth_dev) {
 		PMD_INIT_LOG(ERR, "virtio_user fails to alloc device");
 		goto end;
 	}
 
-	hw = eth_dev->data->dev_private;
-	if (virtio_user_dev_init(hw->virtio_user_dev, path, queues, cq,
+	dev = eth_dev->data->dev_private;
+	hw = &dev->hw;
+	if (virtio_user_dev_init(dev, path, queues, cq,
 			 queue_size, mac_addr, &ifname, server_mode,
 			 mrg_rxbuf, in_order, packed_vq, backend_type) < 0) {
 		PMD_INIT_LOG(ERR, "virtio_user_dev_init fails");
@@ -912,7 +906,6 @@ static int virtio_user_pmd_dma_map(struct rte_vdev_device *vdev, void *addr,
 	const char *name;
 	struct rte_eth_dev *eth_dev;
 	struct virtio_user_dev *dev;
-	struct virtio_hw *hw;
 
 	if (!vdev)
 		return -EINVAL;
@@ -923,8 +916,7 @@ static int virtio_user_pmd_dma_map(struct rte_vdev_device *vdev, void *addr,
 	if (!eth_dev)
 		return 0;
 
-	hw = (struct virtio_hw *)eth_dev->data->dev_private;
-	dev = hw->virtio_user_dev;
+	dev = eth_dev->data->dev_private;
 
 	if (dev->ops->dma_map)
 		return dev->ops->dma_map(dev, addr, iova, len);
@@ -938,7 +930,6 @@ static int virtio_user_pmd_dma_unmap(struct rte_vdev_device *vdev, void *addr,
 	const char *name;
 	struct rte_eth_dev *eth_dev;
 	struct virtio_user_dev *dev;
-	struct virtio_hw *hw;
 
 	if (!vdev)
 		return -EINVAL;
@@ -949,8 +940,7 @@ static int virtio_user_pmd_dma_unmap(struct rte_vdev_device *vdev, void *addr,
 	if (!eth_dev)
 		return 0;
 
-	hw = (struct virtio_hw *)eth_dev->data->dev_private;
-	dev = hw->virtio_user_dev;
+	dev = eth_dev->data->dev_private;
 
 	if (dev->ops->dma_unmap)
 		return dev->ops->dma_unmap(dev, addr, iova, len);
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 06/44] net/virtio: introduce PCI device metadata
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (4 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 05/44] net/virtio: refactor virtio-user device Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 07/44] net/virtio: move PCI device init in dedicated file Maxime Coquelin
                   ` (37 subsequent siblings)
  43 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch initiate refactoring of Virtio PCI, by introducing
a new device structure for PCI-specific metadata.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 2 +-
 drivers/net/virtio/virtio_pci.c    | 2 ++
 drivers/net/virtio/virtio_pci.h    | 5 +++++
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index c8a01a46df..aafba15ac2 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -2154,7 +2154,7 @@ static int eth_virtio_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	if (vdpa == 1)
 		return 1;
 
-	return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct virtio_hw),
+	return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct virtio_pci_dev),
 		eth_virtio_dev_init);
 }
 
diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index 1692268f30..345d73f868 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -689,6 +689,8 @@ virtio_read_caps(struct rte_pci_device *dev, struct virtio_hw *hw)
 int
 vtpci_init(struct rte_pci_device *dev, struct virtio_hw *hw)
 {
+	RTE_BUILD_BUG_ON(offsetof(struct virtio_pci_dev, hw) != 0);
+
 	/*
 	 * Try if we can succeed reading virtio pci caps, which exists
 	 * only on modern pci device. If failed, we fallback to legacy
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index b35a596169..59f6688218 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -289,6 +289,11 @@ struct virtio_hw {
 	struct virtqueue **vqs;
 };
 
+struct virtio_pci_dev {
+	struct virtio_hw hw;
+};
+
+#define virtio_pci_get_dev(hwp) container_of(hwp, struct virtio_pci_dev, hw)
 
 /*
  * While virtio_hw is stored in shared memory, this structure stores
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 07/44] net/virtio: move PCI device init in dedicated file
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (5 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 06/44] net/virtio: introduce PCI device metadata Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 08/44] net/virtio: move PCI specific dev init to PCI ethdev init Maxime Coquelin
                   ` (36 subsequent siblings)
  43 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch moves the PCI Ethernet device registration bits
in a dedicated patch. In following patches, more code will
be moved there, with the goal of making virtio_ethdev.c
truly bus-agnostic.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
---
 drivers/net/virtio/meson.build         |   1 +
 drivers/net/virtio/virtio_ethdev.c     | 117 +------------------
 drivers/net/virtio/virtio_ethdev.h     |   2 +
 drivers/net/virtio/virtio_pci_ethdev.c | 149 +++++++++++++++++++++++++
 4 files changed, 157 insertions(+), 112 deletions(-)
 create mode 100644 drivers/net/virtio/virtio_pci_ethdev.c

diff --git a/drivers/net/virtio/meson.build b/drivers/net/virtio/meson.build
index 0e78d1243b..07e085376b 100644
--- a/drivers/net/virtio/meson.build
+++ b/drivers/net/virtio/meson.build
@@ -8,6 +8,7 @@ if is_windows
 endif
 
 sources += files('virtio_ethdev.c',
+	'virtio_pci_ethdev.c',
 	'virtio_pci.c',
 	'virtio_rxtx.c',
 	'virtio_rxtx_simple.c',
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index aafba15ac2..ad7e9efd5f 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -38,17 +38,14 @@
 #include "virtio_rxtx.h"
 #include "virtio_user/virtio_user_dev.h"
 
-static int eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev);
 static int  virtio_dev_configure(struct rte_eth_dev *dev);
 static int  virtio_dev_start(struct rte_eth_dev *dev);
-static int  virtio_dev_stop(struct rte_eth_dev *dev);
 static int virtio_dev_promiscuous_enable(struct rte_eth_dev *dev);
 static int virtio_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static int virtio_dev_allmulticast_enable(struct rte_eth_dev *dev);
 static int virtio_dev_allmulticast_disable(struct rte_eth_dev *dev);
 static uint32_t virtio_dev_speed_capa_get(uint32_t speed);
 static int virtio_dev_devargs_parse(struct rte_devargs *devargs,
-	int *vdpa,
 	uint32_t *speed,
 	int *vectorized);
 static int virtio_dev_info_get(struct rte_eth_dev *dev,
@@ -89,15 +86,6 @@ static int virtio_dev_queue_stats_mapping_set(
 static void virtio_notify_peers(struct rte_eth_dev *dev);
 static void virtio_ack_link_announce(struct rte_eth_dev *dev);
 
-/*
- * The set of PCI devices this driver supports
- */
-static const struct rte_pci_id pci_id_virtio_map[] = {
-	{ RTE_PCI_DEVICE(VIRTIO_PCI_VENDORID, VIRTIO_PCI_LEGACY_DEVICEID_NET) },
-	{ RTE_PCI_DEVICE(VIRTIO_PCI_VENDORID, VIRTIO_PCI_MODERN_DEVICEID_NET) },
-	{ .vendor_id = 0, /* sentinel */ },
-};
-
 struct rte_virtio_xstats_name_off {
 	char name[RTE_ETH_XSTATS_NAME_SIZE];
 	unsigned offset;
@@ -714,7 +702,7 @@ virtio_alloc_queues(struct rte_eth_dev *dev)
 
 static void virtio_queues_unbind_intr(struct rte_eth_dev *dev);
 
-static int
+int
 virtio_dev_close(struct rte_eth_dev *dev)
 {
 	struct virtio_hw *hw = dev->data->dev_private;
@@ -1932,8 +1920,7 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 
 		return 0;
 	}
-	ret = virtio_dev_devargs_parse(eth_dev->device->devargs,
-		 NULL, &speed, &vectorized);
+	ret = virtio_dev_devargs_parse(eth_dev->device->devargs, &speed, &vectorized);
 	if (ret < 0)
 		return ret;
 	hw->speed = speed;
@@ -1995,36 +1982,6 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 	return ret;
 }
 
-static int
-eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
-{
-	int ret;
-	PMD_INIT_FUNC_TRACE();
-
-	if (rte_eal_process_type() == RTE_PROC_SECONDARY)
-		return 0;
-
-	ret = virtio_dev_stop(eth_dev);
-	virtio_dev_close(eth_dev);
-
-	PMD_INIT_LOG(DEBUG, "dev_uninit completed");
-
-	return ret;
-}
-
-
-static int vdpa_check_handler(__rte_unused const char *key,
-		const char *value, void *ret_val)
-{
-	if (strcmp(value, "1") == 0)
-		*(int *)ret_val = 1;
-	else
-		*(int *)ret_val = 0;
-
-	return 0;
-}
-
-
 static uint32_t
 virtio_dev_speed_capa_get(uint32_t speed)
 {
@@ -2062,10 +2019,8 @@ static int vectorized_check_handler(__rte_unused const char *key,
 }
 
 #define VIRTIO_ARG_SPEED      "speed"
-#define VIRTIO_ARG_VDPA       "vdpa"
 #define VIRTIO_ARG_VECTORIZED "vectorized"
 
-
 static int
 link_speed_handler(const char *key __rte_unused,
 		const char *value, void *ret_val)
@@ -2084,8 +2039,7 @@ link_speed_handler(const char *key __rte_unused,
 
 
 static int
-virtio_dev_devargs_parse(struct rte_devargs *devargs, int *vdpa,
-	uint32_t *speed, int *vectorized)
+virtio_dev_devargs_parse(struct rte_devargs *devargs, uint32_t *speed, int *vectorized)
 {
 	struct rte_kvargs *kvlist;
 	int ret = 0;
@@ -2098,18 +2052,7 @@ virtio_dev_devargs_parse(struct rte_devargs *devargs, int *vdpa,
 		PMD_INIT_LOG(ERR, "error when parsing param");
 		return 0;
 	}
-	if (vdpa && rte_kvargs_count(kvlist, VIRTIO_ARG_VDPA) == 1) {
-		/* vdpa mode selected when there's a key-value pair:
-		 * vdpa=1
-		 */
-		ret = rte_kvargs_process(kvlist, VIRTIO_ARG_VDPA,
-				vdpa_check_handler, vdpa);
-		if (ret < 0) {
-			PMD_INIT_LOG(ERR, "Failed to parse %s",
-				VIRTIO_ARG_VDPA);
-			goto exit;
-		}
-	}
+
 	if (speed && rte_kvargs_count(kvlist, VIRTIO_ARG_SPEED) == 1) {
 		ret = rte_kvargs_process(kvlist,
 					VIRTIO_ARG_SPEED,
@@ -2138,53 +2081,6 @@ virtio_dev_devargs_parse(struct rte_devargs *devargs, int *vdpa,
 	return ret;
 }
 
-static int eth_virtio_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
-	struct rte_pci_device *pci_dev)
-{
-	int vdpa = 0;
-	int ret = 0;
-
-	ret = virtio_dev_devargs_parse(pci_dev->device.devargs, &vdpa, NULL,
-		NULL);
-	if (ret < 0) {
-		PMD_INIT_LOG(ERR, "devargs parsing is failed");
-		return ret;
-	}
-	/* virtio pmd skips probe if device needs to work in vdpa mode */
-	if (vdpa == 1)
-		return 1;
-
-	return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct virtio_pci_dev),
-		eth_virtio_dev_init);
-}
-
-static int eth_virtio_pci_remove(struct rte_pci_device *pci_dev)
-{
-	int ret;
-
-	ret = rte_eth_dev_pci_generic_remove(pci_dev, eth_virtio_dev_uninit);
-	/* Port has already been released by close. */
-	if (ret == -ENODEV)
-		ret = 0;
-	return ret;
-}
-
-static struct rte_pci_driver rte_virtio_pmd = {
-	.driver = {
-		.name = "net_virtio",
-	},
-	.id_table = pci_id_virtio_map,
-	.drv_flags = 0,
-	.probe = eth_virtio_pci_probe,
-	.remove = eth_virtio_pci_remove,
-};
-
-RTE_INIT(rte_virtio_pmd_init)
-{
-	rte_eal_iopl_init();
-	rte_pci_register(&rte_virtio_pmd);
-}
-
 static bool
 rx_offload_enabled(struct virtio_hw *hw)
 {
@@ -2535,7 +2431,7 @@ static void virtio_dev_free_mbufs(struct rte_eth_dev *dev)
 /*
  * Stop device: disable interrupt and mark link down
  */
-static int
+int
 virtio_dev_stop(struct rte_eth_dev *dev)
 {
 	struct virtio_hw *hw = dev->data->dev_private;
@@ -2686,8 +2582,5 @@ __rte_unused uint8_t is_rx)
 	return 0;
 }
 
-RTE_PMD_EXPORT_NAME(net_virtio, __COUNTER__);
-RTE_PMD_REGISTER_PCI_TABLE(net_virtio, pci_id_virtio_map);
-RTE_PMD_REGISTER_KMOD_DEP(net_virtio, "* igb_uio | uio_pci_generic | vfio-pci");
 RTE_LOG_REGISTER(virtio_logtype_init, pmd.net.virtio.init, NOTICE);
 RTE_LOG_REGISTER(virtio_logtype_driver, pmd.net.virtio.driver, NOTICE);
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index b7d52d497f..13395937c8 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -117,6 +117,8 @@ void virtio_interrupt_handler(void *param);
 
 int virtio_dev_pause(struct rte_eth_dev *dev);
 void virtio_dev_resume(struct rte_eth_dev *dev);
+int virtio_dev_stop(struct rte_eth_dev *dev);
+int virtio_dev_close(struct rte_eth_dev *dev);
 int virtio_inject_pkts(struct rte_eth_dev *dev, struct rte_mbuf **tx_pkts,
 		int nb_pkts);
 
diff --git a/drivers/net/virtio/virtio_pci_ethdev.c b/drivers/net/virtio/virtio_pci_ethdev.c
new file mode 100644
index 0000000000..7c849d01ec
--- /dev/null
+++ b/drivers/net/virtio/virtio_pci_ethdev.c
@@ -0,0 +1,149 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2016 Intel Corporation
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <rte_ethdev_driver.h>
+#include <rte_ethdev_pci.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_errno.h>
+
+#include <rte_memory.h>
+#include <rte_eal.h>
+#include <rte_dev.h>
+#include <rte_kvargs.h>
+
+#include "virtio_ethdev.h"
+#include "virtio_pci.h"
+#include "virtio_logs.h"
+
+/*
+ * The set of PCI devices this driver supports
+ */
+static const struct rte_pci_id pci_id_virtio_map[] = {
+	{ RTE_PCI_DEVICE(VIRTIO_PCI_VENDORID, VIRTIO_PCI_LEGACY_DEVICEID_NET) },
+	{ RTE_PCI_DEVICE(VIRTIO_PCI_VENDORID, VIRTIO_PCI_MODERN_DEVICEID_NET) },
+	{ .vendor_id = 0, /* sentinel */ },
+};
+
+static int
+eth_virtio_pci_init(struct rte_eth_dev *eth_dev)
+{
+	return eth_virtio_dev_init(eth_dev);
+}
+
+static int
+eth_virtio_pci_uninit(struct rte_eth_dev *eth_dev)
+{
+	int ret;
+	PMD_INIT_FUNC_TRACE();
+
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY)
+		return 0;
+
+	ret = virtio_dev_stop(eth_dev);
+	virtio_dev_close(eth_dev);
+
+	PMD_INIT_LOG(DEBUG, "dev_uninit completed");
+
+	return ret;
+}
+
+static int vdpa_check_handler(__rte_unused const char *key,
+		const char *value, void *ret_val)
+{
+	if (strcmp(value, "1") == 0)
+		*(int *)ret_val = 1;
+	else
+		*(int *)ret_val = 0;
+
+	return 0;
+}
+
+#define VIRTIO_ARG_VDPA       "vdpa"
+
+static int
+virtio_pci_devargs_parse(struct rte_devargs *devargs, int *vdpa)
+{
+	struct rte_kvargs *kvlist;
+	int ret = 0;
+
+	if (devargs == NULL)
+		return 0;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL) {
+		PMD_INIT_LOG(ERR, "error when parsing param");
+		return 0;
+	}
+
+	if (rte_kvargs_count(kvlist, VIRTIO_ARG_VDPA) == 1) {
+		/* vdpa mode selected when there's a key-value pair:
+		 * vdpa=1
+		 */
+		ret = rte_kvargs_process(kvlist, VIRTIO_ARG_VDPA,
+				vdpa_check_handler, vdpa);
+		if (ret < 0)
+			PMD_INIT_LOG(ERR, "Failed to parse %s", VIRTIO_ARG_VDPA);
+	}
+
+	rte_kvargs_free(kvlist);
+
+	return ret;
+}
+
+static int eth_virtio_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
+	struct rte_pci_device *pci_dev)
+{
+	int vdpa = 0;
+	int ret = 0;
+
+	ret = virtio_pci_devargs_parse(pci_dev->device.devargs, &vdpa);
+	if (ret < 0) {
+		PMD_INIT_LOG(ERR, "devargs parsing is failed");
+		return ret;
+	}
+	/* virtio pmd skips probe if device needs to work in vdpa mode */
+	if (vdpa == 1)
+		return 1;
+
+	return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct virtio_pci_dev),
+		eth_virtio_pci_init);
+}
+
+static int eth_virtio_pci_remove(struct rte_pci_device *pci_dev)
+{
+	int ret;
+
+	ret = rte_eth_dev_pci_generic_remove(pci_dev, eth_virtio_pci_uninit);
+	/* Port has already been released by close. */
+	if (ret == -ENODEV)
+		ret = 0;
+	return ret;
+}
+
+static struct rte_pci_driver rte_virtio_net_pci_pmd = {
+	.driver = {
+		.name = "net_virtio",
+	},
+	.id_table = pci_id_virtio_map,
+	.drv_flags = 0,
+	.probe = eth_virtio_pci_probe,
+	.remove = eth_virtio_pci_remove,
+};
+
+RTE_INIT(rte_virtio_net_pci_pmd_init)
+{
+	rte_eal_iopl_init();
+	rte_pci_register(&rte_virtio_net_pci_pmd);
+}
+
+RTE_PMD_REGISTER_PCI_TABLE(net_virtio, pci_id_virtio_map);
+RTE_PMD_REGISTER_KMOD_DEP(net_virtio, "* igb_uio | uio_pci_generic | vfio-pci");
+RTE_PMD_EXPORT_NAME(net_virtio, __COUNTER__);
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 08/44] net/virtio: move PCI specific dev init to PCI ethdev init
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (6 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 07/44] net/virtio: move PCI device init in dedicated file Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 09/44] net/virtio: move MSIX detection to PCI ethdev Maxime Coquelin
                   ` (35 subsequent siblings)
  43 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch moves the PCI specific initialization from
eth_virtio_dev_init() to eth_virtio_pci_init().

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
Reviewed-by: David Marchand <david.marchand@redhat.com>
---
 drivers/net/virtio/virtio_ethdev.c     | 63 +----------------------
 drivers/net/virtio/virtio_pci_ethdev.c | 71 +++++++++++++++++++++++++-
 2 files changed, 71 insertions(+), 63 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index ad7e9efd5f..a3e81f336d 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1676,7 +1676,6 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 	struct virtio_hw *hw = eth_dev->data->dev_private;
 	struct virtio_net_config *config;
 	struct virtio_net_config local_config;
-	struct rte_pci_device *pci_dev = NULL;
 	int ret;
 
 	/* Reset the device although not necessary at startup */
@@ -1697,9 +1696,6 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 
 	hw->weak_barriers = !vtpci_with_feature(hw, VIRTIO_F_ORDER_PLATFORM);
 
-	if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY || hw->bus_type == VIRTIO_BUS_PCI_MODERN)
-		pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
-
 	/* If host does not support both status and MSI-X then disable LSC */
 	if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS) &&
 	    hw->use_msix != VIRTIO_MSIX_NONE)
@@ -1828,45 +1824,9 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 
 	vtpci_reinit_complete(hw);
 
-	if (pci_dev)
-		PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x",
-			eth_dev->data->port_id, pci_dev->id.vendor_id,
-			pci_dev->id.device_id);
-
 	return 0;
 }
 
-/*
- * Remap the PCI device again (IO port map for legacy device and
- * memory map for modern device), so that the secondary process
- * could have the PCI initiated correctly.
- */
-static int
-virtio_remap_pci(struct rte_pci_device *pci_dev, struct virtio_hw *hw)
-{
-	if (hw->bus_type == VIRTIO_BUS_PCI_MODERN) {
-		/*
-		 * We don't have to re-parse the PCI config space, since
-		 * rte_pci_map_device() makes sure the mapped address
-		 * in secondary process would equal to the one mapped in
-		 * the primary process: error will be returned if that
-		 * requirement is not met.
-		 *
-		 * That said, we could simply reuse all cap pointers
-		 * (such as dev_cfg, common_cfg, etc.) parsed from the
-		 * primary process, which is stored in shared memory.
-		 */
-		if (rte_pci_map_device(pci_dev)) {
-			PMD_INIT_LOG(DEBUG, "failed to map pci device!");
-			return -1;
-		}
-	} else if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY) {
-		if (rte_pci_ioport_map(pci_dev, 0, VTPCI_IO(hw)) < 0)
-			return -1;
-	}
-
-	return 0;
-}
 
 static void
 virtio_set_vtpci_ops(struct virtio_hw *hw)
@@ -1909,17 +1869,11 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 	eth_dev->rx_descriptor_done = virtio_dev_rx_queue_done;
 
 	if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
-		if (hw->bus_type != VIRTIO_BUS_USER) {
-			ret = virtio_remap_pci(RTE_ETH_DEV_TO_PCI(eth_dev), hw);
-			if (ret)
-				return ret;
-		}
-
 		virtio_set_vtpci_ops(hw);
 		set_rxtx_funcs(eth_dev);
-
 		return 0;
 	}
+
 	ret = virtio_dev_devargs_parse(eth_dev->device->devargs, &speed, &vectorized);
 	if (ret < 0)
 		return ret;
@@ -1936,15 +1890,6 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 	}
 
 	hw->port_id = eth_dev->data->port_id;
-	/* For virtio_user case the hw->virtio_user_dev is populated by
-	 * virtio_user_eth_dev_alloc() before eth_virtio_dev_init() is called.
-	 */
-	if (hw->bus_type != VIRTIO_BUS_USER) {
-		ret = vtpci_init(RTE_ETH_DEV_TO_PCI(eth_dev), hw);
-		if (ret)
-			goto err_vtpci_init;
-	}
-
 	rte_spinlock_init(&hw->state_lock);
 
 	/* reset device and negotiate default features */
@@ -1971,12 +1916,6 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 	return 0;
 
 err_virtio_init:
-	if (hw->bus_type == VIRTIO_BUS_PCI_MODERN || hw->bus_type == VIRTIO_BUS_PCI_LEGACY) {
-		rte_pci_unmap_device(RTE_ETH_DEV_TO_PCI(eth_dev));
-		if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY)
-			rte_pci_ioport_unmap(VTPCI_IO(hw));
-	}
-err_vtpci_init:
 	rte_free(eth_dev->data->mac_addrs);
 	eth_dev->data->mac_addrs = NULL;
 	return ret;
diff --git a/drivers/net/virtio/virtio_pci_ethdev.c b/drivers/net/virtio/virtio_pci_ethdev.c
index 7c849d01ec..6a0ef6edc3 100644
--- a/drivers/net/virtio/virtio_pci_ethdev.c
+++ b/drivers/net/virtio/virtio_pci_ethdev.c
@@ -32,10 +32,79 @@ static const struct rte_pci_id pci_id_virtio_map[] = {
 	{ .vendor_id = 0, /* sentinel */ },
 };
 
+
+/*
+ * Remap the PCI device again (IO port map for legacy device and
+ * memory map for modern device), so that the secondary process
+ * could have the PCI initiated correctly.
+ */
+static int
+virtio_remap_pci(struct rte_pci_device *pci_dev, struct virtio_hw *hw)
+{
+	if (hw->bus_type == VIRTIO_BUS_PCI_MODERN) {
+		/*
+		 * We don't have to re-parse the PCI config space, since
+		 * rte_pci_map_device() makes sure the mapped address
+		 * in secondary process would equal to the one mapped in
+		 * the primary process: error will be returned if that
+		 * requirement is not met.
+		 *
+		 * That said, we could simply reuse all cap pointers
+		 * (such as dev_cfg, common_cfg, etc.) parsed from the
+		 * primary process, which is stored in shared memory.
+		 */
+		if (rte_pci_map_device(pci_dev)) {
+			PMD_INIT_LOG(DEBUG, "failed to map pci device!");
+			return -1;
+		}
+	} else if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY) {
+		if (rte_pci_ioport_map(pci_dev, 0, VTPCI_IO(hw)) < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
 static int
 eth_virtio_pci_init(struct rte_eth_dev *eth_dev)
 {
-	return eth_virtio_dev_init(eth_dev);
+	struct virtio_pci_dev *dev = eth_dev->data->dev_private;
+	struct virtio_hw *hw = &dev->hw;
+	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+	int ret;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		ret = vtpci_init(RTE_ETH_DEV_TO_PCI(eth_dev), hw);
+		if (ret) {
+			PMD_INIT_LOG(ERR, "Failed to init PCI device\n");
+			return -1;
+		}
+	} else {
+		ret = virtio_remap_pci(RTE_ETH_DEV_TO_PCI(eth_dev), hw);
+		if (ret < 0) {
+			PMD_INIT_LOG(ERR, "Failed to remap PCI device\n");
+			return -1;
+		}
+	}
+
+	ret = eth_virtio_dev_init(eth_dev);
+	if (ret < 0) {
+		PMD_INIT_LOG(ERR, "Failed to init virtio device\n");
+		goto err_unmap;
+	}
+
+	PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x",
+		eth_dev->data->port_id, pci_dev->id.vendor_id,
+		pci_dev->id.device_id);
+
+	return 0;
+
+err_unmap:
+	rte_pci_unmap_device(RTE_ETH_DEV_TO_PCI(eth_dev));
+	if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY)
+		rte_pci_ioport_unmap(VTPCI_IO(hw));
+
+	return ret;
 }
 
 static int
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 09/44] net/virtio: move MSIX detection to PCI ethdev
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (7 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 08/44] net/virtio: move PCI specific dev init to PCI ethdev init Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-21  7:12   ` Xia, Chenbo
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 10/44] net/virtio: force IOVA as VA mode for Virtio-user Maxime Coquelin
                   ` (34 subsequent siblings)
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch introduces a new callback to notify the bus
driver some interrupt related operation was done.

This is used by Virtio PCI driver to check msix status.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_ethdev.c     |  12 +--
 drivers/net/virtio/virtio_pci.c        | 120 ++++++++++++++-----------
 drivers/net/virtio/virtio_pci.h        |   6 +-
 drivers/net/virtio/virtio_pci_ethdev.c |   2 +
 4 files changed, 82 insertions(+), 58 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index a3e81f336d..13d5a76376 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1287,8 +1287,8 @@ virtio_intr_unmask(struct rte_eth_dev *dev)
 	if (rte_intr_ack(dev->intr_handle) < 0)
 		return -1;
 
-	if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY || hw->bus_type == VIRTIO_BUS_PCI_MODERN)
-		hw->use_msix = vtpci_msix_detect(RTE_ETH_DEV_TO_PCI(dev));
+	if (VTPCI_OPS(hw)->intr_event)
+		VTPCI_OPS(hw)->intr_event(hw);
 
 	return 0;
 }
@@ -1301,8 +1301,8 @@ virtio_intr_enable(struct rte_eth_dev *dev)
 	if (rte_intr_enable(dev->intr_handle) < 0)
 		return -1;
 
-	if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY || hw->bus_type == VIRTIO_BUS_PCI_MODERN)
-		hw->use_msix = vtpci_msix_detect(RTE_ETH_DEV_TO_PCI(dev));
+	if (VTPCI_OPS(hw)->intr_event)
+		VTPCI_OPS(hw)->intr_event(hw);
 
 	return 0;
 }
@@ -1315,8 +1315,8 @@ virtio_intr_disable(struct rte_eth_dev *dev)
 	if (rte_intr_disable(dev->intr_handle) < 0)
 		return -1;
 
-	if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY || hw->bus_type == VIRTIO_BUS_PCI_MODERN)
-		hw->use_msix = vtpci_msix_detect(RTE_ETH_DEV_TO_PCI(dev));
+	if (VTPCI_OPS(hw)->intr_event)
+		VTPCI_OPS(hw)->intr_event(hw);
 
 	return 0;
 }
diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index 345d73f868..63bc31f732 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -47,6 +47,56 @@ check_vq_phys_addr_ok(struct virtqueue *vq)
 	return 1;
 }
 
+#define PCI_MSIX_ENABLE 0x8000
+
+static enum virtio_msix_status
+vtpci_msix_detect(struct rte_pci_device *dev)
+{
+	uint8_t pos;
+	int ret;
+
+	ret = rte_pci_read_config(dev, &pos, 1, PCI_CAPABILITY_LIST);
+	if (ret != 1) {
+		PMD_INIT_LOG(DEBUG,
+			     "failed to read pci capability list, ret %d", ret);
+		return VIRTIO_MSIX_NONE;
+	}
+
+	while (pos) {
+		uint8_t cap[2];
+
+		ret = rte_pci_read_config(dev, cap, sizeof(cap), pos);
+		if (ret != sizeof(cap)) {
+			PMD_INIT_LOG(DEBUG,
+				     "failed to read pci cap at pos: %x ret %d",
+				     pos, ret);
+			break;
+		}
+
+		if (cap[0] == PCI_CAP_ID_MSIX) {
+			uint16_t flags;
+
+			ret = rte_pci_read_config(dev, &flags, sizeof(flags),
+					pos + sizeof(cap));
+			if (ret != sizeof(flags)) {
+				PMD_INIT_LOG(DEBUG,
+					     "failed to read pci cap at pos:"
+					     " %x ret %d", pos + 2, ret);
+				break;
+			}
+
+			if (flags & PCI_MSIX_ENABLE)
+				return VIRTIO_MSIX_ENABLED;
+			else
+				return VIRTIO_MSIX_DISABLED;
+		}
+
+		pos = cap[1];
+	}
+
+	return VIRTIO_MSIX_NONE;
+}
+
 /*
  * Since we are in legacy mode:
  * http://ozlabs.org/~rusty/virtio-spec/virtio-0.9.5.pdf
@@ -241,6 +291,12 @@ legacy_notify_queue(struct virtio_hw *hw, struct virtqueue *vq)
 		VIRTIO_PCI_QUEUE_NOTIFY);
 }
 
+static void
+legacy_intr_event(struct virtio_hw *hw)
+{
+	hw->use_msix = vtpci_msix_detect(VTPCI_DEV(hw));
+}
+
 const struct virtio_pci_ops legacy_ops = {
 	.read_dev_cfg	= legacy_read_dev_config,
 	.write_dev_cfg	= legacy_write_dev_config,
@@ -255,6 +311,7 @@ const struct virtio_pci_ops legacy_ops = {
 	.setup_queue	= legacy_setup_queue,
 	.del_queue	= legacy_del_queue,
 	.notify_queue	= legacy_notify_queue,
+	.intr_event	= legacy_intr_event,
 };
 
 static inline void
@@ -446,6 +503,14 @@ modern_notify_queue(struct virtio_hw *hw, struct virtqueue *vq)
 	rte_write32(notify_data, vq->notify_addr);
 }
 
+
+
+static void
+modern_intr_event(struct virtio_hw *hw)
+{
+	hw->use_msix = vtpci_msix_detect(VTPCI_DEV(hw));
+}
+
 const struct virtio_pci_ops modern_ops = {
 	.read_dev_cfg	= modern_read_dev_config,
 	.write_dev_cfg	= modern_write_dev_config,
@@ -460,6 +525,7 @@ const struct virtio_pci_ops modern_ops = {
 	.setup_queue	= modern_setup_queue,
 	.del_queue	= modern_del_queue,
 	.notify_queue	= modern_notify_queue,
+	.intr_event	= modern_intr_event,
 };
 
 
@@ -562,8 +628,6 @@ get_cfg_addr(struct rte_pci_device *dev, struct virtio_pci_cap *cap)
 	return base + offset;
 }
 
-#define PCI_MSIX_ENABLE 0x8000
-
 static int
 virtio_read_caps(struct rte_pci_device *dev, struct virtio_hw *hw)
 {
@@ -700,7 +764,7 @@ vtpci_init(struct rte_pci_device *dev, struct virtio_hw *hw)
 		PMD_INIT_LOG(INFO, "modern virtio pci detected.");
 		virtio_hw_internal[hw->port_id].vtpci_ops = &modern_ops;
 		hw->bus_type = VIRTIO_BUS_PCI_MODERN;
-		return 0;
+		goto msix_detect;
 	}
 
 	PMD_INIT_LOG(INFO, "trying with legacy virtio pci.");
@@ -720,53 +784,9 @@ vtpci_init(struct rte_pci_device *dev, struct virtio_hw *hw)
 	virtio_hw_internal[hw->port_id].vtpci_ops = &legacy_ops;
 	hw->bus_type = VIRTIO_BUS_PCI_LEGACY;
 
+msix_detect:
+	hw->use_msix = vtpci_msix_detect(dev);
+
 	return 0;
 }
 
-enum virtio_msix_status
-vtpci_msix_detect(struct rte_pci_device *dev)
-{
-	uint8_t pos;
-	int ret;
-
-	ret = rte_pci_read_config(dev, &pos, 1, PCI_CAPABILITY_LIST);
-	if (ret != 1) {
-		PMD_INIT_LOG(DEBUG,
-			     "failed to read pci capability list, ret %d", ret);
-		return VIRTIO_MSIX_NONE;
-	}
-
-	while (pos) {
-		uint8_t cap[2];
-
-		ret = rte_pci_read_config(dev, cap, sizeof(cap), pos);
-		if (ret != sizeof(cap)) {
-			PMD_INIT_LOG(DEBUG,
-				     "failed to read pci cap at pos: %x ret %d",
-				     pos, ret);
-			break;
-		}
-
-		if (cap[0] == PCI_CAP_ID_MSIX) {
-			uint16_t flags;
-
-			ret = rte_pci_read_config(dev, &flags, sizeof(flags),
-					pos + sizeof(cap));
-			if (ret != sizeof(flags)) {
-				PMD_INIT_LOG(DEBUG,
-					     "failed to read pci cap at pos:"
-					     " %x ret %d", pos + 2, ret);
-				break;
-			}
-
-			if (flags & PCI_MSIX_ENABLE)
-				return VIRTIO_MSIX_ENABLED;
-			else
-				return VIRTIO_MSIX_DISABLED;
-		}
-
-		pos = cap[1];
-	}
-
-	return VIRTIO_MSIX_NONE;
-}
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 59f6688218..6f5c53c4b7 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -239,6 +239,7 @@ struct virtio_pci_ops {
 	int (*setup_queue)(struct virtio_hw *hw, struct virtqueue *vq);
 	void (*del_queue)(struct virtio_hw *hw, struct virtqueue *vq);
 	void (*notify_queue)(struct virtio_hw *hw, struct virtqueue *vq);
+	void (*intr_event)(struct virtio_hw *hw);
 };
 
 struct virtio_net_config;
@@ -303,10 +304,13 @@ struct virtio_pci_dev {
 struct virtio_hw_internal {
 	const struct virtio_pci_ops *vtpci_ops;
 	struct rte_pci_ioport io;
+	struct rte_pci_device *dev;
 };
 
 #define VTPCI_OPS(hw)	(virtio_hw_internal[(hw)->port_id].vtpci_ops)
 #define VTPCI_IO(hw)	(&virtio_hw_internal[(hw)->port_id].io)
+#define VTPCI_DEV(hw)	(virtio_hw_internal[(hw)->port_id].dev)
+
 
 extern struct virtio_hw_internal virtio_hw_internal[RTE_MAX_ETHPORTS];
 
@@ -383,8 +387,6 @@ void vtpci_read_dev_config(struct virtio_hw *, size_t, void *, int);
 
 uint8_t vtpci_isr(struct virtio_hw *);
 
-enum virtio_msix_status vtpci_msix_detect(struct rte_pci_device *dev);
-
 extern const struct virtio_pci_ops legacy_ops;
 extern const struct virtio_pci_ops modern_ops;
 extern const struct virtio_pci_ops virtio_user_ops;
diff --git a/drivers/net/virtio/virtio_pci_ethdev.c b/drivers/net/virtio/virtio_pci_ethdev.c
index 6a0ef6edc3..045b134ef2 100644
--- a/drivers/net/virtio/virtio_pci_ethdev.c
+++ b/drivers/net/virtio/virtio_pci_ethdev.c
@@ -73,6 +73,8 @@ eth_virtio_pci_init(struct rte_eth_dev *eth_dev)
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
 	int ret;
 
+	VTPCI_DEV(hw) = pci_dev;
+
 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
 		ret = vtpci_init(RTE_ETH_DEV_TO_PCI(eth_dev), hw);
 		if (ret) {
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 10/44] net/virtio: force IOVA as VA mode for Virtio-user
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (8 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 09/44] net/virtio: move MSIX detection to PCI ethdev Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 11/44] net/virtio: store PCI type in Virtio device metadata Maxime Coquelin
                   ` (33 subsequent siblings)
  43 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

At least Vhost-user backend of Virtio-user PMD requires
IOVA as VA mode. Until now, it was implemented as a hack
by forcing to use mbuf's buf_addr field instead of buf_iova.

This patch removes all this logic and just fails probing
if IOVA as VA mode is not selected. It simplifies the
code overall, and removes some bus-specific logic from
generic virtio_ethdev.c.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c           | 15 ---------
 drivers/net/virtio/virtio_rxtx.c             | 34 ++++++++------------
 drivers/net/virtio/virtio_rxtx_packed.h      |  2 +-
 drivers/net/virtio/virtio_rxtx_packed_avx.h  |  8 ++---
 drivers/net/virtio/virtio_rxtx_packed_neon.h |  8 ++---
 drivers/net/virtio/virtio_rxtx_simple.h      |  3 +-
 drivers/net/virtio/virtio_user_ethdev.c      |  1 +
 drivers/net/virtio/virtqueue.h               | 25 +-------------
 8 files changed, 26 insertions(+), 70 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 13d5a76376..da0e168355 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -576,21 +576,6 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
 		hw->cvq = cvq;
 	}
 
-	/* For virtio_user case (that is when hw->virtio_user_dev is not NULL),
-	 * we use virtual address. And we need properly set _offset_, please see
-	 * VIRTIO_MBUF_DATA_DMA_ADDR in virtqueue.h for more information.
-	 */
-	if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY || hw->bus_type == VIRTIO_BUS_PCI_MODERN) {
-		vq->offset = offsetof(struct rte_mbuf, buf_iova);
-	} else if (hw->bus_type == VIRTIO_BUS_USER) {
-		vq->vq_ring_mem = (uintptr_t)mz->addr;
-		vq->offset = offsetof(struct rte_mbuf, buf_addr);
-		if (queue_type == VTNET_TQ)
-			txvq->virtio_net_hdr_mem = (uintptr_t)hdr_mz->addr;
-		else if (queue_type == VTNET_CQ)
-			cvq->virtio_net_hdr_mem = (uintptr_t)hdr_mz->addr;
-	}
-
 	if (queue_type == VTNET_TQ) {
 		struct virtio_tx_region *txr;
 		unsigned int i;
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index 622d4bf201..6875c8fbee 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -271,13 +271,10 @@ virtqueue_enqueue_refill_inorder(struct virtqueue *vq,
 		dxp->cookie = (void *)cookies[i];
 		dxp->ndescs = 1;
 
-		start_dp[idx].addr =
-				VIRTIO_MBUF_ADDR(cookies[i], vq) +
-				RTE_PKTMBUF_HEADROOM - hw->vtnet_hdr_size;
-		start_dp[idx].len =
-				cookies[i]->buf_len -
-				RTE_PKTMBUF_HEADROOM +
-				hw->vtnet_hdr_size;
+		start_dp[idx].addr = cookies[i]->buf_iova +
+			RTE_PKTMBUF_HEADROOM - hw->vtnet_hdr_size;
+		start_dp[idx].len = cookies[i]->buf_len -
+			RTE_PKTMBUF_HEADROOM + hw->vtnet_hdr_size;
 		start_dp[idx].flags =  VRING_DESC_F_WRITE;
 
 		vq_update_avail_ring(vq, idx);
@@ -313,12 +310,10 @@ virtqueue_enqueue_recv_refill(struct virtqueue *vq, struct rte_mbuf **cookie,
 		dxp->cookie = (void *)cookie[i];
 		dxp->ndescs = 1;
 
-		start_dp[idx].addr =
-			VIRTIO_MBUF_ADDR(cookie[i], vq) +
+		start_dp[idx].addr = cookie[i]->buf_iova +
 			RTE_PKTMBUF_HEADROOM - hw->vtnet_hdr_size;
-		start_dp[idx].len =
-			cookie[i]->buf_len - RTE_PKTMBUF_HEADROOM +
-			hw->vtnet_hdr_size;
+		start_dp[idx].len = cookie[i]->buf_len -
+			RTE_PKTMBUF_HEADROOM + hw->vtnet_hdr_size;
 		start_dp[idx].flags = VRING_DESC_F_WRITE;
 		vq->vq_desc_head_idx = start_dp[idx].next;
 		vq_update_avail_ring(vq, idx);
@@ -355,10 +350,10 @@ virtqueue_enqueue_recv_refill_packed(struct virtqueue *vq,
 		dxp->cookie = (void *)cookie[i];
 		dxp->ndescs = 1;
 
-		start_dp[idx].addr = VIRTIO_MBUF_ADDR(cookie[i], vq) +
-				RTE_PKTMBUF_HEADROOM - hw->vtnet_hdr_size;
-		start_dp[idx].len = cookie[i]->buf_len - RTE_PKTMBUF_HEADROOM
-					+ hw->vtnet_hdr_size;
+		start_dp[idx].addr = cookie[i]->buf_iova +
+			RTE_PKTMBUF_HEADROOM - hw->vtnet_hdr_size;
+		start_dp[idx].len = cookie[i]->buf_len -
+			RTE_PKTMBUF_HEADROOM + hw->vtnet_hdr_size;
 
 		vq->vq_desc_head_idx = dxp->next;
 		if (vq->vq_desc_head_idx == VQ_RING_DESC_CHAIN_END)
@@ -455,8 +450,7 @@ virtqueue_enqueue_xmit_inorder(struct virtnet_tx *txvq,
 		else
 			virtqueue_xmit_offload(hdr, cookies[i], true);
 
-		start_dp[idx].addr  =
-			VIRTIO_MBUF_DATA_DMA_ADDR(cookies[i], vq) - head_size;
+		start_dp[idx].addr  = rte_mbuf_data_iova(cookies[i]) - head_size;
 		start_dp[idx].len   = cookies[i]->data_len + head_size;
 		start_dp[idx].flags = 0;
 
@@ -503,7 +497,7 @@ virtqueue_enqueue_xmit_packed_fast(struct virtnet_tx *txvq,
 	else
 		virtqueue_xmit_offload(hdr, cookie, true);
 
-	dp->addr = VIRTIO_MBUF_DATA_DMA_ADDR(cookie, vq) - head_size;
+	dp->addr = rte_mbuf_data_iova(cookie) - head_size;
 	dp->len  = cookie->data_len + head_size;
 	dp->id   = id;
 
@@ -590,7 +584,7 @@ virtqueue_enqueue_xmit(struct virtnet_tx *txvq, struct rte_mbuf *cookie,
 	virtqueue_xmit_offload(hdr, cookie, vq->hw->has_tx_offload);
 
 	do {
-		start_dp[idx].addr  = VIRTIO_MBUF_DATA_DMA_ADDR(cookie, vq);
+		start_dp[idx].addr  = rte_mbuf_data_iova(cookie);
 		start_dp[idx].len   = cookie->data_len;
 		if (prepend_header) {
 			start_dp[idx].addr -= head_size;
diff --git a/drivers/net/virtio/virtio_rxtx_packed.h b/drivers/net/virtio/virtio_rxtx_packed.h
index 016b6fb247..c0fad41c3d 100644
--- a/drivers/net/virtio/virtio_rxtx_packed.h
+++ b/drivers/net/virtio/virtio_rxtx_packed.h
@@ -288,7 +288,7 @@ virtio_recv_refill_packed_vec(struct virtnet_rx *rxvq,
 			dxp = &vq->vq_descx[idx + i];
 			dxp->cookie = (void *)cookie[total_num + i];
 
-			addr = VIRTIO_MBUF_ADDR(cookie[total_num + i], vq) +
+			addr = cookie[total_num + i]->buf_iova +
 				RTE_PKTMBUF_HEADROOM - hw->vtnet_hdr_size;
 			start_dp[idx + i].addr = addr;
 			start_dp[idx + i].len = cookie[total_num + i]->buf_len
diff --git a/drivers/net/virtio/virtio_rxtx_packed_avx.h b/drivers/net/virtio/virtio_rxtx_packed_avx.h
index f831828845..2c610d57de 100644
--- a/drivers/net/virtio/virtio_rxtx_packed_avx.h
+++ b/drivers/net/virtio/virtio_rxtx_packed_avx.h
@@ -71,13 +71,13 @@ virtqueue_enqueue_batch_packed_vec(struct virtnet_tx *txvq,
 	}
 
 	__m512i descs_base = _mm512_set_epi64(tx_pkts[3]->data_len,
-			VIRTIO_MBUF_ADDR(tx_pkts[3], vq),
+			tx_pkts[3]->buf_iova,
 			tx_pkts[2]->data_len,
-			VIRTIO_MBUF_ADDR(tx_pkts[2], vq),
+			tx_pkts[2]->buf_iova,
 			tx_pkts[1]->data_len,
-			VIRTIO_MBUF_ADDR(tx_pkts[1], vq),
+			tx_pkts[1]->buf_iova,
 			tx_pkts[0]->data_len,
-			VIRTIO_MBUF_ADDR(tx_pkts[0], vq));
+			tx_pkts[0]->buf_iova);
 
 	/* id offset and data offset */
 	__m512i data_offsets = _mm512_set_epi64((uint64_t)3 << ID_BITS_OFFSET,
diff --git a/drivers/net/virtio/virtio_rxtx_packed_neon.h b/drivers/net/virtio/virtio_rxtx_packed_neon.h
index 01c77b712d..ae2d099c0b 100644
--- a/drivers/net/virtio/virtio_rxtx_packed_neon.h
+++ b/drivers/net/virtio/virtio_rxtx_packed_neon.h
@@ -97,12 +97,12 @@ virtqueue_enqueue_batch_packed_vec(struct virtnet_tx *txvq,
 
 	uint64x2x2_t desc[PACKED_BATCH_SIZE / 2];
 	uint64x2_t base_addr0 = {
-		VIRTIO_MBUF_ADDR(tx_pkts[0], vq) + tx_pkts[0]->data_off,
-		VIRTIO_MBUF_ADDR(tx_pkts[1], vq) + tx_pkts[1]->data_off
+		tx_pkts[0]->buf_iova + tx_pkts[0]->data_off,
+		tx_pkts[1]->buf_iova + tx_pkts[1]->data_off
 	};
 	uint64x2_t base_addr1 = {
-		VIRTIO_MBUF_ADDR(tx_pkts[2], vq) + tx_pkts[2]->data_off,
-		VIRTIO_MBUF_ADDR(tx_pkts[3], vq) + tx_pkts[3]->data_off
+		tx_pkts[2]->buf_iova + tx_pkts[2]->data_off,
+		tx_pkts[3]->buf_iova + tx_pkts[3]->data_off
 	};
 
 	desc[0].val[0] = base_addr0;
diff --git a/drivers/net/virtio/virtio_rxtx_simple.h b/drivers/net/virtio/virtio_rxtx_simple.h
index 3d1296a23c..f2a5aedf97 100644
--- a/drivers/net/virtio/virtio_rxtx_simple.h
+++ b/drivers/net/virtio/virtio_rxtx_simple.h
@@ -43,8 +43,7 @@ virtio_rxq_rearm_vec(struct virtnet_rx *rxvq)
 		p = (uintptr_t)&sw_ring[i]->rearm_data;
 		*(uint64_t *)p = rxvq->mbuf_initializer;
 
-		start_dp[i].addr =
-			VIRTIO_MBUF_ADDR(sw_ring[i], vq) +
+		start_dp[i].addr = sw_ring[i]->buf_iova +
 			RTE_PKTMBUF_HEADROOM - vq->hw->vtnet_hdr_size;
 		start_dp[i].len = sw_ring[i]->buf_len -
 			RTE_PKTMBUF_HEADROOM + vq->hw->vtnet_hdr_size;
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index 620ecb126c..241fe373b9 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -953,6 +953,7 @@ static struct rte_vdev_driver virtio_user_driver = {
 	.remove = virtio_user_pmd_remove,
 	.dma_map = virtio_user_pmd_dma_map,
 	.dma_unmap = virtio_user_pmd_dma_unmap,
+	.drv_flags = RTE_VDEV_DRV_NEED_IOVA_AS_VA,
 };
 
 RTE_PMD_REGISTER_VDEV(net_virtio_user, virtio_user_driver);
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index d78b943443..7611317581 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -113,29 +113,6 @@ virtqueue_store_flags_packed(struct vring_packed_desc *dp,
 
 #define VIRTQUEUE_MAX_NAME_SZ 32
 
-#ifdef RTE_VIRTIO_USER
-/**
- * Return the physical address (or virtual address in case of
- * virtio-user) of mbuf data buffer.
- *
- * The address is firstly casted to the word size (sizeof(uintptr_t))
- * before casting it to uint64_t. This is to make it work with different
- * combination of word size (64 bit and 32 bit) and virtio device
- * (virtio-pci and virtio-user).
- */
-#define VIRTIO_MBUF_ADDR(mb, vq) \
-	((uint64_t)(*(uintptr_t *)((uintptr_t)(mb) + (vq)->offset)))
-#else
-#define VIRTIO_MBUF_ADDR(mb, vq) ((mb)->buf_iova)
-#endif
-
-/**
- * Return the physical address (or virtual address in case of
- * virtio-user) of mbuf data buffer, taking care of mbuf data offset
- */
-#define VIRTIO_MBUF_DATA_DMA_ADDR(mb, vq) \
-	(VIRTIO_MBUF_ADDR(mb, vq) + (mb)->data_off)
-
 #define VTNET_SQ_RQ_QUEUE_IDX 0
 #define VTNET_SQ_TQ_QUEUE_IDX 1
 #define VTNET_SQ_CQ_QUEUE_IDX 2
@@ -763,7 +740,7 @@ virtqueue_enqueue_xmit_packed(struct virtnet_tx *txvq, struct rte_mbuf *cookie,
 	do {
 		uint16_t flags;
 
-		start_dp[idx].addr = VIRTIO_MBUF_DATA_DMA_ADDR(cookie, vq);
+		start_dp[idx].addr = rte_mbuf_data_iova(cookie);
 		start_dp[idx].len  = cookie->data_len;
 		if (prepend_header) {
 			start_dp[idx].addr -= head_size;
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 11/44] net/virtio: store PCI type in Virtio device metadata
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (9 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 10/44] net/virtio: force IOVA as VA mode for Virtio-user Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 12/44] net/virtio: add callback for device closing Maxime Coquelin
                   ` (32 subsequent siblings)
  43 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

Going further in making the Virtio ethdev layer bus agnostic,
this patch adds a boolean in the Virtio PCI device metadata.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
Reviewed-by: David Marchand <david.marchand@redhat.com>
---
 drivers/net/virtio/virtio_pci.c        | 20 ++++++++++++--------
 drivers/net/virtio/virtio_pci.h        |  3 ++-
 drivers/net/virtio/virtio_pci_ethdev.c | 12 +++++++-----
 3 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index 63bc31f732..7475d5af3a 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -751,8 +751,10 @@ virtio_read_caps(struct rte_pci_device *dev, struct virtio_hw *hw)
  * Return 0 on success.
  */
 int
-vtpci_init(struct rte_pci_device *dev, struct virtio_hw *hw)
+vtpci_init(struct rte_pci_device *pci_dev, struct virtio_pci_dev *dev)
 {
+	struct virtio_hw *hw = &dev->hw;
+
 	RTE_BUILD_BUG_ON(offsetof(struct virtio_pci_dev, hw) != 0);
 
 	/*
@@ -760,19 +762,20 @@ vtpci_init(struct rte_pci_device *dev, struct virtio_hw *hw)
 	 * only on modern pci device. If failed, we fallback to legacy
 	 * virtio handling.
 	 */
-	if (virtio_read_caps(dev, hw) == 0) {
+	if (virtio_read_caps(pci_dev, hw) == 0) {
 		PMD_INIT_LOG(INFO, "modern virtio pci detected.");
 		virtio_hw_internal[hw->port_id].vtpci_ops = &modern_ops;
 		hw->bus_type = VIRTIO_BUS_PCI_MODERN;
+		dev->modern = true;
 		goto msix_detect;
 	}
 
 	PMD_INIT_LOG(INFO, "trying with legacy virtio pci.");
-	if (rte_pci_ioport_map(dev, 0, VTPCI_IO(hw)) < 0) {
-		rte_pci_unmap_device(dev);
-		if (dev->kdrv == RTE_PCI_KDRV_UNKNOWN &&
-		    (!dev->device.devargs ||
-		     dev->device.devargs->bus !=
+	if (rte_pci_ioport_map(pci_dev, 0, VTPCI_IO(hw)) < 0) {
+		rte_pci_unmap_device(pci_dev);
+		if (pci_dev->kdrv == RTE_PCI_KDRV_UNKNOWN &&
+		    (!pci_dev->device.devargs ||
+		     pci_dev->device.devargs->bus !=
 		     rte_bus_find_by_name("pci"))) {
 			PMD_INIT_LOG(INFO,
 				"skip kernel managed virtio device.");
@@ -783,9 +786,10 @@ vtpci_init(struct rte_pci_device *dev, struct virtio_hw *hw)
 
 	virtio_hw_internal[hw->port_id].vtpci_ops = &legacy_ops;
 	hw->bus_type = VIRTIO_BUS_PCI_LEGACY;
+	dev->modern = false;
 
 msix_detect:
-	hw->use_msix = vtpci_msix_detect(dev);
+	hw->use_msix = vtpci_msix_detect(pci_dev);
 
 	return 0;
 }
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 6f5c53c4b7..61850ec4b2 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -292,6 +292,7 @@ struct virtio_hw {
 
 struct virtio_pci_dev {
 	struct virtio_hw hw;
+	bool modern;
 };
 
 #define virtio_pci_get_dev(hwp) container_of(hwp, struct virtio_pci_dev, hw)
@@ -371,7 +372,7 @@ vtpci_packed_queue(struct virtio_hw *hw)
 /*
  * Function declaration from virtio_pci.c
  */
-int vtpci_init(struct rte_pci_device *dev, struct virtio_hw *hw);
+int vtpci_init(struct rte_pci_device *pci_dev, struct virtio_pci_dev *dev);
 void vtpci_reset(struct virtio_hw *);
 
 void vtpci_reinit_complete(struct virtio_hw *);
diff --git a/drivers/net/virtio/virtio_pci_ethdev.c b/drivers/net/virtio/virtio_pci_ethdev.c
index 045b134ef2..076a5dbced 100644
--- a/drivers/net/virtio/virtio_pci_ethdev.c
+++ b/drivers/net/virtio/virtio_pci_ethdev.c
@@ -39,9 +39,11 @@ static const struct rte_pci_id pci_id_virtio_map[] = {
  * could have the PCI initiated correctly.
  */
 static int
-virtio_remap_pci(struct rte_pci_device *pci_dev, struct virtio_hw *hw)
+virtio_remap_pci(struct rte_pci_device *pci_dev, struct virtio_pci_dev *dev)
 {
-	if (hw->bus_type == VIRTIO_BUS_PCI_MODERN) {
+	struct virtio_hw *hw = &dev->hw;
+
+	if (dev->modern) {
 		/*
 		 * We don't have to re-parse the PCI config space, since
 		 * rte_pci_map_device() makes sure the mapped address
@@ -57,7 +59,7 @@ virtio_remap_pci(struct rte_pci_device *pci_dev, struct virtio_hw *hw)
 			PMD_INIT_LOG(DEBUG, "failed to map pci device!");
 			return -1;
 		}
-	} else if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY) {
+	} else {
 		if (rte_pci_ioport_map(pci_dev, 0, VTPCI_IO(hw)) < 0)
 			return -1;
 	}
@@ -76,13 +78,13 @@ eth_virtio_pci_init(struct rte_eth_dev *eth_dev)
 	VTPCI_DEV(hw) = pci_dev;
 
 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
-		ret = vtpci_init(RTE_ETH_DEV_TO_PCI(eth_dev), hw);
+		ret = vtpci_init(RTE_ETH_DEV_TO_PCI(eth_dev), dev);
 		if (ret) {
 			PMD_INIT_LOG(ERR, "Failed to init PCI device\n");
 			return -1;
 		}
 	} else {
-		ret = virtio_remap_pci(RTE_ETH_DEV_TO_PCI(eth_dev), hw);
+		ret = virtio_remap_pci(RTE_ETH_DEV_TO_PCI(eth_dev), dev);
 		if (ret < 0) {
 			PMD_INIT_LOG(ERR, "Failed to remap PCI device\n");
 			return -1;
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 12/44] net/virtio: add callback for device closing
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (10 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 11/44] net/virtio: store PCI type in Virtio device metadata Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 13/44] net/virtio: validate features at bus level Maxime Coquelin
                   ` (31 subsequent siblings)
  43 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch introduces a new callback for device closing,
making virtio_dev_close() bus-agnostic.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
Reviewed-by: David Marchand <david.marchand@redhat.com>
---
 drivers/net/virtio/meson.build          |  2 --
 drivers/net/virtio/virtio_ethdev.c      | 13 +------------
 drivers/net/virtio/virtio_pci.c         | 25 +++++++++++++++++++++++++
 drivers/net/virtio/virtio_pci.h         |  2 ++
 drivers/net/virtio/virtio_user_ethdev.c | 11 +++++++++++
 5 files changed, 39 insertions(+), 14 deletions(-)

diff --git a/drivers/net/virtio/meson.build b/drivers/net/virtio/meson.build
index 07e085376b..f2873d6180 100644
--- a/drivers/net/virtio/meson.build
+++ b/drivers/net/virtio/meson.build
@@ -44,8 +44,6 @@ elif arch_subdir == 'arm' and host_machine.cpu_family().startswith('aarch64')
 endif
 
 if is_linux
-	dpdk_conf.set('RTE_VIRTIO_USER', 1)
-
 	sources += files('virtio_user_ethdev.c',
 		'virtio_user/vhost_kernel.c',
 		'virtio_user/vhost_kernel_tap.c',
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index da0e168355..7e2240fd79 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -718,18 +718,7 @@ virtio_dev_close(struct rte_eth_dev *dev)
 	virtio_dev_free_mbufs(dev);
 	virtio_free_queues(hw);
 
-#ifdef RTE_VIRTIO_USER
-	if (hw->bus_type == VIRTIO_BUS_USER)
-		virtio_user_dev_uninit(dev->data->dev_private);
-	else
-#endif
-	if (dev->device) {
-		rte_pci_unmap_device(RTE_ETH_DEV_TO_PCI(dev));
-		if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY)
-			rte_pci_ioport_unmap(VTPCI_IO(hw));
-	}
-
-	return 0;
+	return VTPCI_OPS(hw)->dev_close(hw);
 }
 
 static int
diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index 7475d5af3a..145bc38de3 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -297,6 +297,17 @@ legacy_intr_event(struct virtio_hw *hw)
 	hw->use_msix = vtpci_msix_detect(VTPCI_DEV(hw));
 }
 
+static int
+legacy_dev_close(struct virtio_hw *hw)
+{
+	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
+
+	rte_pci_unmap_device(dev->pci_dev);
+	rte_pci_ioport_unmap(VTPCI_IO(hw));
+
+	return 0;
+}
+
 const struct virtio_pci_ops legacy_ops = {
 	.read_dev_cfg	= legacy_read_dev_config,
 	.write_dev_cfg	= legacy_write_dev_config,
@@ -312,6 +323,7 @@ const struct virtio_pci_ops legacy_ops = {
 	.del_queue	= legacy_del_queue,
 	.notify_queue	= legacy_notify_queue,
 	.intr_event	= legacy_intr_event,
+	.dev_close	= legacy_dev_close,
 };
 
 static inline void
@@ -511,6 +523,16 @@ modern_intr_event(struct virtio_hw *hw)
 	hw->use_msix = vtpci_msix_detect(VTPCI_DEV(hw));
 }
 
+static int
+modern_dev_close(struct virtio_hw *hw)
+{
+	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
+
+	rte_pci_unmap_device(dev->pci_dev);
+
+	return 0;
+}
+
 const struct virtio_pci_ops modern_ops = {
 	.read_dev_cfg	= modern_read_dev_config,
 	.write_dev_cfg	= modern_write_dev_config,
@@ -526,6 +548,7 @@ const struct virtio_pci_ops modern_ops = {
 	.del_queue	= modern_del_queue,
 	.notify_queue	= modern_notify_queue,
 	.intr_event	= modern_intr_event,
+	.dev_close	= modern_dev_close,
 };
 
 
@@ -757,6 +780,8 @@ vtpci_init(struct rte_pci_device *pci_dev, struct virtio_pci_dev *dev)
 
 	RTE_BUILD_BUG_ON(offsetof(struct virtio_pci_dev, hw) != 0);
 
+	dev->pci_dev = pci_dev;
+
 	/*
 	 * Try if we can succeed reading virtio pci caps, which exists
 	 * only on modern pci device. If failed, we fallback to legacy
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 61850ec4b2..d1bed0ad59 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -240,6 +240,7 @@ struct virtio_pci_ops {
 	void (*del_queue)(struct virtio_hw *hw, struct virtqueue *vq);
 	void (*notify_queue)(struct virtio_hw *hw, struct virtqueue *vq);
 	void (*intr_event)(struct virtio_hw *hw);
+	int (*dev_close)(struct virtio_hw *hw);
 };
 
 struct virtio_net_config;
@@ -292,6 +293,7 @@ struct virtio_hw {
 
 struct virtio_pci_dev {
 	struct virtio_hw hw;
+	struct rte_pci_device *pci_dev;
 	bool modern;
 };
 
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index 241fe373b9..3cbf310c03 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -462,6 +462,16 @@ virtio_user_notify_queue(struct virtio_hw *hw, struct virtqueue *vq)
 			    strerror(errno));
 }
 
+static int
+virtio_user_dev_close(struct virtio_hw *hw)
+{
+	struct virtio_user_dev *dev = virtio_user_get_dev(hw);
+
+	virtio_user_dev_uninit(dev);
+
+	return 0;
+}
+
 const struct virtio_pci_ops virtio_user_ops = {
 	.read_dev_cfg	= virtio_user_read_dev_config,
 	.write_dev_cfg	= virtio_user_write_dev_config,
@@ -476,6 +486,7 @@ const struct virtio_pci_ops virtio_user_ops = {
 	.setup_queue	= virtio_user_setup_queue,
 	.del_queue	= virtio_user_del_queue,
 	.notify_queue	= virtio_user_notify_queue,
+	.dev_close	= virtio_user_dev_close,
 };
 
 static const char *valid_args[] = {
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 13/44] net/virtio: validate features at bus level
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (11 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 12/44] net/virtio: add callback for device closing Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 14/44] net/virtio: remove bus type enum Maxime Coquelin
                   ` (30 subsequent siblings)
  43 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch provides a new callback for the bus type
to validate negotiated features are compatible with it.

Only user for now is PCI modern bus type, which implies
that the device supports Virtio 1.0+.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c      | 11 ++++-------
 drivers/net/virtio/virtio_pci.c         | 19 +++++++++++++++++++
 drivers/net/virtio/virtio_pci.h         |  1 +
 drivers/net/virtio/virtio_user_ethdev.c |  7 +++++++
 4 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 7e2240fd79..747e70171f 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1330,17 +1330,14 @@ virtio_negotiate_features(struct virtio_hw *hw, uint64_t req_features)
 	PMD_INIT_LOG(DEBUG, "features after negotiate = %" PRIx64,
 		hw->guest_features);
 
-	if (hw->bus_type == VIRTIO_BUS_PCI_MODERN && !vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) {
-		PMD_INIT_LOG(ERR,
-			"VIRTIO_F_VERSION_1 features is not enabled.");
+	if (VTPCI_OPS(hw)->features_ok(hw) < 0)
 		return -1;
-	}
 
-	if (hw->bus_type == VIRTIO_BUS_PCI_MODERN || hw->bus_type == VIRTIO_BUS_USER) {
+	if (vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) {
 		vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_FEATURES_OK);
+
 		if (!(vtpci_get_status(hw) & VIRTIO_CONFIG_STATUS_FEATURES_OK)) {
-			PMD_INIT_LOG(ERR,
-				"failed to set FEATURES_OK status!");
+			PMD_INIT_LOG(ERR, "Failed to set FEATURES_OK status!");
 			return -1;
 		}
 	}
diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index 145bc38de3..41571522df 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -201,6 +201,12 @@ legacy_set_features(struct virtio_hw *hw, uint64_t features)
 		VIRTIO_PCI_GUEST_FEATURES);
 }
 
+static int
+legacy_features_ok(struct virtio_hw *hw __rte_unused)
+{
+	return 0;
+}
+
 static uint8_t
 legacy_get_status(struct virtio_hw *hw)
 {
@@ -315,6 +321,7 @@ const struct virtio_pci_ops legacy_ops = {
 	.set_status	= legacy_set_status,
 	.get_features	= legacy_get_features,
 	.set_features	= legacy_set_features,
+	.features_ok	= legacy_features_ok,
 	.get_isr	= legacy_get_isr,
 	.set_config_irq	= legacy_set_config_irq,
 	.set_queue_irq  = legacy_set_queue_irq,
@@ -389,6 +396,17 @@ modern_set_features(struct virtio_hw *hw, uint64_t features)
 		    &hw->common_cfg->guest_feature);
 }
 
+static int
+modern_features_ok(struct virtio_hw *hw)
+{
+	if (!vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) {
+		PMD_INIT_LOG(ERR, "Version 1+ required with modern devices\n");
+		return -1;
+	}
+
+	return 0;
+}
+
 static uint8_t
 modern_get_status(struct virtio_hw *hw)
 {
@@ -540,6 +558,7 @@ const struct virtio_pci_ops modern_ops = {
 	.set_status	= modern_set_status,
 	.get_features	= modern_get_features,
 	.set_features	= modern_set_features,
+	.features_ok	= modern_features_ok,
 	.get_isr	= modern_get_isr,
 	.set_config_irq	= modern_set_config_irq,
 	.set_queue_irq  = modern_set_queue_irq,
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index d1bed0ad59..ce43b40330 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -227,6 +227,7 @@ struct virtio_pci_ops {
 
 	uint64_t (*get_features)(struct virtio_hw *hw);
 	void     (*set_features)(struct virtio_hw *hw, uint64_t features);
+	int      (*features_ok)(struct virtio_hw *hw);
 
 	uint8_t (*get_isr)(struct virtio_hw *hw);
 
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index 3cbf310c03..bf958de571 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -327,6 +327,12 @@ virtio_user_set_features(struct virtio_hw *hw, uint64_t features)
 	dev->features = features & dev->device_features;
 }
 
+static int
+virtio_user_features_ok(struct virtio_hw *hw __rte_unused)
+{
+	return 0;
+}
+
 static uint8_t
 virtio_user_get_isr(struct virtio_hw *hw __rte_unused)
 {
@@ -479,6 +485,7 @@ const struct virtio_pci_ops virtio_user_ops = {
 	.set_status	= virtio_user_set_status,
 	.get_features	= virtio_user_get_features,
 	.set_features	= virtio_user_set_features,
+	.features_ok	= virtio_user_features_ok,
 	.get_isr	= virtio_user_get_isr,
 	.set_config_irq	= virtio_user_set_config_irq,
 	.set_queue_irq	= virtio_user_set_queue_irq,
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 14/44] net/virtio: remove bus type enum
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (12 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 13/44] net/virtio: validate features at bus level Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 15/44] net/virtio: move PCI-specific fields to PCI device Maxime Coquelin
                   ` (29 subsequent siblings)
  43 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

Bus type awareness at the generic ethdev level is no
more needed as previous patches have made it bus-agnostic.

This patch removes it from struct virtio_hw.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
Reviewed-by: David Marchand <david.marchand@redhat.com>
---
 drivers/net/virtio/virtio_ethdev.c      | 18 ------------------
 drivers/net/virtio/virtio_pci.c         |  2 --
 drivers/net/virtio/virtio_pci.h         |  8 --------
 drivers/net/virtio/virtio_pci_ethdev.c  |  7 ++++++-
 drivers/net/virtio/virtio_user_ethdev.c |  5 ++++-
 5 files changed, 10 insertions(+), 30 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 747e70171f..1df2b852ce 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1798,23 +1798,6 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 	return 0;
 }
 
-
-static void
-virtio_set_vtpci_ops(struct virtio_hw *hw)
-{
-#ifdef RTE_VIRTIO_USER
-	if (hw->bus_type == VIRTIO_BUS_USER)
-		VTPCI_OPS(hw) = &virtio_user_ops;
-	else
-#endif
-	if (hw->bus_type == VIRTIO_BUS_PCI_MODERN)
-		VTPCI_OPS(hw) = &modern_ops;
-	else if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY)
-		VTPCI_OPS(hw) = &legacy_ops;
-
-	return;
-}
-
 /*
  * This function is based on probe() function in virtio_pci.c
  * It returns 0 on success.
@@ -1840,7 +1823,6 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 	eth_dev->rx_descriptor_done = virtio_dev_rx_queue_done;
 
 	if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
-		virtio_set_vtpci_ops(hw);
 		set_rxtx_funcs(eth_dev);
 		return 0;
 	}
diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index 41571522df..90631d1a2d 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -809,7 +809,6 @@ vtpci_init(struct rte_pci_device *pci_dev, struct virtio_pci_dev *dev)
 	if (virtio_read_caps(pci_dev, hw) == 0) {
 		PMD_INIT_LOG(INFO, "modern virtio pci detected.");
 		virtio_hw_internal[hw->port_id].vtpci_ops = &modern_ops;
-		hw->bus_type = VIRTIO_BUS_PCI_MODERN;
 		dev->modern = true;
 		goto msix_detect;
 	}
@@ -829,7 +828,6 @@ vtpci_init(struct rte_pci_device *pci_dev, struct virtio_pci_dev *dev)
 	}
 
 	virtio_hw_internal[hw->port_id].vtpci_ops = &legacy_ops;
-	hw->bus_type = VIRTIO_BUS_PCI_LEGACY;
 	dev->modern = false;
 
 msix_detect:
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index ce43b40330..b6c44a7f7c 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -246,15 +246,7 @@ struct virtio_pci_ops {
 
 struct virtio_net_config;
 
-enum virtio_bus_type {
-	VIRTIO_BUS_UNKNOWN,
-	VIRTIO_BUS_PCI_LEGACY,
-	VIRTIO_BUS_PCI_MODERN,
-	VIRTIO_BUS_USER,
-};
-
 struct virtio_hw {
-	enum virtio_bus_type bus_type;
 	struct virtnet_ctl *cvq;
 	uint64_t    req_guest_features;
 	uint64_t    guest_features;
diff --git a/drivers/net/virtio/virtio_pci_ethdev.c b/drivers/net/virtio/virtio_pci_ethdev.c
index 076a5dbced..8cc6561914 100644
--- a/drivers/net/virtio/virtio_pci_ethdev.c
+++ b/drivers/net/virtio/virtio_pci_ethdev.c
@@ -84,6 +84,11 @@ eth_virtio_pci_init(struct rte_eth_dev *eth_dev)
 			return -1;
 		}
 	} else {
+		if (dev->modern)
+			VTPCI_OPS(hw) = &modern_ops;
+		else
+			VTPCI_OPS(hw) = &legacy_ops;
+
 		ret = virtio_remap_pci(RTE_ETH_DEV_TO_PCI(eth_dev), dev);
 		if (ret < 0) {
 			PMD_INIT_LOG(ERR, "Failed to remap PCI device\n");
@@ -105,7 +110,7 @@ eth_virtio_pci_init(struct rte_eth_dev *eth_dev)
 
 err_unmap:
 	rte_pci_unmap_device(RTE_ETH_DEV_TO_PCI(eth_dev));
-	if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY)
+	if (!dev->modern)
 		rte_pci_ioport_unmap(VTPCI_IO(hw));
 
 	return ret;
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index bf958de571..61880a8e02 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -641,7 +641,6 @@ virtio_user_eth_dev_alloc(struct rte_vdev_device *vdev)
 	 * Here just pretend that we support msix.
 	 */
 	hw->use_msix = 1;
-	hw->bus_type = VIRTIO_BUS_USER;
 	hw->use_vec_rx = 0;
 	hw->use_vec_tx = 0;
 	hw->use_inorder_rx = 0;
@@ -691,6 +690,10 @@ virtio_user_pmd_probe(struct rte_vdev_device *vdev)
 			return -1;
 		}
 
+		dev = eth_dev->data->dev_private;
+		hw = &dev->hw;
+		VTPCI_OPS(hw) = &virtio_user_ops;
+
 		if (eth_virtio_dev_init(eth_dev) < 0) {
 			PMD_INIT_LOG(ERR, "eth_virtio_dev_init fails");
 			rte_eth_dev_release_port(eth_dev);
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 15/44] net/virtio: move PCI-specific fields to PCI device
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (13 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 14/44] net/virtio: remove bus type enum Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 16/44] net/virtio: pack virtio HW struct Maxime Coquelin
                   ` (28 subsequent siblings)
  43 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch moves the fields from virtio_hw structure that
are PCI-specific to virtio_pci_dev_struct.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
Reviewed-by: David Marchand <david.marchand@redhat.com>
---
 drivers/net/virtio/virtio_pci.c | 139 ++++++++++++++++++--------------
 drivers/net/virtio/virtio_pci.h |  10 +--
 2 files changed, 85 insertions(+), 64 deletions(-)

diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index 90631d1a2d..21dd0f0e5d 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -344,18 +344,19 @@ static void
 modern_read_dev_config(struct virtio_hw *hw, size_t offset,
 		       void *dst, int length)
 {
+	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
 	int i;
 	uint8_t *p;
 	uint8_t old_gen, new_gen;
 
 	do {
-		old_gen = rte_read8(&hw->common_cfg->config_generation);
+		old_gen = rte_read8(&dev->common_cfg->config_generation);
 
 		p = dst;
 		for (i = 0;  i < length; i++)
-			*p++ = rte_read8((uint8_t *)hw->dev_cfg + offset + i);
+			*p++ = rte_read8((uint8_t *)dev->dev_cfg + offset + i);
 
-		new_gen = rte_read8(&hw->common_cfg->config_generation);
+		new_gen = rte_read8(&dev->common_cfg->config_generation);
 	} while (old_gen != new_gen);
 }
 
@@ -363,23 +364,25 @@ static void
 modern_write_dev_config(struct virtio_hw *hw, size_t offset,
 			const void *src, int length)
 {
+	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
 	int i;
 	const uint8_t *p = src;
 
 	for (i = 0;  i < length; i++)
-		rte_write8((*p++), (((uint8_t *)hw->dev_cfg) + offset + i));
+		rte_write8((*p++), (((uint8_t *)dev->dev_cfg) + offset + i));
 }
 
 static uint64_t
 modern_get_features(struct virtio_hw *hw)
 {
+	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
 	uint32_t features_lo, features_hi;
 
-	rte_write32(0, &hw->common_cfg->device_feature_select);
-	features_lo = rte_read32(&hw->common_cfg->device_feature);
+	rte_write32(0, &dev->common_cfg->device_feature_select);
+	features_lo = rte_read32(&dev->common_cfg->device_feature);
 
-	rte_write32(1, &hw->common_cfg->device_feature_select);
-	features_hi = rte_read32(&hw->common_cfg->device_feature);
+	rte_write32(1, &dev->common_cfg->device_feature_select);
+	features_hi = rte_read32(&dev->common_cfg->device_feature);
 
 	return ((uint64_t)features_hi << 32) | features_lo;
 }
@@ -387,13 +390,15 @@ modern_get_features(struct virtio_hw *hw)
 static void
 modern_set_features(struct virtio_hw *hw, uint64_t features)
 {
-	rte_write32(0, &hw->common_cfg->guest_feature_select);
+	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
+
+	rte_write32(0, &dev->common_cfg->guest_feature_select);
 	rte_write32(features & ((1ULL << 32) - 1),
-		    &hw->common_cfg->guest_feature);
+		    &dev->common_cfg->guest_feature);
 
-	rte_write32(1, &hw->common_cfg->guest_feature_select);
+	rte_write32(1, &dev->common_cfg->guest_feature_select);
 	rte_write32(features >> 32,
-		    &hw->common_cfg->guest_feature);
+		    &dev->common_cfg->guest_feature);
 }
 
 static int
@@ -410,46 +415,59 @@ modern_features_ok(struct virtio_hw *hw)
 static uint8_t
 modern_get_status(struct virtio_hw *hw)
 {
-	return rte_read8(&hw->common_cfg->device_status);
+	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
+
+	return rte_read8(&dev->common_cfg->device_status);
 }
 
 static void
 modern_set_status(struct virtio_hw *hw, uint8_t status)
 {
-	rte_write8(status, &hw->common_cfg->device_status);
+	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
+
+	rte_write8(status, &dev->common_cfg->device_status);
 }
 
 static uint8_t
 modern_get_isr(struct virtio_hw *hw)
 {
-	return rte_read8(hw->isr);
+	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
+
+	return rte_read8(dev->isr);
 }
 
 static uint16_t
 modern_set_config_irq(struct virtio_hw *hw, uint16_t vec)
 {
-	rte_write16(vec, &hw->common_cfg->msix_config);
-	return rte_read16(&hw->common_cfg->msix_config);
+	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
+
+	rte_write16(vec, &dev->common_cfg->msix_config);
+	return rte_read16(&dev->common_cfg->msix_config);
 }
 
 static uint16_t
 modern_set_queue_irq(struct virtio_hw *hw, struct virtqueue *vq, uint16_t vec)
 {
-	rte_write16(vq->vq_queue_index, &hw->common_cfg->queue_select);
-	rte_write16(vec, &hw->common_cfg->queue_msix_vector);
-	return rte_read16(&hw->common_cfg->queue_msix_vector);
+	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
+
+	rte_write16(vq->vq_queue_index, &dev->common_cfg->queue_select);
+	rte_write16(vec, &dev->common_cfg->queue_msix_vector);
+	return rte_read16(&dev->common_cfg->queue_msix_vector);
 }
 
 static uint16_t
 modern_get_queue_num(struct virtio_hw *hw, uint16_t queue_id)
 {
-	rte_write16(queue_id, &hw->common_cfg->queue_select);
-	return rte_read16(&hw->common_cfg->queue_size);
+	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
+
+	rte_write16(queue_id, &dev->common_cfg->queue_select);
+	return rte_read16(&dev->common_cfg->queue_size);
 }
 
 static int
 modern_setup_queue(struct virtio_hw *hw, struct virtqueue *vq)
 {
+	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
 	uint64_t desc_addr, avail_addr, used_addr;
 	uint16_t notify_off;
 
@@ -462,20 +480,20 @@ modern_setup_queue(struct virtio_hw *hw, struct virtqueue *vq)
 							 ring[vq->vq_nentries]),
 				   VIRTIO_PCI_VRING_ALIGN);
 
-	rte_write16(vq->vq_queue_index, &hw->common_cfg->queue_select);
+	rte_write16(vq->vq_queue_index, &dev->common_cfg->queue_select);
 
-	io_write64_twopart(desc_addr, &hw->common_cfg->queue_desc_lo,
-				      &hw->common_cfg->queue_desc_hi);
-	io_write64_twopart(avail_addr, &hw->common_cfg->queue_avail_lo,
-				       &hw->common_cfg->queue_avail_hi);
-	io_write64_twopart(used_addr, &hw->common_cfg->queue_used_lo,
-				      &hw->common_cfg->queue_used_hi);
+	io_write64_twopart(desc_addr, &dev->common_cfg->queue_desc_lo,
+				      &dev->common_cfg->queue_desc_hi);
+	io_write64_twopart(avail_addr, &dev->common_cfg->queue_avail_lo,
+				       &dev->common_cfg->queue_avail_hi);
+	io_write64_twopart(used_addr, &dev->common_cfg->queue_used_lo,
+				      &dev->common_cfg->queue_used_hi);
 
-	notify_off = rte_read16(&hw->common_cfg->queue_notify_off);
-	vq->notify_addr = (void *)((uint8_t *)hw->notify_base +
-				notify_off * hw->notify_off_multiplier);
+	notify_off = rte_read16(&dev->common_cfg->queue_notify_off);
+	vq->notify_addr = (void *)((uint8_t *)dev->notify_base +
+				notify_off * dev->notify_off_multiplier);
 
-	rte_write16(1, &hw->common_cfg->queue_enable);
+	rte_write16(1, &dev->common_cfg->queue_enable);
 
 	PMD_INIT_LOG(DEBUG, "queue %u addresses:", vq->vq_queue_index);
 	PMD_INIT_LOG(DEBUG, "\t desc_addr: %" PRIx64, desc_addr);
@@ -490,16 +508,18 @@ modern_setup_queue(struct virtio_hw *hw, struct virtqueue *vq)
 static void
 modern_del_queue(struct virtio_hw *hw, struct virtqueue *vq)
 {
-	rte_write16(vq->vq_queue_index, &hw->common_cfg->queue_select);
+	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
+
+	rte_write16(vq->vq_queue_index, &dev->common_cfg->queue_select);
 
-	io_write64_twopart(0, &hw->common_cfg->queue_desc_lo,
-				  &hw->common_cfg->queue_desc_hi);
-	io_write64_twopart(0, &hw->common_cfg->queue_avail_lo,
-				  &hw->common_cfg->queue_avail_hi);
-	io_write64_twopart(0, &hw->common_cfg->queue_used_lo,
-				  &hw->common_cfg->queue_used_hi);
+	io_write64_twopart(0, &dev->common_cfg->queue_desc_lo,
+				  &dev->common_cfg->queue_desc_hi);
+	io_write64_twopart(0, &dev->common_cfg->queue_avail_lo,
+				  &dev->common_cfg->queue_avail_hi);
+	io_write64_twopart(0, &dev->common_cfg->queue_used_lo,
+				  &dev->common_cfg->queue_used_hi);
 
-	rte_write16(0, &hw->common_cfg->queue_enable);
+	rte_write16(0, &dev->common_cfg->queue_enable);
 }
 
 static void
@@ -671,18 +691,19 @@ get_cfg_addr(struct rte_pci_device *dev, struct virtio_pci_cap *cap)
 }
 
 static int
-virtio_read_caps(struct rte_pci_device *dev, struct virtio_hw *hw)
+virtio_read_caps(struct rte_pci_device *pci_dev, struct virtio_hw *hw)
 {
+	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
 	uint8_t pos;
 	struct virtio_pci_cap cap;
 	int ret;
 
-	if (rte_pci_map_device(dev)) {
+	if (rte_pci_map_device(pci_dev)) {
 		PMD_INIT_LOG(DEBUG, "failed to map pci device!");
 		return -1;
 	}
 
-	ret = rte_pci_read_config(dev, &pos, 1, PCI_CAPABILITY_LIST);
+	ret = rte_pci_read_config(pci_dev, &pos, 1, PCI_CAPABILITY_LIST);
 	if (ret != 1) {
 		PMD_INIT_LOG(DEBUG,
 			     "failed to read pci capability list, ret %d", ret);
@@ -690,7 +711,7 @@ virtio_read_caps(struct rte_pci_device *dev, struct virtio_hw *hw)
 	}
 
 	while (pos) {
-		ret = rte_pci_read_config(dev, &cap, 2, pos);
+		ret = rte_pci_read_config(pci_dev, &cap, 2, pos);
 		if (ret != 2) {
 			PMD_INIT_LOG(DEBUG,
 				     "failed to read pci cap at pos: %x ret %d",
@@ -706,7 +727,7 @@ virtio_read_caps(struct rte_pci_device *dev, struct virtio_hw *hw)
 			 */
 			uint16_t flags;
 
-			ret = rte_pci_read_config(dev, &flags, sizeof(flags),
+			ret = rte_pci_read_config(pci_dev, &flags, sizeof(flags),
 					pos + 2);
 			if (ret != sizeof(flags)) {
 				PMD_INIT_LOG(DEBUG,
@@ -728,7 +749,7 @@ virtio_read_caps(struct rte_pci_device *dev, struct virtio_hw *hw)
 			goto next;
 		}
 
-		ret = rte_pci_read_config(dev, &cap, sizeof(cap), pos);
+		ret = rte_pci_read_config(pci_dev, &cap, sizeof(cap), pos);
 		if (ret != sizeof(cap)) {
 			PMD_INIT_LOG(DEBUG,
 				     "failed to read pci cap at pos: %x ret %d",
@@ -742,24 +763,24 @@ virtio_read_caps(struct rte_pci_device *dev, struct virtio_hw *hw)
 
 		switch (cap.cfg_type) {
 		case VIRTIO_PCI_CAP_COMMON_CFG:
-			hw->common_cfg = get_cfg_addr(dev, &cap);
+			dev->common_cfg = get_cfg_addr(pci_dev, &cap);
 			break;
 		case VIRTIO_PCI_CAP_NOTIFY_CFG:
-			ret = rte_pci_read_config(dev,
-					&hw->notify_off_multiplier,
+			ret = rte_pci_read_config(pci_dev,
+					&dev->notify_off_multiplier,
 					4, pos + sizeof(cap));
 			if (ret != 4)
 				PMD_INIT_LOG(DEBUG,
 					"failed to read notify_off_multiplier, ret %d",
 					ret);
 			else
-				hw->notify_base = get_cfg_addr(dev, &cap);
+				dev->notify_base = get_cfg_addr(pci_dev, &cap);
 			break;
 		case VIRTIO_PCI_CAP_DEVICE_CFG:
-			hw->dev_cfg = get_cfg_addr(dev, &cap);
+			dev->dev_cfg = get_cfg_addr(pci_dev, &cap);
 			break;
 		case VIRTIO_PCI_CAP_ISR_CFG:
-			hw->isr = get_cfg_addr(dev, &cap);
+			dev->isr = get_cfg_addr(pci_dev, &cap);
 			break;
 		}
 
@@ -767,19 +788,19 @@ virtio_read_caps(struct rte_pci_device *dev, struct virtio_hw *hw)
 		pos = cap.cap_next;
 	}
 
-	if (hw->common_cfg == NULL || hw->notify_base == NULL ||
-	    hw->dev_cfg == NULL    || hw->isr == NULL) {
+	if (dev->common_cfg == NULL || dev->notify_base == NULL ||
+	    dev->dev_cfg == NULL    || dev->isr == NULL) {
 		PMD_INIT_LOG(INFO, "no modern virtio pci device found.");
 		return -1;
 	}
 
 	PMD_INIT_LOG(INFO, "found modern virtio pci device.");
 
-	PMD_INIT_LOG(DEBUG, "common cfg mapped at: %p", hw->common_cfg);
-	PMD_INIT_LOG(DEBUG, "device cfg mapped at: %p", hw->dev_cfg);
-	PMD_INIT_LOG(DEBUG, "isr cfg mapped at: %p", hw->isr);
+	PMD_INIT_LOG(DEBUG, "common cfg mapped at: %p", dev->common_cfg);
+	PMD_INIT_LOG(DEBUG, "device cfg mapped at: %p", dev->dev_cfg);
+	PMD_INIT_LOG(DEBUG, "isr cfg mapped at: %p", dev->isr);
 	PMD_INIT_LOG(DEBUG, "notify base: %p, notify off multiplier: %u",
-		hw->notify_base, hw->notify_off_multiplier);
+		dev->notify_base, dev->notify_off_multiplier);
 
 	return 0;
 }
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index b6c44a7f7c..8a73d7e3f4 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -265,13 +265,8 @@ struct virtio_hw {
 	bool        has_rx_offload;
 	uint16_t    port_id;
 	uint8_t     mac_addr[RTE_ETHER_ADDR_LEN];
-	uint32_t    notify_off_multiplier;
 	uint32_t    speed;  /* link speed in MB */
 	uint8_t     duplex;
-	uint8_t     *isr;
-	uint16_t    *notify_base;
-	struct virtio_pci_common_cfg *common_cfg;
-	struct virtio_net_config *dev_cfg;
 	/*
 	 * App management thread and virtio interrupt handler thread
 	 * both can change device state, this lock is meant to avoid
@@ -287,6 +282,11 @@ struct virtio_hw {
 struct virtio_pci_dev {
 	struct virtio_hw hw;
 	struct rte_pci_device *pci_dev;
+	struct virtio_pci_common_cfg *common_cfg;
+	struct virtio_net_config *dev_cfg;
+	uint8_t *isr;
+	uint16_t *notify_base;
+	uint32_t notify_off_multiplier;
 	bool modern;
 };
 
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 16/44] net/virtio: pack virtio HW struct
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (14 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 15/44] net/virtio: move PCI-specific fields to PCI device Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 17/44] net/virtio: move legacy IO to Virtio PCI Maxime Coquelin
                   ` (27 subsequent siblings)
  43 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch improves the virtio_hw struct packing,
going from 88 down to 80 bytes with a 6 bytes hole in
the end of the first cacheline. Fields only used in the
slow path are placed in the end, so that hot path only
uses the first cacheline.

The patch also changes booleans fields to uint8_t type, and
fix inconsistencies in their assignments.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 12 ++++----
 drivers/net/virtio/virtio_pci.h    | 45 +++++++++++++++---------------
 drivers/net/virtio/virtqueue.h     |  2 +-
 3 files changed, 29 insertions(+), 30 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 1df2b852ce..cb835f11ad 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -699,7 +699,7 @@ virtio_dev_close(struct rte_eth_dev *dev)
 
 	if (!hw->opened)
 		return 0;
-	hw->opened = false;
+	hw->opened = 0;
 
 	/* reset the NIC */
 	if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
@@ -1864,7 +1864,7 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 		}
 	}
 
-	hw->opened = true;
+	hw->opened = 1;
 
 	return 0;
 
@@ -1973,7 +1973,7 @@ virtio_dev_devargs_parse(struct rte_devargs *devargs, uint32_t *speed, int *vect
 	return ret;
 }
 
-static bool
+static uint8_t
 rx_offload_enabled(struct virtio_hw *hw)
 {
 	return vtpci_with_feature(hw, VIRTIO_NET_F_GUEST_CSUM) ||
@@ -1981,7 +1981,7 @@ rx_offload_enabled(struct virtio_hw *hw)
 		vtpci_with_feature(hw, VIRTIO_NET_F_GUEST_TSO6);
 }
 
-static bool
+static uint8_t
 tx_offload_enabled(struct virtio_hw *hw)
 {
 	return vtpci_with_feature(hw, VIRTIO_NET_F_CSUM) ||
@@ -2267,7 +2267,7 @@ virtio_dev_start(struct rte_eth_dev *dev)
 	}
 
 	set_rxtx_funcs(dev);
-	hw->started = true;
+	hw->started = 1;
 
 	/* Initialize Link state */
 	virtio_dev_link_update(dev, 0);
@@ -2336,7 +2336,7 @@ virtio_dev_stop(struct rte_eth_dev *dev)
 	rte_spinlock_lock(&hw->state_lock);
 	if (!hw->started)
 		goto out_unlock;
-	hw->started = false;
+	hw->started = 0;
 
 	if (intr_conf->lsc || intr_conf->rxq) {
 		virtio_intr_disable(dev);
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 8a73d7e3f4..35ae41e600 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -247,26 +247,25 @@ struct virtio_pci_ops {
 struct virtio_net_config;
 
 struct virtio_hw {
-	struct virtnet_ctl *cvq;
-	uint64_t    req_guest_features;
-	uint64_t    guest_features;
-	uint32_t    max_queue_pairs;
-	bool        started;
-	uint16_t	max_mtu;
-	uint16_t    vtnet_hdr_size;
-	uint8_t	    vlan_strip;
-	uint8_t	    use_msix;
-	uint8_t     use_vec_rx;
-	uint8_t     use_vec_tx;
-	uint8_t     use_inorder_rx;
-	uint8_t     use_inorder_tx;
-	uint8_t     weak_barriers;
-	bool        has_tx_offload;
-	bool        has_rx_offload;
-	uint16_t    port_id;
-	uint8_t     mac_addr[RTE_ETHER_ADDR_LEN];
-	uint32_t    speed;  /* link speed in MB */
-	uint8_t     duplex;
+	struct virtqueue **vqs;
+	uint64_t guest_features;
+	uint16_t vtnet_hdr_size;
+	uint8_t started;
+	uint8_t weak_barriers;
+	uint8_t vlan_strip;
+	uint8_t has_tx_offload;
+	uint8_t has_rx_offload;
+	uint8_t use_vec_rx;
+	uint8_t use_vec_tx;
+	uint8_t use_inorder_rx;
+	uint8_t use_inorder_tx;
+	uint8_t opened;
+	uint16_t port_id;
+	uint8_t mac_addr[RTE_ETHER_ADDR_LEN];
+	uint32_t speed;  /* link speed in MB */
+	uint8_t duplex;
+	uint8_t use_msix;
+	uint16_t max_mtu;
 	/*
 	 * App management thread and virtio interrupt handler thread
 	 * both can change device state, this lock is meant to avoid
@@ -274,9 +273,9 @@ struct virtio_hw {
 	 */
 	rte_spinlock_t state_lock;
 	struct rte_mbuf **inject_pkts;
-	bool        opened;
-
-	struct virtqueue **vqs;
+	uint16_t max_queue_pairs;
+	uint64_t req_guest_features;
+	struct virtnet_ctl *cvq;
 };
 
 struct virtio_pci_dev {
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index 7611317581..3a9ce29069 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -615,7 +615,7 @@ virtqueue_notify(struct virtqueue *vq)
 static inline void
 virtqueue_xmit_offload(struct virtio_net_hdr *hdr,
 			struct rte_mbuf *cookie,
-			bool offload)
+			uint8_t offload)
 {
 	if (offload) {
 		if (cookie->ol_flags & PKT_TX_TCP_SEG)
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 17/44] net/virtio: move legacy IO to Virtio PCI
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (15 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 16/44] net/virtio: pack virtio HW struct Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 18/44] net/virtio: introduce generic virtio header Maxime Coquelin
                   ` (26 subsequent siblings)
  43 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch moves Virtio PCI legacy IO handling to
virtio_pci.c. Two functions are created so that
virtio_pci_ethdev does not have to care about it.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
Reviewed-by: David Marchand <david.marchand@redhat.com>
---
 drivers/net/virtio/virtio_pci.c        | 28 ++++++++++++++++++++++++--
 drivers/net/virtio/virtio_pci.h        |  9 +++------
 drivers/net/virtio/virtio_pci_ethdev.c |  6 ++----
 3 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index 21dd0f0e5d..50516976ce 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -31,6 +31,15 @@
 #define VIRTIO_PCI_CONFIG(hw) \
 		(((hw)->use_msix == VIRTIO_MSIX_ENABLED) ? 24 : 20)
 
+
+struct virtio_pci_internal {
+	struct rte_pci_ioport io;
+};
+
+#define VTPCI_IO(hw) (&virtio_pci_internal[(hw)->port_id].io)
+
+struct virtio_pci_internal virtio_pci_internal[RTE_MAX_ETHPORTS];
+
 static inline int
 check_vq_phys_addr_ok(struct virtqueue *vq)
 {
@@ -300,7 +309,9 @@ legacy_notify_queue(struct virtio_hw *hw, struct virtqueue *vq)
 static void
 legacy_intr_event(struct virtio_hw *hw)
 {
-	hw->use_msix = vtpci_msix_detect(VTPCI_DEV(hw));
+	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
+
+	hw->use_msix = vtpci_msix_detect(dev->pci_dev);
 }
 
 static int
@@ -558,7 +569,9 @@ modern_notify_queue(struct virtio_hw *hw, struct virtqueue *vq)
 static void
 modern_intr_event(struct virtio_hw *hw)
 {
-	hw->use_msix = vtpci_msix_detect(VTPCI_DEV(hw));
+	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
+
+	hw->use_msix = vtpci_msix_detect(dev->pci_dev);
 }
 
 static int
@@ -857,3 +870,14 @@ vtpci_init(struct rte_pci_device *pci_dev, struct virtio_pci_dev *dev)
 	return 0;
 }
 
+void vtpci_legacy_ioport_unmap(struct virtio_hw *hw)
+{
+	rte_pci_ioport_unmap(VTPCI_IO(hw));
+}
+
+int vtpci_legacy_ioport_map(struct virtio_hw *hw)
+{
+	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
+
+	return rte_pci_ioport_map(dev->pci_dev, 0, VTPCI_IO(hw));
+}
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 35ae41e600..f208472273 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -298,18 +298,12 @@ struct virtio_pci_dev {
  */
 struct virtio_hw_internal {
 	const struct virtio_pci_ops *vtpci_ops;
-	struct rte_pci_ioport io;
-	struct rte_pci_device *dev;
 };
 
 #define VTPCI_OPS(hw)	(virtio_hw_internal[(hw)->port_id].vtpci_ops)
-#define VTPCI_IO(hw)	(&virtio_hw_internal[(hw)->port_id].io)
-#define VTPCI_DEV(hw)	(virtio_hw_internal[(hw)->port_id].dev)
-
 
 extern struct virtio_hw_internal virtio_hw_internal[RTE_MAX_ETHPORTS];
 
-
 /*
  * This structure is just a reference to read
  * net device specific config space; it just a chodu structure
@@ -382,6 +376,9 @@ void vtpci_read_dev_config(struct virtio_hw *, size_t, void *, int);
 
 uint8_t vtpci_isr(struct virtio_hw *);
 
+void vtpci_legacy_ioport_unmap(struct virtio_hw *hw);
+int vtpci_legacy_ioport_map(struct virtio_hw *hw);
+
 extern const struct virtio_pci_ops legacy_ops;
 extern const struct virtio_pci_ops modern_ops;
 extern const struct virtio_pci_ops virtio_user_ops;
diff --git a/drivers/net/virtio/virtio_pci_ethdev.c b/drivers/net/virtio/virtio_pci_ethdev.c
index 8cc6561914..9fe59feb51 100644
--- a/drivers/net/virtio/virtio_pci_ethdev.c
+++ b/drivers/net/virtio/virtio_pci_ethdev.c
@@ -60,7 +60,7 @@ virtio_remap_pci(struct rte_pci_device *pci_dev, struct virtio_pci_dev *dev)
 			return -1;
 		}
 	} else {
-		if (rte_pci_ioport_map(pci_dev, 0, VTPCI_IO(hw)) < 0)
+		if (vtpci_legacy_ioport_map(hw) < 0)
 			return -1;
 	}
 
@@ -75,8 +75,6 @@ eth_virtio_pci_init(struct rte_eth_dev *eth_dev)
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
 	int ret;
 
-	VTPCI_DEV(hw) = pci_dev;
-
 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
 		ret = vtpci_init(RTE_ETH_DEV_TO_PCI(eth_dev), dev);
 		if (ret) {
@@ -111,7 +109,7 @@ eth_virtio_pci_init(struct rte_eth_dev *eth_dev)
 err_unmap:
 	rte_pci_unmap_device(RTE_ETH_DEV_TO_PCI(eth_dev));
 	if (!dev->modern)
-		rte_pci_ioport_unmap(VTPCI_IO(hw));
+		vtpci_legacy_ioport_unmap(hw);
 
 	return ret;
 }
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 18/44] net/virtio: introduce generic virtio header
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (16 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 17/44] net/virtio: move legacy IO to Virtio PCI Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 19/44] net/virtio: move features definition to generic header Maxime Coquelin
                   ` (25 subsequent siblings)
  43 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch moves virtio_hw and virtio callbacks into
a generic virtio header, now that they have been
curated from PCI references.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
---
 drivers/net/virtio/virtio.h             | 74 ++++++++++++++++++++++
 drivers/net/virtio/virtio_ethdev.c      | 32 +++++-----
 drivers/net/virtio/virtio_pci.c         | 26 ++++----
 drivers/net/virtio/virtio_pci.h         | 84 ++-----------------------
 drivers/net/virtio/virtio_pci_ethdev.c  |  5 +-
 drivers/net/virtio/virtio_user_ethdev.c |  8 +--
 drivers/net/virtio/virtqueue.h          |  2 +-
 7 files changed, 115 insertions(+), 116 deletions(-)
 create mode 100644 drivers/net/virtio/virtio.h

diff --git a/drivers/net/virtio/virtio.h b/drivers/net/virtio/virtio.h
new file mode 100644
index 0000000000..256060287d
--- /dev/null
+++ b/drivers/net/virtio/virtio.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
+ * Copyright(c) 2021 Red Hat, Inc.
+ */
+
+#ifndef _VIRTIO_H_
+#define _VIRTIO_H_
+
+#include <rte_ether.h>
+
+struct virtio_hw {
+	struct virtqueue **vqs;
+	uint64_t guest_features;
+	uint16_t vtnet_hdr_size;
+	uint8_t started;
+	uint8_t weak_barriers;
+	uint8_t vlan_strip;
+	uint8_t has_tx_offload;
+	uint8_t has_rx_offload;
+	uint8_t use_vec_rx;
+	uint8_t use_vec_tx;
+	uint8_t use_inorder_rx;
+	uint8_t use_inorder_tx;
+	uint8_t opened;
+	uint16_t port_id;
+	uint8_t mac_addr[RTE_ETHER_ADDR_LEN];
+	uint32_t speed;  /* link speed in MB */
+	uint8_t duplex;
+	uint8_t use_msix;
+	uint16_t max_mtu;
+	/*
+	 * App management thread and virtio interrupt handler thread
+	 * both can change device state, this lock is meant to avoid
+	 * such a contention.
+	 */
+	rte_spinlock_t state_lock;
+	struct rte_mbuf **inject_pkts;
+	uint16_t max_queue_pairs;
+	uint64_t req_guest_features;
+	struct virtnet_ctl *cvq;
+};
+
+struct virtio_ops {
+	void (*read_dev_cfg)(struct virtio_hw *hw, size_t offset, void *dst, int len);
+	void (*write_dev_cfg)(struct virtio_hw *hw, size_t offset, const void *src, int len);
+	uint8_t (*get_status)(struct virtio_hw *hw);
+	void (*set_status)(struct virtio_hw *hw, uint8_t status);
+	uint64_t (*get_features)(struct virtio_hw *hw);
+	void (*set_features)(struct virtio_hw *hw, uint64_t features);
+	int (*features_ok)(struct virtio_hw *hw);
+	uint8_t (*get_isr)(struct virtio_hw *hw);
+	uint16_t (*set_config_irq)(struct virtio_hw *hw, uint16_t vec);
+	uint16_t (*set_queue_irq)(struct virtio_hw *hw, struct virtqueue *vq, uint16_t vec);
+	uint16_t (*get_queue_num)(struct virtio_hw *hw, uint16_t queue_id);
+	int (*setup_queue)(struct virtio_hw *hw, struct virtqueue *vq);
+	void (*del_queue)(struct virtio_hw *hw, struct virtqueue *vq);
+	void (*notify_queue)(struct virtio_hw *hw, struct virtqueue *vq);
+	void (*intr_event)(struct virtio_hw *hw);
+	int (*dev_close)(struct virtio_hw *hw);
+};
+
+/*
+ * This structure stores per-process data. Only virtio_ops for now.
+ */
+struct virtio_hw_internal {
+	const struct virtio_ops *virtio_ops;
+};
+
+#define VIRTIO_OPS(hw)	(virtio_hw_internal[(hw)->port_id].virtio_ops)
+
+extern struct virtio_hw_internal virtio_hw_internal[RTE_MAX_ETHPORTS];
+
+
+#endif /* _VIRTIO_H_ */
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index cb835f11ad..6287d0c29b 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -446,7 +446,7 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
 	 * Read the virtqueue size from the Queue Size field
 	 * Always power of 2 and if 0 virtqueue does not exist
 	 */
-	vq_size = VTPCI_OPS(hw)->get_queue_num(hw, vtpci_queue_idx);
+	vq_size = VIRTIO_OPS(hw)->get_queue_num(hw, vtpci_queue_idx);
 	PMD_INIT_LOG(DEBUG, "vq_size: %u", vq_size);
 	if (vq_size == 0) {
 		PMD_INIT_LOG(ERR, "virtqueue does not exist");
@@ -608,7 +608,7 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
 		}
 	}
 
-	if (VTPCI_OPS(hw)->setup_queue(hw, vq) < 0) {
+	if (VIRTIO_OPS(hw)->setup_queue(hw, vq) < 0) {
 		PMD_INIT_LOG(ERR, "setup_queue failed");
 		return -EINVAL;
 	}
@@ -703,7 +703,7 @@ virtio_dev_close(struct rte_eth_dev *dev)
 
 	/* reset the NIC */
 	if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
-		VTPCI_OPS(hw)->set_config_irq(hw, VIRTIO_MSI_NO_VECTOR);
+		VIRTIO_OPS(hw)->set_config_irq(hw, VIRTIO_MSI_NO_VECTOR);
 	if (intr_conf->rxq)
 		virtio_queues_unbind_intr(dev);
 
@@ -718,7 +718,7 @@ virtio_dev_close(struct rte_eth_dev *dev)
 	virtio_dev_free_mbufs(dev);
 	virtio_free_queues(hw);
 
-	return VTPCI_OPS(hw)->dev_close(hw);
+	return VIRTIO_OPS(hw)->dev_close(hw);
 }
 
 static int
@@ -1261,8 +1261,8 @@ virtio_intr_unmask(struct rte_eth_dev *dev)
 	if (rte_intr_ack(dev->intr_handle) < 0)
 		return -1;
 
-	if (VTPCI_OPS(hw)->intr_event)
-		VTPCI_OPS(hw)->intr_event(hw);
+	if (VIRTIO_OPS(hw)->intr_event)
+		VIRTIO_OPS(hw)->intr_event(hw);
 
 	return 0;
 }
@@ -1275,8 +1275,8 @@ virtio_intr_enable(struct rte_eth_dev *dev)
 	if (rte_intr_enable(dev->intr_handle) < 0)
 		return -1;
 
-	if (VTPCI_OPS(hw)->intr_event)
-		VTPCI_OPS(hw)->intr_event(hw);
+	if (VIRTIO_OPS(hw)->intr_event)
+		VIRTIO_OPS(hw)->intr_event(hw);
 
 	return 0;
 }
@@ -1289,8 +1289,8 @@ virtio_intr_disable(struct rte_eth_dev *dev)
 	if (rte_intr_disable(dev->intr_handle) < 0)
 		return -1;
 
-	if (VTPCI_OPS(hw)->intr_event)
-		VTPCI_OPS(hw)->intr_event(hw);
+	if (VIRTIO_OPS(hw)->intr_event)
+		VIRTIO_OPS(hw)->intr_event(hw);
 
 	return 0;
 }
@@ -1305,7 +1305,7 @@ virtio_negotiate_features(struct virtio_hw *hw, uint64_t req_features)
 		req_features);
 
 	/* Read device(host) feature bits */
-	host_features = VTPCI_OPS(hw)->get_features(hw);
+	host_features = VIRTIO_OPS(hw)->get_features(hw);
 	PMD_INIT_LOG(DEBUG, "host_features before negotiate = %" PRIx64,
 		host_features);
 
@@ -1330,7 +1330,7 @@ virtio_negotiate_features(struct virtio_hw *hw, uint64_t req_features)
 	PMD_INIT_LOG(DEBUG, "features after negotiate = %" PRIx64,
 		hw->guest_features);
 
-	if (VTPCI_OPS(hw)->features_ok(hw) < 0)
+	if (VIRTIO_OPS(hw)->features_ok(hw) < 0)
 		return -1;
 
 	if (vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) {
@@ -1564,7 +1564,7 @@ virtio_queues_bind_intr(struct rte_eth_dev *dev)
 	PMD_INIT_LOG(INFO, "queue/interrupt binding");
 	for (i = 0; i < dev->data->nb_rx_queues; ++i) {
 		dev->intr_handle->intr_vec[i] = i + 1;
-		if (VTPCI_OPS(hw)->set_queue_irq(hw, hw->vqs[i * 2], i + 1) ==
+		if (VIRTIO_OPS(hw)->set_queue_irq(hw, hw->vqs[i * 2], i + 1) ==
 						 VIRTIO_MSI_NO_VECTOR) {
 			PMD_DRV_LOG(ERR, "failed to set queue vector");
 			return -EBUSY;
@@ -1582,7 +1582,7 @@ virtio_queues_unbind_intr(struct rte_eth_dev *dev)
 
 	PMD_INIT_LOG(INFO, "queue/interrupt unbinding");
 	for (i = 0; i < dev->data->nb_rx_queues; ++i)
-		VTPCI_OPS(hw)->set_queue_irq(hw,
+		VIRTIO_OPS(hw)->set_queue_irq(hw,
 					     hw->vqs[i * VTNET_CQ],
 					     VIRTIO_MSI_NO_VECTOR);
 }
@@ -2092,7 +2092,7 @@ virtio_dev_configure(struct rte_eth_dev *dev)
 
 	if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
 		/* Enable vector (0) for Link State Intrerrupt */
-		if (VTPCI_OPS(hw)->set_config_irq(hw, 0) ==
+		if (VIRTIO_OPS(hw)->set_config_irq(hw, 0) ==
 				VIRTIO_MSI_NO_VECTOR) {
 			PMD_DRV_LOG(ERR, "failed to set config vector");
 			return -EBUSY;
@@ -2433,7 +2433,7 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->max_rx_pktlen = VIRTIO_MAX_RX_PKTLEN;
 	dev_info->max_mac_addrs = VIRTIO_MAX_MAC_ADDRS;
 
-	host_features = VTPCI_OPS(hw)->get_features(hw);
+	host_features = VIRTIO_OPS(hw)->get_features(hw);
 	dev_info->rx_offload_capa = DEV_RX_OFFLOAD_VLAN_STRIP;
 	dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_JUMBO_FRAME;
 	if (host_features & (1ULL << VIRTIO_NET_F_GUEST_CSUM)) {
diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index 50516976ce..acd91042d9 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -325,7 +325,7 @@ legacy_dev_close(struct virtio_hw *hw)
 	return 0;
 }
 
-const struct virtio_pci_ops legacy_ops = {
+const struct virtio_ops legacy_ops = {
 	.read_dev_cfg	= legacy_read_dev_config,
 	.write_dev_cfg	= legacy_write_dev_config,
 	.get_status	= legacy_get_status,
@@ -584,7 +584,7 @@ modern_dev_close(struct virtio_hw *hw)
 	return 0;
 }
 
-const struct virtio_pci_ops modern_ops = {
+const struct virtio_ops modern_ops = {
 	.read_dev_cfg	= modern_read_dev_config,
 	.write_dev_cfg	= modern_write_dev_config,
 	.get_status	= modern_get_status,
@@ -608,14 +608,14 @@ void
 vtpci_read_dev_config(struct virtio_hw *hw, size_t offset,
 		      void *dst, int length)
 {
-	VTPCI_OPS(hw)->read_dev_cfg(hw, offset, dst, length);
+	VIRTIO_OPS(hw)->read_dev_cfg(hw, offset, dst, length);
 }
 
 void
 vtpci_write_dev_config(struct virtio_hw *hw, size_t offset,
 		       const void *src, int length)
 {
-	VTPCI_OPS(hw)->write_dev_cfg(hw, offset, src, length);
+	VIRTIO_OPS(hw)->write_dev_cfg(hw, offset, src, length);
 }
 
 uint64_t
@@ -628,7 +628,7 @@ vtpci_negotiate_features(struct virtio_hw *hw, uint64_t host_features)
 	 * host all support.
 	 */
 	features = host_features & hw->guest_features;
-	VTPCI_OPS(hw)->set_features(hw, features);
+	VIRTIO_OPS(hw)->set_features(hw, features);
 
 	return features;
 }
@@ -636,9 +636,9 @@ vtpci_negotiate_features(struct virtio_hw *hw, uint64_t host_features)
 void
 vtpci_reset(struct virtio_hw *hw)
 {
-	VTPCI_OPS(hw)->set_status(hw, VIRTIO_CONFIG_STATUS_RESET);
+	VIRTIO_OPS(hw)->set_status(hw, VIRTIO_CONFIG_STATUS_RESET);
 	/* flush status write */
-	VTPCI_OPS(hw)->get_status(hw);
+	VIRTIO_OPS(hw)->get_status(hw);
 }
 
 void
@@ -651,21 +651,21 @@ void
 vtpci_set_status(struct virtio_hw *hw, uint8_t status)
 {
 	if (status != VIRTIO_CONFIG_STATUS_RESET)
-		status |= VTPCI_OPS(hw)->get_status(hw);
+		status |= VIRTIO_OPS(hw)->get_status(hw);
 
-	VTPCI_OPS(hw)->set_status(hw, status);
+	VIRTIO_OPS(hw)->set_status(hw, status);
 }
 
 uint8_t
 vtpci_get_status(struct virtio_hw *hw)
 {
-	return VTPCI_OPS(hw)->get_status(hw);
+	return VIRTIO_OPS(hw)->get_status(hw);
 }
 
 uint8_t
 vtpci_isr(struct virtio_hw *hw)
 {
-	return VTPCI_OPS(hw)->get_isr(hw);
+	return VIRTIO_OPS(hw)->get_isr(hw);
 }
 
 static void *
@@ -842,7 +842,7 @@ vtpci_init(struct rte_pci_device *pci_dev, struct virtio_pci_dev *dev)
 	 */
 	if (virtio_read_caps(pci_dev, hw) == 0) {
 		PMD_INIT_LOG(INFO, "modern virtio pci detected.");
-		virtio_hw_internal[hw->port_id].vtpci_ops = &modern_ops;
+		VIRTIO_OPS(hw) = &modern_ops;
 		dev->modern = true;
 		goto msix_detect;
 	}
@@ -861,7 +861,7 @@ vtpci_init(struct rte_pci_device *pci_dev, struct virtio_pci_dev *dev)
 		return -1;
 	}
 
-	virtio_hw_internal[hw->port_id].vtpci_ops = &legacy_ops;
+	VIRTIO_OPS(hw) = &legacy_ops;
 	dev->modern = false;
 
 msix_detect:
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index f208472273..f7f51fba79 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -12,6 +12,8 @@
 #include <rte_bus_pci.h>
 #include <rte_ethdev_driver.h>
 
+#include "virtio.h"
+
 struct virtqueue;
 struct virtnet_ctl;
 
@@ -214,70 +216,6 @@ struct virtio_pci_common_cfg {
 	uint32_t queue_used_hi;		/* read-write */
 };
 
-struct virtio_hw;
-
-struct virtio_pci_ops {
-	void (*read_dev_cfg)(struct virtio_hw *hw, size_t offset,
-			     void *dst, int len);
-	void (*write_dev_cfg)(struct virtio_hw *hw, size_t offset,
-			      const void *src, int len);
-
-	uint8_t (*get_status)(struct virtio_hw *hw);
-	void    (*set_status)(struct virtio_hw *hw, uint8_t status);
-
-	uint64_t (*get_features)(struct virtio_hw *hw);
-	void     (*set_features)(struct virtio_hw *hw, uint64_t features);
-	int      (*features_ok)(struct virtio_hw *hw);
-
-	uint8_t (*get_isr)(struct virtio_hw *hw);
-
-	uint16_t (*set_config_irq)(struct virtio_hw *hw, uint16_t vec);
-
-	uint16_t (*set_queue_irq)(struct virtio_hw *hw, struct virtqueue *vq,
-			uint16_t vec);
-
-	uint16_t (*get_queue_num)(struct virtio_hw *hw, uint16_t queue_id);
-	int (*setup_queue)(struct virtio_hw *hw, struct virtqueue *vq);
-	void (*del_queue)(struct virtio_hw *hw, struct virtqueue *vq);
-	void (*notify_queue)(struct virtio_hw *hw, struct virtqueue *vq);
-	void (*intr_event)(struct virtio_hw *hw);
-	int (*dev_close)(struct virtio_hw *hw);
-};
-
-struct virtio_net_config;
-
-struct virtio_hw {
-	struct virtqueue **vqs;
-	uint64_t guest_features;
-	uint16_t vtnet_hdr_size;
-	uint8_t started;
-	uint8_t weak_barriers;
-	uint8_t vlan_strip;
-	uint8_t has_tx_offload;
-	uint8_t has_rx_offload;
-	uint8_t use_vec_rx;
-	uint8_t use_vec_tx;
-	uint8_t use_inorder_rx;
-	uint8_t use_inorder_tx;
-	uint8_t opened;
-	uint16_t port_id;
-	uint8_t mac_addr[RTE_ETHER_ADDR_LEN];
-	uint32_t speed;  /* link speed in MB */
-	uint8_t duplex;
-	uint8_t use_msix;
-	uint16_t max_mtu;
-	/*
-	 * App management thread and virtio interrupt handler thread
-	 * both can change device state, this lock is meant to avoid
-	 * such a contention.
-	 */
-	rte_spinlock_t state_lock;
-	struct rte_mbuf **inject_pkts;
-	uint16_t max_queue_pairs;
-	uint64_t req_guest_features;
-	struct virtnet_ctl *cvq;
-};
-
 struct virtio_pci_dev {
 	struct virtio_hw hw;
 	struct rte_pci_device *pci_dev;
@@ -291,19 +229,6 @@ struct virtio_pci_dev {
 
 #define virtio_pci_get_dev(hwp) container_of(hwp, struct virtio_pci_dev, hw)
 
-/*
- * While virtio_hw is stored in shared memory, this structure stores
- * some infos that may vary in the multiple process model locally.
- * For example, the vtpci_ops pointer.
- */
-struct virtio_hw_internal {
-	const struct virtio_pci_ops *vtpci_ops;
-};
-
-#define VTPCI_OPS(hw)	(virtio_hw_internal[(hw)->port_id].vtpci_ops)
-
-extern struct virtio_hw_internal virtio_hw_internal[RTE_MAX_ETHPORTS];
-
 /*
  * This structure is just a reference to read
  * net device specific config space; it just a chodu structure
@@ -379,8 +304,7 @@ uint8_t vtpci_isr(struct virtio_hw *);
 void vtpci_legacy_ioport_unmap(struct virtio_hw *hw);
 int vtpci_legacy_ioport_map(struct virtio_hw *hw);
 
-extern const struct virtio_pci_ops legacy_ops;
-extern const struct virtio_pci_ops modern_ops;
-extern const struct virtio_pci_ops virtio_user_ops;
+extern const struct virtio_ops legacy_ops;
+extern const struct virtio_ops modern_ops;
 
 #endif /* _VIRTIO_PCI_H_ */
diff --git a/drivers/net/virtio/virtio_pci_ethdev.c b/drivers/net/virtio/virtio_pci_ethdev.c
index 9fe59feb51..fb462572fb 100644
--- a/drivers/net/virtio/virtio_pci_ethdev.c
+++ b/drivers/net/virtio/virtio_pci_ethdev.c
@@ -19,6 +19,7 @@
 #include <rte_dev.h>
 #include <rte_kvargs.h>
 
+#include "virtio.h"
 #include "virtio_ethdev.h"
 #include "virtio_pci.h"
 #include "virtio_logs.h"
@@ -83,9 +84,9 @@ eth_virtio_pci_init(struct rte_eth_dev *eth_dev)
 		}
 	} else {
 		if (dev->modern)
-			VTPCI_OPS(hw) = &modern_ops;
+			VIRTIO_OPS(hw) = &modern_ops;
 		else
-			VTPCI_OPS(hw) = &legacy_ops;
+			VIRTIO_OPS(hw) = &legacy_ops;
 
 		ret = virtio_remap_pci(RTE_ETH_DEV_TO_PCI(eth_dev), dev);
 		if (ret < 0) {
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index 61880a8e02..6597c16539 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -20,7 +20,7 @@
 
 #include "virtio_ethdev.h"
 #include "virtio_logs.h"
-#include "virtio_pci.h"
+#include "virtio.h"
 #include "virtqueue.h"
 #include "virtio_rxtx.h"
 #include "virtio_user/virtio_user_dev.h"
@@ -478,7 +478,7 @@ virtio_user_dev_close(struct virtio_hw *hw)
 	return 0;
 }
 
-const struct virtio_pci_ops virtio_user_ops = {
+const struct virtio_ops virtio_user_ops = {
 	.read_dev_cfg	= virtio_user_read_dev_config,
 	.write_dev_cfg	= virtio_user_write_dev_config,
 	.get_status	= virtio_user_get_status,
@@ -635,7 +635,7 @@ virtio_user_eth_dev_alloc(struct rte_vdev_device *vdev)
 
 	hw->port_id = data->port_id;
 	dev->port_id = data->port_id;
-	virtio_hw_internal[hw->port_id].vtpci_ops = &virtio_user_ops;
+	VIRTIO_OPS(hw) = &virtio_user_ops;
 	/*
 	 * MSIX is required to enable LSC (see virtio_init_device).
 	 * Here just pretend that we support msix.
@@ -692,7 +692,7 @@ virtio_user_pmd_probe(struct rte_vdev_device *vdev)
 
 		dev = eth_dev->data->dev_private;
 		hw = &dev->hw;
-		VTPCI_OPS(hw) = &virtio_user_ops;
+		VIRTIO_OPS(hw) = &virtio_user_ops;
 
 		if (eth_virtio_dev_init(eth_dev) < 0) {
 			PMD_INIT_LOG(ERR, "eth_virtio_dev_init fails");
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index 3a9ce29069..6293cd2604 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -563,7 +563,7 @@ virtqueue_kick_prepare_packed(struct virtqueue *vq)
 static inline void
 virtqueue_notify(struct virtqueue *vq)
 {
-	VTPCI_OPS(vq->hw)->notify_queue(vq->hw, vq);
+	VIRTIO_OPS(vq->hw)->notify_queue(vq->hw, vq);
 }
 
 #ifdef RTE_LIBRTE_VIRTIO_DEBUG_DUMP
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 19/44] net/virtio: move features definition to generic header
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (17 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 18/44] net/virtio: introduce generic virtio header Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-21  6:47   ` Xia, Chenbo
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 20/44] net/virtio: move virtqueue defines in " Maxime Coquelin
                   ` (24 subsequent siblings)
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch moves all the Virtio definition to the generic
header. It also renames some helpers to no more reference
PCI.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/meson.build                |   3 +-
 drivers/net/virtio/virtio.c                   |  22 ++++
 drivers/net/virtio/virtio.h                   |  94 +++++++++++++++
 drivers/net/virtio/virtio_ethdev.c            | 114 +++++++++---------
 drivers/net/virtio/virtio_pci.c               |  21 +---
 drivers/net/virtio/virtio_pci.h               |  90 --------------
 drivers/net/virtio/virtio_ring.h              |   2 +-
 drivers/net/virtio/virtio_rxtx.c              |  38 +++---
 drivers/net/virtio/virtio_rxtx_packed.h       |   6 +-
 .../net/virtio/virtio_user/vhost_kernel_tap.c |   2 +-
 drivers/net/virtio/virtio_user_ethdev.c       |   6 +-
 drivers/net/virtio/virtqueue.c                |   4 +-
 drivers/net/virtio/virtqueue.h                |   8 +-
 13 files changed, 211 insertions(+), 199 deletions(-)
 create mode 100644 drivers/net/virtio/virtio.c

diff --git a/drivers/net/virtio/meson.build b/drivers/net/virtio/meson.build
index f2873d6180..d595cfdcab 100644
--- a/drivers/net/virtio/meson.build
+++ b/drivers/net/virtio/meson.build
@@ -7,7 +7,8 @@ if is_windows
 	subdir_done()
 endif
 
-sources += files('virtio_ethdev.c',
+sources += files('virtio.c',
+	'virtio_ethdev.c',
 	'virtio_pci_ethdev.c',
 	'virtio_pci.c',
 	'virtio_rxtx.c',
diff --git a/drivers/net/virtio/virtio.c b/drivers/net/virtio/virtio.c
new file mode 100644
index 0000000000..d8d6bf7add
--- /dev/null
+++ b/drivers/net/virtio/virtio.c
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
+ * Copyright(c) 2020 Red Hat, Inc.
+ */
+
+#include "virtio.h"
+
+uint64_t
+virtio_negotiate_features(struct virtio_hw *hw, uint64_t host_features)
+{
+	uint64_t features;
+
+	/*
+	 * Limit negotiated features to what the driver, virtqueue, and
+	 * host all support.
+	 */
+	features = host_features & hw->guest_features;
+	VIRTIO_OPS(hw)->set_features(hw, features);
+
+	return features;
+}
+
diff --git a/drivers/net/virtio/virtio.h b/drivers/net/virtio/virtio.h
index 256060287d..572be2006d 100644
--- a/drivers/net/virtio/virtio.h
+++ b/drivers/net/virtio/virtio.h
@@ -8,6 +8,86 @@
 
 #include <rte_ether.h>
 
+/* The feature bitmap for virtio net */
+#define VIRTIO_NET_F_CSUM	0	/* Host handles pkts w/ partial csum */
+#define VIRTIO_NET_F_GUEST_CSUM	1	/* Guest handles pkts w/ partial csum */
+#define VIRTIO_NET_F_MTU	3	/* Initial MTU advice. */
+#define VIRTIO_NET_F_MAC	5	/* Host has given MAC address. */
+#define VIRTIO_NET_F_GUEST_TSO4	7	/* Guest can handle TSOv4 in. */
+#define VIRTIO_NET_F_GUEST_TSO6	8	/* Guest can handle TSOv6 in. */
+#define VIRTIO_NET_F_GUEST_ECN	9	/* Guest can handle TSO[6] w/ ECN in. */
+#define VIRTIO_NET_F_GUEST_UFO	10	/* Guest can handle UFO in. */
+#define VIRTIO_NET_F_HOST_TSO4	11	/* Host can handle TSOv4 in. */
+#define VIRTIO_NET_F_HOST_TSO6	12	/* Host can handle TSOv6 in. */
+#define VIRTIO_NET_F_HOST_ECN	13	/* Host can handle TSO[6] w/ ECN in. */
+#define VIRTIO_NET_F_HOST_UFO	14	/* Host can handle UFO in. */
+#define VIRTIO_NET_F_MRG_RXBUF	15	/* Host can merge receive buffers. */
+#define VIRTIO_NET_F_STATUS	16	/* virtio_net_config.status available */
+#define VIRTIO_NET_F_CTRL_VQ	17	/* Control channel available */
+#define VIRTIO_NET_F_CTRL_RX	18	/* Control channel RX mode support */
+#define VIRTIO_NET_F_CTRL_VLAN	19	/* Control channel VLAN filtering */
+#define VIRTIO_NET_F_CTRL_RX_EXTRA 20	/* Extra RX mode control support */
+#define VIRTIO_NET_F_GUEST_ANNOUNCE 21	/* Guest can announce device on the network */
+#define VIRTIO_NET_F_MQ		22	/* Device supports Receive Flow Steering */
+#define VIRTIO_NET_F_CTRL_MAC_ADDR 23	/* Set MAC address */
+
+/*
+ * Do we get callbacks when the ring is completely used,
+ * even if we've suppressed them?
+ */
+#define VIRTIO_F_NOTIFY_ON_EMPTY	24
+
+/* Can the device handle any descriptor layout? */
+#define VIRTIO_F_ANY_LAYOUT		27
+
+/* We support indirect buffer descriptors */
+#define VIRTIO_RING_F_INDIRECT_DESC	28
+
+#define VIRTIO_F_VERSION_1		32
+#define VIRTIO_F_IOMMU_PLATFORM	33
+#define VIRTIO_F_RING_PACKED		34
+
+/*
+ * Some VirtIO feature bits (currently bits 28 through 31) are
+ * reserved for the transport being used (eg. virtio_ring), the
+ * rest are per-device feature bits.
+ */
+#define VIRTIO_TRANSPORT_F_START 28
+#define VIRTIO_TRANSPORT_F_END   34
+
+/*
+ * Inorder feature indicates that all buffers are used by the device
+ * in the same order in which they have been made available.
+ */
+#define VIRTIO_F_IN_ORDER 35
+
+/*
+ * This feature indicates that memory accesses by the driver and the device
+ * are ordered in a way described by the platform.
+ */
+#define VIRTIO_F_ORDER_PLATFORM 36
+
+/*
+ * This feature indicates that the driver passes extra data (besides
+ * identifying the virtqueue) in its device notifications.
+ */
+#define VIRTIO_F_NOTIFICATION_DATA 38
+
+/* Device set linkspeed and duplex */
+#define VIRTIO_NET_F_SPEED_DUPLEX 63
+
+/*
+ * The Guest publishes the used index for which it expects an interrupt
+ * at the end of the avail ring. Host should ignore the avail->flags field
+ *
+ * The Host publishes the avail index for which it expects a kick
+ * at the end of the used ring. Guest should ignore the used->flags field.
+ */
+#define VIRTIO_RING_F_EVENT_IDX		29
+
+#define VIRTIO_NET_S_LINK_UP	1	/* Link is up */
+#define VIRTIO_NET_S_ANNOUNCE	2	/* Announcement is needed */
+
 struct virtio_hw {
 	struct virtqueue **vqs;
 	uint64_t guest_features;
@@ -71,4 +151,18 @@ struct virtio_hw_internal {
 extern struct virtio_hw_internal virtio_hw_internal[RTE_MAX_ETHPORTS];
 
 
+static inline int
+virtio_with_feature(struct virtio_hw *hw, uint64_t bit)
+{
+	return (hw->guest_features & (1ULL << bit)) != 0;
+}
+
+static inline int
+virtio_with_packed_queue(struct virtio_hw *hw)
+{
+	return virtio_with_feature(hw, VIRTIO_F_RING_PACKED);
+}
+
+uint64_t virtio_negotiate_features(struct virtio_hw *hw, uint64_t host_features);
+
 #endif /* _VIRTIO_H_ */
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 6287d0c29b..ea81340997 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -339,7 +339,7 @@ virtio_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
 	memcpy(cvq->virtio_net_hdr_mz->addr, ctrl,
 		sizeof(struct virtio_pmd_ctrl));
 
-	if (vtpci_packed_queue(vq->hw))
+	if (virtio_with_packed_queue(vq->hw))
 		result = virtio_send_command_packed(cvq, ctrl, dlen, pkt_num);
 	else
 		result = virtio_send_command_split(cvq, ctrl, dlen, pkt_num);
@@ -383,7 +383,7 @@ virtio_get_nr_vq(struct virtio_hw *hw)
 {
 	uint16_t nr_vq = hw->max_queue_pairs * 2;
 
-	if (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ))
+	if (virtio_with_feature(hw, VIRTIO_NET_F_CTRL_VQ))
 		nr_vq += 1;
 
 	return nr_vq;
@@ -405,7 +405,7 @@ virtio_init_vring(struct virtqueue *vq)
 	vq->vq_desc_tail_idx = (uint16_t)(vq->vq_nentries - 1);
 	vq->vq_free_cnt = vq->vq_nentries;
 	memset(vq->vq_descx, 0, sizeof(struct vq_desc_extra) * vq->vq_nentries);
-	if (vtpci_packed_queue(vq->hw)) {
+	if (virtio_with_packed_queue(vq->hw)) {
 		vring_init_packed(&vq->vq_packed.ring, ring_mem,
 				  VIRTIO_PCI_VRING_ALIGN, size);
 		vring_desc_init_packed(vq, size);
@@ -453,7 +453,7 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
 		return -EINVAL;
 	}
 
-	if (!vtpci_packed_queue(hw) && !rte_is_power_of_2(vq_size)) {
+	if (!virtio_with_packed_queue(hw) && !rte_is_power_of_2(vq_size)) {
 		PMD_INIT_LOG(ERR, "split virtqueue size is not power of 2");
 		return -EINVAL;
 	}
@@ -486,7 +486,7 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
 	vq->hw = hw;
 	vq->vq_queue_index = vtpci_queue_idx;
 	vq->vq_nentries = vq_size;
-	if (vtpci_packed_queue(hw)) {
+	if (virtio_with_packed_queue(hw)) {
 		vq->vq_packed.used_wrap_counter = 1;
 		vq->vq_packed.cached_flags = VRING_PACKED_DESC_F_AVAIL;
 		vq->vq_packed.event_flags_shadow = 0;
@@ -584,7 +584,7 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
 		memset(txr, 0, vq_size * sizeof(*txr));
 		for (i = 0; i < vq_size; i++) {
 			/* first indirect descriptor is always the tx header */
-			if (!vtpci_packed_queue(hw)) {
+			if (!virtio_with_packed_queue(hw)) {
 				struct vring_desc *start_dp = txr[i].tx_indir;
 				vring_desc_init_split(start_dp,
 						      RTE_DIM(txr[i].tx_indir));
@@ -729,7 +729,7 @@ virtio_dev_promiscuous_enable(struct rte_eth_dev *dev)
 	int dlen[1];
 	int ret;
 
-	if (!vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_RX)) {
+	if (!virtio_with_feature(hw, VIRTIO_NET_F_CTRL_RX)) {
 		PMD_INIT_LOG(INFO, "host does not support rx control");
 		return -ENOTSUP;
 	}
@@ -756,7 +756,7 @@ virtio_dev_promiscuous_disable(struct rte_eth_dev *dev)
 	int dlen[1];
 	int ret;
 
-	if (!vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_RX)) {
+	if (!virtio_with_feature(hw, VIRTIO_NET_F_CTRL_RX)) {
 		PMD_INIT_LOG(INFO, "host does not support rx control");
 		return -ENOTSUP;
 	}
@@ -783,7 +783,7 @@ virtio_dev_allmulticast_enable(struct rte_eth_dev *dev)
 	int dlen[1];
 	int ret;
 
-	if (!vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_RX)) {
+	if (!virtio_with_feature(hw, VIRTIO_NET_F_CTRL_RX)) {
 		PMD_INIT_LOG(INFO, "host does not support rx control");
 		return -ENOTSUP;
 	}
@@ -810,7 +810,7 @@ virtio_dev_allmulticast_disable(struct rte_eth_dev *dev)
 	int dlen[1];
 	int ret;
 
-	if (!vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_RX)) {
+	if (!virtio_with_feature(hw, VIRTIO_NET_F_CTRL_RX)) {
 		PMD_INIT_LOG(INFO, "host does not support rx control");
 		return -ENOTSUP;
 	}
@@ -1104,7 +1104,7 @@ virtio_set_hwaddr(struct virtio_hw *hw)
 static void
 virtio_get_hwaddr(struct virtio_hw *hw)
 {
-	if (vtpci_with_feature(hw, VIRTIO_NET_F_MAC)) {
+	if (virtio_with_feature(hw, VIRTIO_NET_F_MAC)) {
 		vtpci_read_dev_config(hw,
 			offsetof(struct virtio_net_config, mac),
 			&hw->mac_addr, RTE_ETHER_ADDR_LEN);
@@ -1122,7 +1122,7 @@ virtio_mac_table_set(struct virtio_hw *hw,
 	struct virtio_pmd_ctrl ctrl;
 	int err, len[2];
 
-	if (!vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_MAC_ADDR)) {
+	if (!virtio_with_feature(hw, VIRTIO_NET_F_CTRL_MAC_ADDR)) {
 		PMD_DRV_LOG(INFO, "host does not support mac table");
 		return -1;
 	}
@@ -1217,7 +1217,7 @@ virtio_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr)
 	memcpy(hw->mac_addr, mac_addr, RTE_ETHER_ADDR_LEN);
 
 	/* Use atomic update if available */
-	if (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_MAC_ADDR)) {
+	if (virtio_with_feature(hw, VIRTIO_NET_F_CTRL_MAC_ADDR)) {
 		struct virtio_pmd_ctrl ctrl;
 		int len = RTE_ETHER_ADDR_LEN;
 
@@ -1228,7 +1228,7 @@ virtio_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr)
 		return virtio_send_command(hw->cvq, &ctrl, &len, 1);
 	}
 
-	if (!vtpci_with_feature(hw, VIRTIO_NET_F_MAC))
+	if (!virtio_with_feature(hw, VIRTIO_NET_F_MAC))
 		return -ENOTSUP;
 
 	virtio_set_hwaddr(hw);
@@ -1242,7 +1242,7 @@ virtio_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 	struct virtio_pmd_ctrl ctrl;
 	int len;
 
-	if (!vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VLAN))
+	if (!virtio_with_feature(hw, VIRTIO_NET_F_CTRL_VLAN))
 		return -ENOTSUP;
 
 	ctrl.hdr.class = VIRTIO_NET_CTRL_VLAN;
@@ -1296,7 +1296,7 @@ virtio_intr_disable(struct rte_eth_dev *dev)
 }
 
 static int
-virtio_negotiate_features(struct virtio_hw *hw, uint64_t req_features)
+virtio_ethdev_negotiate_features(struct virtio_hw *hw, uint64_t req_features)
 {
 	uint64_t host_features;
 
@@ -1326,14 +1326,14 @@ virtio_negotiate_features(struct virtio_hw *hw, uint64_t req_features)
 	 * guest feature bits.
 	 */
 	hw->guest_features = req_features;
-	hw->guest_features = vtpci_negotiate_features(hw, host_features);
+	hw->guest_features = virtio_negotiate_features(hw, host_features);
 	PMD_INIT_LOG(DEBUG, "features after negotiate = %" PRIx64,
 		hw->guest_features);
 
 	if (VIRTIO_OPS(hw)->features_ok(hw) < 0)
 		return -1;
 
-	if (vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) {
+	if (virtio_with_feature(hw, VIRTIO_F_VERSION_1)) {
 		vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_FEATURES_OK);
 
 		if (!(vtpci_get_status(hw) & VIRTIO_CONFIG_STATUS_FEATURES_OK)) {
@@ -1467,7 +1467,7 @@ virtio_interrupt_handler(void *param)
 						     RTE_ETH_EVENT_INTR_LSC,
 						     NULL);
 
-		if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {
+		if (virtio_with_feature(hw, VIRTIO_NET_F_STATUS)) {
 			vtpci_read_dev_config(hw,
 				offsetof(struct virtio_net_config, status),
 				&status, sizeof(status));
@@ -1487,7 +1487,7 @@ set_rxtx_funcs(struct rte_eth_dev *eth_dev)
 	struct virtio_hw *hw = eth_dev->data->dev_private;
 
 	eth_dev->tx_pkt_prepare = virtio_xmit_pkts_prepare;
-	if (vtpci_packed_queue(hw)) {
+	if (virtio_with_packed_queue(hw)) {
 		PMD_INIT_LOG(INFO,
 			"virtio: using packed ring %s Tx path on port %u",
 			hw->use_vec_tx ? "vectorized" : "standard",
@@ -1508,14 +1508,14 @@ set_rxtx_funcs(struct rte_eth_dev *eth_dev)
 		}
 	}
 
-	if (vtpci_packed_queue(hw)) {
+	if (virtio_with_packed_queue(hw)) {
 		if (hw->use_vec_rx) {
 			PMD_INIT_LOG(INFO,
 				"virtio: using packed ring vectorized Rx path on port %u",
 				eth_dev->data->port_id);
 			eth_dev->rx_pkt_burst =
 				&virtio_recv_pkts_packed_vec;
-		} else if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
+		} else if (virtio_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
 			PMD_INIT_LOG(INFO,
 				"virtio: using packed ring mergeable buffer Rx path on port %u",
 				eth_dev->data->port_id);
@@ -1537,7 +1537,7 @@ set_rxtx_funcs(struct rte_eth_dev *eth_dev)
 				"virtio: using inorder Rx path on port %u",
 				eth_dev->data->port_id);
 			eth_dev->rx_pkt_burst =	&virtio_recv_pkts_inorder;
-		} else if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
+		} else if (virtio_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
 			PMD_INIT_LOG(INFO,
 				"virtio: using mergeable buffer Rx path on port %u",
 				eth_dev->data->port_id);
@@ -1662,13 +1662,13 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 
 	/* Tell the host we've known how to drive the device. */
 	vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);
-	if (virtio_negotiate_features(hw, req_features) < 0)
+	if (virtio_ethdev_negotiate_features(hw, req_features) < 0)
 		return -1;
 
-	hw->weak_barriers = !vtpci_with_feature(hw, VIRTIO_F_ORDER_PLATFORM);
+	hw->weak_barriers = !virtio_with_feature(hw, VIRTIO_F_ORDER_PLATFORM);
 
 	/* If host does not support both status and MSI-X then disable LSC */
-	if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS) &&
+	if (virtio_with_feature(hw, VIRTIO_NET_F_STATUS) &&
 	    hw->use_msix != VIRTIO_MSIX_NONE)
 		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
 	else
@@ -1677,9 +1677,9 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 	eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
 
 	/* Setting up rx_header size for the device */
-	if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF) ||
-	    vtpci_with_feature(hw, VIRTIO_F_VERSION_1) ||
-	    vtpci_with_feature(hw, VIRTIO_F_RING_PACKED))
+	if (virtio_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF) ||
+	    virtio_with_feature(hw, VIRTIO_F_VERSION_1) ||
+	    virtio_with_packed_queue(hw))
 		hw->vtnet_hdr_size = sizeof(struct virtio_net_hdr_mrg_rxbuf);
 	else
 		hw->vtnet_hdr_size = sizeof(struct virtio_net_hdr);
@@ -1694,7 +1694,7 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 		     hw->mac_addr[3], hw->mac_addr[4], hw->mac_addr[5]);
 
 	if (hw->speed == ETH_SPEED_NUM_UNKNOWN) {
-		if (vtpci_with_feature(hw, VIRTIO_NET_F_SPEED_DUPLEX)) {
+		if (virtio_with_feature(hw, VIRTIO_NET_F_SPEED_DUPLEX)) {
 			config = &local_config;
 			vtpci_read_dev_config(hw,
 				offsetof(struct virtio_net_config, speed),
@@ -1710,14 +1710,14 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 		hw->duplex = ETH_LINK_FULL_DUPLEX;
 	PMD_INIT_LOG(DEBUG, "link speed = %d, duplex = %d",
 		hw->speed, hw->duplex);
-	if (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ)) {
+	if (virtio_with_feature(hw, VIRTIO_NET_F_CTRL_VQ)) {
 		config = &local_config;
 
 		vtpci_read_dev_config(hw,
 			offsetof(struct virtio_net_config, mac),
 			&config->mac, sizeof(config->mac));
 
-		if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {
+		if (virtio_with_feature(hw, VIRTIO_NET_F_STATUS)) {
 			vtpci_read_dev_config(hw,
 				offsetof(struct virtio_net_config, status),
 				&config->status, sizeof(config->status));
@@ -1727,7 +1727,7 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 			config->status = 0;
 		}
 
-		if (vtpci_with_feature(hw, VIRTIO_NET_F_MQ)) {
+		if (virtio_with_feature(hw, VIRTIO_NET_F_MQ)) {
 			vtpci_read_dev_config(hw,
 				offsetof(struct virtio_net_config, max_virtqueue_pairs),
 				&config->max_virtqueue_pairs,
@@ -1740,7 +1740,7 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 
 		hw->max_queue_pairs = config->max_virtqueue_pairs;
 
-		if (vtpci_with_feature(hw, VIRTIO_NET_F_MTU)) {
+		if (virtio_with_feature(hw, VIRTIO_NET_F_MTU)) {
 			vtpci_read_dev_config(hw,
 				offsetof(struct virtio_net_config, mtu),
 				&config->mtu,
@@ -1851,7 +1851,7 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 		goto err_virtio_init;
 
 	if (vectorized) {
-		if (!vtpci_packed_queue(hw)) {
+		if (!virtio_with_packed_queue(hw)) {
 			hw->use_vec_rx = 1;
 		} else {
 #if defined(CC_AVX512_SUPPORT) || defined(RTE_ARCH_ARM)
@@ -1976,17 +1976,17 @@ virtio_dev_devargs_parse(struct rte_devargs *devargs, uint32_t *speed, int *vect
 static uint8_t
 rx_offload_enabled(struct virtio_hw *hw)
 {
-	return vtpci_with_feature(hw, VIRTIO_NET_F_GUEST_CSUM) ||
-		vtpci_with_feature(hw, VIRTIO_NET_F_GUEST_TSO4) ||
-		vtpci_with_feature(hw, VIRTIO_NET_F_GUEST_TSO6);
+	return virtio_with_feature(hw, VIRTIO_NET_F_GUEST_CSUM) ||
+		virtio_with_feature(hw, VIRTIO_NET_F_GUEST_TSO4) ||
+		virtio_with_feature(hw, VIRTIO_NET_F_GUEST_TSO6);
 }
 
 static uint8_t
 tx_offload_enabled(struct virtio_hw *hw)
 {
-	return vtpci_with_feature(hw, VIRTIO_NET_F_CSUM) ||
-		vtpci_with_feature(hw, VIRTIO_NET_F_HOST_TSO4) ||
-		vtpci_with_feature(hw, VIRTIO_NET_F_HOST_TSO6);
+	return virtio_with_feature(hw, VIRTIO_NET_F_CSUM) ||
+		virtio_with_feature(hw, VIRTIO_NET_F_HOST_TSO4) ||
+		virtio_with_feature(hw, VIRTIO_NET_F_HOST_TSO6);
 }
 
 /*
@@ -2059,29 +2059,29 @@ virtio_dev_configure(struct rte_eth_dev *dev)
 
 	if ((rx_offloads & (DEV_RX_OFFLOAD_UDP_CKSUM |
 			    DEV_RX_OFFLOAD_TCP_CKSUM)) &&
-		!vtpci_with_feature(hw, VIRTIO_NET_F_GUEST_CSUM)) {
+		!virtio_with_feature(hw, VIRTIO_NET_F_GUEST_CSUM)) {
 		PMD_DRV_LOG(ERR,
 			"rx checksum not available on this host");
 		return -ENOTSUP;
 	}
 
 	if ((rx_offloads & DEV_RX_OFFLOAD_TCP_LRO) &&
-		(!vtpci_with_feature(hw, VIRTIO_NET_F_GUEST_TSO4) ||
-		 !vtpci_with_feature(hw, VIRTIO_NET_F_GUEST_TSO6))) {
+		(!virtio_with_feature(hw, VIRTIO_NET_F_GUEST_TSO4) ||
+		 !virtio_with_feature(hw, VIRTIO_NET_F_GUEST_TSO6))) {
 		PMD_DRV_LOG(ERR,
 			"Large Receive Offload not available on this host");
 		return -ENOTSUP;
 	}
 
 	/* start control queue */
-	if (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ))
+	if (virtio_with_feature(hw, VIRTIO_NET_F_CTRL_VQ))
 		virtio_dev_cq_start(dev);
 
 	if (rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
 		hw->vlan_strip = 1;
 
-	if ((rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)
-	    && !vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VLAN)) {
+	if ((rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER) &&
+			!virtio_with_feature(hw, VIRTIO_NET_F_CTRL_VLAN)) {
 		PMD_DRV_LOG(ERR,
 			    "vlan filtering not available on this host");
 		return -ENOTSUP;
@@ -2098,12 +2098,12 @@ virtio_dev_configure(struct rte_eth_dev *dev)
 			return -EBUSY;
 		}
 
-	if (vtpci_packed_queue(hw)) {
+	if (virtio_with_packed_queue(hw)) {
 #if defined(RTE_ARCH_X86_64) && defined(CC_AVX512_SUPPORT)
 		if ((hw->use_vec_rx || hw->use_vec_tx) &&
 		    (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512F) ||
-		     !vtpci_with_feature(hw, VIRTIO_F_IN_ORDER) ||
-		     !vtpci_with_feature(hw, VIRTIO_F_VERSION_1) ||
+		     !virtio_with_feature(hw, VIRTIO_F_IN_ORDER) ||
+		     !virtio_with_feature(hw, VIRTIO_F_VERSION_1) ||
 		     rte_vect_get_max_simd_bitwidth() < RTE_VECT_SIMD_512)) {
 			PMD_DRV_LOG(INFO,
 				"disabled packed ring vectorized path for requirements not met");
@@ -2113,8 +2113,8 @@ virtio_dev_configure(struct rte_eth_dev *dev)
 #elif defined(RTE_ARCH_ARM)
 		if ((hw->use_vec_rx || hw->use_vec_tx) &&
 		    (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_NEON) ||
-		     !vtpci_with_feature(hw, VIRTIO_F_IN_ORDER) ||
-		     !vtpci_with_feature(hw, VIRTIO_F_VERSION_1) ||
+		     !virtio_with_feature(hw, VIRTIO_F_IN_ORDER) ||
+		     !virtio_with_feature(hw, VIRTIO_F_VERSION_1) ||
 		     rte_vect_get_max_simd_bitwidth() < RTE_VECT_SIMD_128)) {
 			PMD_DRV_LOG(INFO,
 				"disabled packed ring vectorized path for requirements not met");
@@ -2127,7 +2127,7 @@ virtio_dev_configure(struct rte_eth_dev *dev)
 #endif
 
 		if (hw->use_vec_rx) {
-			if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
+			if (virtio_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
 				PMD_DRV_LOG(INFO,
 					"disabled packed ring vectorized rx for mrg_rxbuf enabled");
 				hw->use_vec_rx = 0;
@@ -2140,7 +2140,7 @@ virtio_dev_configure(struct rte_eth_dev *dev)
 			}
 		}
 	} else {
-		if (vtpci_with_feature(hw, VIRTIO_F_IN_ORDER)) {
+		if (virtio_with_feature(hw, VIRTIO_F_IN_ORDER)) {
 			hw->use_inorder_tx = 1;
 			hw->use_inorder_rx = 1;
 			hw->use_vec_rx = 0;
@@ -2154,7 +2154,7 @@ virtio_dev_configure(struct rte_eth_dev *dev)
 				hw->use_vec_rx = 0;
 			}
 #endif
-			if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
+			if (virtio_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
 				PMD_DRV_LOG(INFO,
 					"disabled split ring vectorized rx for mrg_rxbuf enabled");
 				hw->use_vec_rx = 0;
@@ -2372,7 +2372,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 	if (!hw->started) {
 		link.link_status = ETH_LINK_DOWN;
 		link.link_speed = ETH_SPEED_NUM_NONE;
-	} else if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {
+	} else if (virtio_with_feature(hw, VIRTIO_NET_F_STATUS)) {
 		PMD_INIT_LOG(DEBUG, "Get link status from hw");
 		vtpci_read_dev_config(hw,
 				offsetof(struct virtio_net_config, status),
@@ -2403,7 +2403,7 @@ virtio_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
 
 	if (mask & ETH_VLAN_FILTER_MASK) {
 		if ((offloads & DEV_RX_OFFLOAD_VLAN_FILTER) &&
-				!vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VLAN)) {
+				!virtio_with_feature(hw, VIRTIO_NET_F_CTRL_VLAN)) {
 
 			PMD_DRV_LOG(NOTICE,
 				"vlan filtering not available on this host");
diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index acd91042d9..760d404a5a 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -415,7 +415,7 @@ modern_set_features(struct virtio_hw *hw, uint64_t features)
 static int
 modern_features_ok(struct virtio_hw *hw)
 {
-	if (!vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) {
+	if (!virtio_with_feature(hw, VIRTIO_F_VERSION_1)) {
 		PMD_INIT_LOG(ERR, "Version 1+ required with modern devices\n");
 		return -1;
 	}
@@ -538,12 +538,12 @@ modern_notify_queue(struct virtio_hw *hw, struct virtqueue *vq)
 {
 	uint32_t notify_data;
 
-	if (!vtpci_with_feature(hw, VIRTIO_F_NOTIFICATION_DATA)) {
+	if (!virtio_with_feature(hw, VIRTIO_F_NOTIFICATION_DATA)) {
 		rte_write16(vq->vq_queue_index, vq->notify_addr);
 		return;
 	}
 
-	if (vtpci_with_feature(hw, VIRTIO_F_RING_PACKED)) {
+	if (virtio_with_feature(hw, VIRTIO_F_RING_PACKED)) {
 		/*
 		 * Bit[0:15]: vq queue index
 		 * Bit[16:30]: avail index
@@ -618,21 +618,6 @@ vtpci_write_dev_config(struct virtio_hw *hw, size_t offset,
 	VIRTIO_OPS(hw)->write_dev_cfg(hw, offset, src, length);
 }
 
-uint64_t
-vtpci_negotiate_features(struct virtio_hw *hw, uint64_t host_features)
-{
-	uint64_t features;
-
-	/*
-	 * Limit negotiated features to what the driver, virtqueue, and
-	 * host all support.
-	 */
-	features = host_features & hw->guest_features;
-	VIRTIO_OPS(hw)->set_features(hw, features);
-
-	return features;
-}
-
 void
 vtpci_reset(struct virtio_hw *hw)
 {
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index f7f51fba79..3d93e74f36 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -79,83 +79,6 @@ struct virtnet_ctl;
  */
 #define VIRTIO_MAX_INDIRECT ((int) (PAGE_SIZE / 16))
 
-/* The feature bitmap for virtio net */
-#define VIRTIO_NET_F_CSUM	0	/* Host handles pkts w/ partial csum */
-#define VIRTIO_NET_F_GUEST_CSUM	1	/* Guest handles pkts w/ partial csum */
-#define VIRTIO_NET_F_MTU	3	/* Initial MTU advice. */
-#define VIRTIO_NET_F_MAC	5	/* Host has given MAC address. */
-#define VIRTIO_NET_F_GUEST_TSO4	7	/* Guest can handle TSOv4 in. */
-#define VIRTIO_NET_F_GUEST_TSO6	8	/* Guest can handle TSOv6 in. */
-#define VIRTIO_NET_F_GUEST_ECN	9	/* Guest can handle TSO[6] w/ ECN in. */
-#define VIRTIO_NET_F_GUEST_UFO	10	/* Guest can handle UFO in. */
-#define VIRTIO_NET_F_HOST_TSO4	11	/* Host can handle TSOv4 in. */
-#define VIRTIO_NET_F_HOST_TSO6	12	/* Host can handle TSOv6 in. */
-#define VIRTIO_NET_F_HOST_ECN	13	/* Host can handle TSO[6] w/ ECN in. */
-#define VIRTIO_NET_F_HOST_UFO	14	/* Host can handle UFO in. */
-#define VIRTIO_NET_F_MRG_RXBUF	15	/* Host can merge receive buffers. */
-#define VIRTIO_NET_F_STATUS	16	/* virtio_net_config.status available */
-#define VIRTIO_NET_F_CTRL_VQ	17	/* Control channel available */
-#define VIRTIO_NET_F_CTRL_RX	18	/* Control channel RX mode support */
-#define VIRTIO_NET_F_CTRL_VLAN	19	/* Control channel VLAN filtering */
-#define VIRTIO_NET_F_CTRL_RX_EXTRA 20	/* Extra RX mode control support */
-#define VIRTIO_NET_F_GUEST_ANNOUNCE 21	/* Guest can announce device on the
-					 * network */
-#define VIRTIO_NET_F_MQ		22	/* Device supports Receive Flow
-					 * Steering */
-#define VIRTIO_NET_F_CTRL_MAC_ADDR 23	/* Set MAC address */
-
-/* Do we get callbacks when the ring is completely used, even if we've
- * suppressed them? */
-#define VIRTIO_F_NOTIFY_ON_EMPTY	24
-
-/* Can the device handle any descriptor layout? */
-#define VIRTIO_F_ANY_LAYOUT		27
-
-/* We support indirect buffer descriptors */
-#define VIRTIO_RING_F_INDIRECT_DESC	28
-
-#define VIRTIO_F_VERSION_1		32
-#define VIRTIO_F_IOMMU_PLATFORM	33
-#define VIRTIO_F_RING_PACKED		34
-
-/*
- * Some VirtIO feature bits (currently bits 28 through 31) are
- * reserved for the transport being used (eg. virtio_ring), the
- * rest are per-device feature bits.
- */
-#define VIRTIO_TRANSPORT_F_START 28
-#define VIRTIO_TRANSPORT_F_END   34
-
-/*
- * Inorder feature indicates that all buffers are used by the device
- * in the same order in which they have been made available.
- */
-#define VIRTIO_F_IN_ORDER 35
-
-/*
- * This feature indicates that memory accesses by the driver and the device
- * are ordered in a way described by the platform.
- */
-#define VIRTIO_F_ORDER_PLATFORM 36
-
-/*
- * This feature indicates that the driver passes extra data (besides
- * identifying the virtqueue) in its device notifications.
- */
-#define VIRTIO_F_NOTIFICATION_DATA 38
-
-/* Device set linkspeed and duplex */
-#define VIRTIO_NET_F_SPEED_DUPLEX 63
-
-/* The Guest publishes the used index for which it expects an interrupt
- * at the end of the avail ring. Host should ignore the avail->flags field. */
-/* The Host publishes the avail index for which it expects a kick
- * at the end of the used ring. Guest should ignore the used->flags field. */
-#define VIRTIO_RING_F_EVENT_IDX		29
-
-#define VIRTIO_NET_S_LINK_UP	1	/* Link is up */
-#define VIRTIO_NET_S_ANNOUNCE	2	/* Announcement is needed */
-
 /*
  * Maximum number of virtqueues per device.
  */
@@ -270,17 +193,6 @@ enum virtio_msix_status {
 	VIRTIO_MSIX_ENABLED = 2
 };
 
-static inline int
-vtpci_with_feature(struct virtio_hw *hw, uint64_t bit)
-{
-	return (hw->guest_features & (1ULL << bit)) != 0;
-}
-
-static inline int
-vtpci_packed_queue(struct virtio_hw *hw)
-{
-	return vtpci_with_feature(hw, VIRTIO_F_RING_PACKED);
-}
 
 /*
  * Function declaration from virtio_pci.c
@@ -293,8 +205,6 @@ void vtpci_reinit_complete(struct virtio_hw *);
 uint8_t vtpci_get_status(struct virtio_hw *);
 void vtpci_set_status(struct virtio_hw *, uint8_t);
 
-uint64_t vtpci_negotiate_features(struct virtio_hw *, uint64_t);
-
 void vtpci_write_dev_config(struct virtio_hw *, size_t, const void *, int);
 
 void vtpci_read_dev_config(struct virtio_hw *, size_t, void *, int);
diff --git a/drivers/net/virtio/virtio_ring.h b/drivers/net/virtio/virtio_ring.h
index 0f6574f684..17a56b0a73 100644
--- a/drivers/net/virtio/virtio_ring.h
+++ b/drivers/net/virtio/virtio_ring.h
@@ -133,7 +133,7 @@ vring_size(struct virtio_hw *hw, unsigned int num, unsigned long align)
 {
 	size_t size;
 
-	if (vtpci_packed_queue(hw)) {
+	if (virtio_with_packed_queue(hw)) {
 		size = num * sizeof(struct vring_packed_desc);
 		size += sizeof(struct vring_packed_desc_event);
 		size = RTE_ALIGN_CEIL(size, align);
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index 6875c8fbee..728085e99b 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -685,14 +685,14 @@ virtio_dev_rx_queue_setup_finish(struct rte_eth_dev *dev, uint16_t queue_idx)
 	struct rte_mbuf *m;
 	uint16_t desc_idx;
 	int error, nbufs, i;
-	bool in_order = vtpci_with_feature(hw, VIRTIO_F_IN_ORDER);
+	bool in_order = virtio_with_feature(hw, VIRTIO_F_IN_ORDER);
 
 	PMD_INIT_FUNC_TRACE();
 
 	/* Allocate blank mbufs for the each rx descriptor */
 	nbufs = 0;
 
-	if (hw->use_vec_rx && !vtpci_packed_queue(hw)) {
+	if (hw->use_vec_rx && !virtio_with_packed_queue(hw)) {
 		for (desc_idx = 0; desc_idx < vq->vq_nentries;
 		     desc_idx++) {
 			vq->vq_split.ring.avail->ring[desc_idx] = desc_idx;
@@ -710,12 +710,12 @@ virtio_dev_rx_queue_setup_finish(struct rte_eth_dev *dev, uint16_t queue_idx)
 			&rxvq->fake_mbuf;
 	}
 
-	if (hw->use_vec_rx && !vtpci_packed_queue(hw)) {
+	if (hw->use_vec_rx && !virtio_with_packed_queue(hw)) {
 		while (vq->vq_free_cnt >= RTE_VIRTIO_VPMD_RX_REARM_THRESH) {
 			virtio_rxq_rearm_vec(rxvq);
 			nbufs += RTE_VIRTIO_VPMD_RX_REARM_THRESH;
 		}
-	} else if (!vtpci_packed_queue(vq->hw) && in_order) {
+	} else if (!virtio_with_packed_queue(vq->hw) && in_order) {
 		if ((!virtqueue_full(vq))) {
 			uint16_t free_cnt = vq->vq_free_cnt;
 			struct rte_mbuf *pkts[free_cnt];
@@ -741,7 +741,7 @@ virtio_dev_rx_queue_setup_finish(struct rte_eth_dev *dev, uint16_t queue_idx)
 				break;
 
 			/* Enqueue allocated buffers */
-			if (vtpci_packed_queue(vq->hw))
+			if (virtio_with_packed_queue(vq->hw))
 				error = virtqueue_enqueue_recv_refill_packed(vq,
 						&m, 1);
 			else
@@ -754,7 +754,7 @@ virtio_dev_rx_queue_setup_finish(struct rte_eth_dev *dev, uint16_t queue_idx)
 			nbufs++;
 		}
 
-		if (!vtpci_packed_queue(vq->hw))
+		if (!virtio_with_packed_queue(vq->hw))
 			vq_update_avail_idx(vq);
 	}
 
@@ -829,8 +829,8 @@ virtio_dev_tx_queue_setup_finish(struct rte_eth_dev *dev,
 
 	PMD_INIT_FUNC_TRACE();
 
-	if (!vtpci_packed_queue(hw)) {
-		if (vtpci_with_feature(hw, VIRTIO_F_IN_ORDER))
+	if (!virtio_with_packed_queue(hw)) {
+		if (virtio_with_feature(hw, VIRTIO_F_IN_ORDER))
 			vq->vq_split.ring.desc[vq->vq_nentries - 1].next = 0;
 	}
 
@@ -847,7 +847,7 @@ virtio_discard_rxbuf(struct virtqueue *vq, struct rte_mbuf *m)
 	 * Requeue the discarded mbuf. This should always be
 	 * successful since it was just dequeued.
 	 */
-	if (vtpci_packed_queue(vq->hw))
+	if (virtio_with_packed_queue(vq->hw))
 		error = virtqueue_enqueue_recv_refill_packed(vq, &m, 1);
 	else
 		error = virtqueue_enqueue_recv_refill(vq, &m, 1);
@@ -1209,7 +1209,7 @@ virtio_recv_pkts_inorder(void *rx_queue,
 			 ((char *)rxm->buf_addr + RTE_PKTMBUF_HEADROOM
 			 - hdr_size);
 
-		if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
+		if (virtio_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
 			seg_num = header->num_buffers;
 			if (seg_num == 0)
 				seg_num = 1;
@@ -1735,7 +1735,7 @@ virtio_xmit_pkts_packed(void *tx_queue, struct rte_mbuf **tx_pkts,
 	struct virtio_hw *hw = vq->hw;
 	uint16_t hdr_size = hw->vtnet_hdr_size;
 	uint16_t nb_tx = 0;
-	bool in_order = vtpci_with_feature(hw, VIRTIO_F_IN_ORDER);
+	bool in_order = virtio_with_feature(hw, VIRTIO_F_IN_ORDER);
 
 	if (unlikely(hw->started == 0 && tx_pkts != hw->inject_pkts))
 		return nb_tx;
@@ -1754,8 +1754,8 @@ virtio_xmit_pkts_packed(void *tx_queue, struct rte_mbuf **tx_pkts,
 		int can_push = 0, use_indirect = 0, slots, need;
 
 		/* optimize ring usage */
-		if ((vtpci_with_feature(hw, VIRTIO_F_ANY_LAYOUT) ||
-		      vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) &&
+		if ((virtio_with_feature(hw, VIRTIO_F_ANY_LAYOUT) ||
+		      virtio_with_feature(hw, VIRTIO_F_VERSION_1)) &&
 		    rte_mbuf_refcnt_read(txm) == 1 &&
 		    RTE_MBUF_DIRECT(txm) &&
 		    txm->nb_segs == 1 &&
@@ -1763,7 +1763,7 @@ virtio_xmit_pkts_packed(void *tx_queue, struct rte_mbuf **tx_pkts,
 		    rte_is_aligned(rte_pktmbuf_mtod(txm, char *),
 			   __alignof__(struct virtio_net_hdr_mrg_rxbuf)))
 			can_push = 1;
-		else if (vtpci_with_feature(hw, VIRTIO_RING_F_INDIRECT_DESC) &&
+		else if (virtio_with_feature(hw, VIRTIO_RING_F_INDIRECT_DESC) &&
 			 txm->nb_segs < VIRTIO_MAX_TX_INDIRECT)
 			use_indirect = 1;
 		/* How many main ring entries are needed to this Tx?
@@ -1835,8 +1835,8 @@ virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 		int can_push = 0, use_indirect = 0, slots, need;
 
 		/* optimize ring usage */
-		if ((vtpci_with_feature(hw, VIRTIO_F_ANY_LAYOUT) ||
-		      vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) &&
+		if ((virtio_with_feature(hw, VIRTIO_F_ANY_LAYOUT) ||
+		      virtio_with_feature(hw, VIRTIO_F_VERSION_1)) &&
 		    rte_mbuf_refcnt_read(txm) == 1 &&
 		    RTE_MBUF_DIRECT(txm) &&
 		    txm->nb_segs == 1 &&
@@ -1844,7 +1844,7 @@ virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 		    rte_is_aligned(rte_pktmbuf_mtod(txm, char *),
 				   __alignof__(struct virtio_net_hdr_mrg_rxbuf)))
 			can_push = 1;
-		else if (vtpci_with_feature(hw, VIRTIO_RING_F_INDIRECT_DESC) &&
+		else if (virtio_with_feature(hw, VIRTIO_RING_F_INDIRECT_DESC) &&
 			 txm->nb_segs < VIRTIO_MAX_TX_INDIRECT)
 			use_indirect = 1;
 
@@ -1937,8 +1937,8 @@ virtio_xmit_pkts_inorder(void *tx_queue,
 		int slots;
 
 		/* optimize ring usage */
-		if ((vtpci_with_feature(hw, VIRTIO_F_ANY_LAYOUT) ||
-		     vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) &&
+		if ((virtio_with_feature(hw, VIRTIO_F_ANY_LAYOUT) ||
+		     virtio_with_feature(hw, VIRTIO_F_VERSION_1)) &&
 		     rte_mbuf_refcnt_read(txm) == 1 &&
 		     RTE_MBUF_DIRECT(txm) &&
 		     txm->nb_segs == 1 &&
diff --git a/drivers/net/virtio/virtio_rxtx_packed.h b/drivers/net/virtio/virtio_rxtx_packed.h
index c0fad41c3d..8d99caeead 100644
--- a/drivers/net/virtio/virtio_rxtx_packed.h
+++ b/drivers/net/virtio/virtio_rxtx_packed.h
@@ -111,12 +111,12 @@ virtqueue_enqueue_single_packed_vec(struct virtnet_tx *txvq,
 	int16_t need;
 
 	/* optimize ring usage */
-	if ((vtpci_with_feature(hw, VIRTIO_F_ANY_LAYOUT) ||
-	     vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) &&
+	if ((virtio_with_feature(hw, VIRTIO_F_ANY_LAYOUT) ||
+	     virtio_with_feature(hw, VIRTIO_F_VERSION_1)) &&
 	     rte_mbuf_refcnt_read(txm) == 1 && RTE_MBUF_DIRECT(txm) &&
 	     txm->nb_segs == 1 && rte_pktmbuf_headroom(txm) >= hdr_size)
 		can_push = 1;
-	else if (vtpci_with_feature(hw, VIRTIO_RING_F_INDIRECT_DESC) &&
+	else if (virtio_with_feature(hw, VIRTIO_RING_F_INDIRECT_DESC) &&
 		 txm->nb_segs < VIRTIO_MAX_TX_INDIRECT)
 		use_indirect = 1;
 
diff --git a/drivers/net/virtio/virtio_user/vhost_kernel_tap.c b/drivers/net/virtio/virtio_user/vhost_kernel_tap.c
index 79b8446f8e..eade702c5c 100644
--- a/drivers/net/virtio/virtio_user/vhost_kernel_tap.c
+++ b/drivers/net/virtio/virtio_user/vhost_kernel_tap.c
@@ -16,7 +16,7 @@
 
 #include "vhost_kernel_tap.h"
 #include "../virtio_logs.h"
-#include "../virtio_pci.h"
+#include "../virtio.h"
 
 int
 vhost_kernel_tap_set_offload(int fd, uint64_t features)
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index 6597c16539..8e609333c6 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -122,7 +122,7 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev)
 	dev->features &= dev->device_features;
 
 	/* For packed ring, resetting queues is required in reconnection. */
-	if (vtpci_packed_queue(hw) &&
+	if (virtio_with_packed_queue(hw) &&
 	   (old_status & VIRTIO_CONFIG_STATUS_DRIVER_OK)) {
 		PMD_INIT_LOG(NOTICE, "Packets on the fly will be dropped"
 				" when packed ring reconnecting.");
@@ -423,7 +423,7 @@ virtio_user_setup_queue(struct virtio_hw *hw, struct virtqueue *vq)
 {
 	struct virtio_user_dev *dev = virtio_user_get_dev(hw);
 
-	if (vtpci_packed_queue(hw))
+	if (virtio_with_packed_queue(hw))
 		virtio_user_setup_queue_packed(vq, dev);
 	else
 		virtio_user_setup_queue_split(vq, dev);
@@ -456,7 +456,7 @@ virtio_user_notify_queue(struct virtio_hw *hw, struct virtqueue *vq)
 	struct virtio_user_dev *dev = virtio_user_get_dev(hw);
 
 	if (hw->cvq && (hw->cvq->vq == vq)) {
-		if (vtpci_packed_queue(vq->hw))
+		if (virtio_with_packed_queue(vq->hw))
 			virtio_user_handle_cq_packed(dev, vq->vq_queue_index);
 		else
 			virtio_user_handle_cq(dev, vq->vq_queue_index);
diff --git a/drivers/net/virtio/virtqueue.c b/drivers/net/virtio/virtqueue.c
index 2702e120ee..59a2cb6599 100644
--- a/drivers/net/virtio/virtqueue.c
+++ b/drivers/net/virtio/virtqueue.c
@@ -32,7 +32,7 @@ virtqueue_detach_unused(struct virtqueue *vq)
 	end = (vq->vq_avail_idx + vq->vq_free_cnt) & (vq->vq_nentries - 1);
 
 	for (idx = 0; idx < vq->vq_nentries; idx++) {
-		if (hw->use_vec_rx && !vtpci_packed_queue(hw) &&
+		if (hw->use_vec_rx && !virtio_with_packed_queue(hw) &&
 		    type == VTNET_RQ) {
 			if (start <= end && idx >= start && idx < end)
 				continue;
@@ -137,7 +137,7 @@ virtqueue_rxvq_flush(struct virtqueue *vq)
 {
 	struct virtio_hw *hw = vq->hw;
 
-	if (vtpci_packed_queue(hw))
+	if (virtio_with_packed_queue(hw))
 		virtqueue_rxvq_flush_packed(vq);
 	else
 		virtqueue_rxvq_flush_split(vq);
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index 6293cd2604..f419c0aa99 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -12,7 +12,7 @@
 #include <rte_mempool.h>
 #include <rte_net.h>
 
-#include "virtio_pci.h"
+#include "virtio.h"
 #include "virtio_ring.h"
 #include "virtio_logs.h"
 #include "virtio_rxtx.h"
@@ -385,7 +385,7 @@ virtqueue_disable_intr_split(struct virtqueue *vq)
 static inline void
 virtqueue_disable_intr(struct virtqueue *vq)
 {
-	if (vtpci_packed_queue(vq->hw))
+	if (virtio_with_packed_queue(vq->hw))
 		virtqueue_disable_intr_packed(vq);
 	else
 		virtqueue_disable_intr_split(vq);
@@ -419,7 +419,7 @@ virtqueue_enable_intr_split(struct virtqueue *vq)
 static inline void
 virtqueue_enable_intr(struct virtqueue *vq)
 {
-	if (vtpci_packed_queue(vq->hw))
+	if (virtio_with_packed_queue(vq->hw))
 		virtqueue_enable_intr_packed(vq);
 	else
 		virtqueue_enable_intr_split(vq);
@@ -572,7 +572,7 @@ virtqueue_notify(struct virtqueue *vq)
 	used_idx = __atomic_load_n(&(vq)->vq_split.ring.used->idx, \
 				   __ATOMIC_RELAXED); \
 	nused = (uint16_t)(used_idx - (vq)->vq_used_cons_idx); \
-	if (vtpci_packed_queue((vq)->hw)) { \
+	if (virtio_with_packed_queue((vq)->hw)) { \
 		PMD_INIT_LOG(DEBUG, \
 		"VQ: - size=%d; free=%d; used_cons_idx=%d; avail_idx=%d;" \
 		" cached_flags=0x%x; used_wrap_counter=%d", \
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 20/44] net/virtio: move virtqueue defines in generic header
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (18 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 19/44] net/virtio: move features definition to generic header Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 21/44] net/virtio: move config definitions to " Maxime Coquelin
                   ` (23 subsequent siblings)
  43 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch moves the virtqueues defines from PCI header
to the generic one.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
---
 drivers/net/virtio/virtio.h                    | 18 ++++++++++++++++++
 drivers/net/virtio/virtio_ethdev.h             |  4 +++-
 drivers/net/virtio/virtio_pci.h                | 17 -----------------
 .../net/virtio/virtio_user/virtio_user_dev.h   |  3 ++-
 4 files changed, 23 insertions(+), 19 deletions(-)

diff --git a/drivers/net/virtio/virtio.h b/drivers/net/virtio/virtio.h
index 572be2006d..cfd2913420 100644
--- a/drivers/net/virtio/virtio.h
+++ b/drivers/net/virtio/virtio.h
@@ -88,6 +88,24 @@
 #define VIRTIO_NET_S_LINK_UP	1	/* Link is up */
 #define VIRTIO_NET_S_ANNOUNCE	2	/* Announcement is needed */
 
+/*
+ * Each virtqueue indirect descriptor list must be physically contiguous.
+ * To allow us to malloc(9) each list individually, limit the number
+ * supported to what will fit in one page. With 4KB pages, this is a limit
+ * of 256 descriptors. If there is ever a need for more, we can switch to
+ * contigmalloc(9) for the larger allocations, similar to what
+ * bus_dmamem_alloc(9) does.
+ *
+ * Note the sizeof(struct vring_desc) is 16 bytes.
+ */
+#define VIRTIO_MAX_INDIRECT ((int)(PAGE_SIZE / 16))
+
+/*
+ * Maximum number of virtqueues per device.
+ */
+#define VIRTIO_MAX_VIRTQUEUE_PAIRS 8
+#define VIRTIO_MAX_VIRTQUEUES (VIRTIO_MAX_VIRTQUEUE_PAIRS * 2 + 1)
+
 struct virtio_hw {
 	struct virtqueue **vqs;
 	uint64_t guest_features;
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index 13395937c8..d82856df9b 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -7,7 +7,9 @@
 
 #include <stdint.h>
 
-#include "virtio_pci.h"
+#include <rte_ethdev_driver.h>
+
+#include "virtio.h"
 
 #ifndef PAGE_SIZE
 #define PAGE_SIZE 4096
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 3d93e74f36..2c27c906fb 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -67,23 +67,6 @@ struct virtnet_ctl;
 #define VIRTIO_CONFIG_STATUS_DEV_NEED_RESET	0x40
 #define VIRTIO_CONFIG_STATUS_FAILED		0x80
 
-/*
- * Each virtqueue indirect descriptor list must be physically contiguous.
- * To allow us to malloc(9) each list individually, limit the number
- * supported to what will fit in one page. With 4KB pages, this is a limit
- * of 256 descriptors. If there is ever a need for more, we can switch to
- * contigmalloc(9) for the larger allocations, similar to what
- * bus_dmamem_alloc(9) does.
- *
- * Note the sizeof(struct vring_desc) is 16 bytes.
- */
-#define VIRTIO_MAX_INDIRECT ((int) (PAGE_SIZE / 16))
-
-/*
- * Maximum number of virtqueues per device.
- */
-#define VIRTIO_MAX_VIRTQUEUE_PAIRS 8
-#define VIRTIO_MAX_VIRTQUEUES (VIRTIO_MAX_VIRTQUEUE_PAIRS * 2 + 1)
 
 /* Common configuration */
 #define VIRTIO_PCI_CAP_COMMON_CFG	1
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h b/drivers/net/virtio/virtio_user/virtio_user_dev.h
index b3776cc7a0..ab62463a5b 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
@@ -7,7 +7,8 @@
 
 #include <limits.h>
 #include <stdbool.h>
-#include "../virtio_pci.h"
+
+#include "../virtio.h"
 #include "../virtio_ring.h"
 
 enum virtio_user_backend_type {
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 21/44] net/virtio: move config definitions to generic header
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (19 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 20/44] net/virtio: move virtqueue defines in " Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 22/44] net/virtio: make interrupt handling more generic Maxime Coquelin
                   ` (22 subsequent siblings)
  43 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch moves config and status definitions from the PCI
header to the generic one.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
---
 drivers/net/virtio/virtio.c             | 43 +++++++++++++++++++
 drivers/net/virtio/virtio.h             | 50 ++++++++++++++++++++++
 drivers/net/virtio/virtio_ethdev.c      | 36 ++++++++--------
 drivers/net/virtio/virtio_pci.c         | 44 --------------------
 drivers/net/virtio/virtio_pci.h         | 55 -------------------------
 drivers/net/virtio/virtio_user_ethdev.c | 10 ++---
 6 files changed, 116 insertions(+), 122 deletions(-)

diff --git a/drivers/net/virtio/virtio.c b/drivers/net/virtio/virtio.c
index d8d6bf7add..ba3203e68b 100644
--- a/drivers/net/virtio/virtio.c
+++ b/drivers/net/virtio/virtio.c
@@ -20,3 +20,46 @@ virtio_negotiate_features(struct virtio_hw *hw, uint64_t host_features)
 	return features;
 }
 
+
+void
+virtio_read_dev_config(struct virtio_hw *hw, size_t offset,
+		      void *dst, int length)
+{
+	VIRTIO_OPS(hw)->read_dev_cfg(hw, offset, dst, length);
+}
+
+void
+virtio_write_dev_config(struct virtio_hw *hw, size_t offset,
+		       const void *src, int length)
+{
+	VIRTIO_OPS(hw)->write_dev_cfg(hw, offset, src, length);
+}
+
+void
+virtio_reset(struct virtio_hw *hw)
+{
+	VIRTIO_OPS(hw)->set_status(hw, VIRTIO_CONFIG_STATUS_RESET);
+	/* flush status write */
+	VIRTIO_OPS(hw)->get_status(hw);
+}
+
+void
+virtio_reinit_complete(struct virtio_hw *hw)
+{
+	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER_OK);
+}
+
+void
+virtio_set_status(struct virtio_hw *hw, uint8_t status)
+{
+	if (status != VIRTIO_CONFIG_STATUS_RESET)
+		status |= VIRTIO_OPS(hw)->get_status(hw);
+
+	VIRTIO_OPS(hw)->set_status(hw, status);
+}
+
+uint8_t
+virtio_get_status(struct virtio_hw *hw)
+{
+	return VIRTIO_OPS(hw)->get_status(hw);
+}
diff --git a/drivers/net/virtio/virtio.h b/drivers/net/virtio/virtio.h
index cfd2913420..81eaff23ce 100644
--- a/drivers/net/virtio/virtio.h
+++ b/drivers/net/virtio/virtio.h
@@ -106,6 +106,50 @@
 #define VIRTIO_MAX_VIRTQUEUE_PAIRS 8
 #define VIRTIO_MAX_VIRTQUEUES (VIRTIO_MAX_VIRTQUEUE_PAIRS * 2 + 1)
 
+/* VirtIO device IDs. */
+#define VIRTIO_ID_NETWORK  0x01
+#define VIRTIO_ID_BLOCK    0x02
+#define VIRTIO_ID_CONSOLE  0x03
+#define VIRTIO_ID_ENTROPY  0x04
+#define VIRTIO_ID_BALLOON  0x05
+#define VIRTIO_ID_IOMEMORY 0x06
+#define VIRTIO_ID_9P       0x09
+
+/* Status byte for guest to report progress. */
+#define VIRTIO_CONFIG_STATUS_RESET		0x00
+#define VIRTIO_CONFIG_STATUS_ACK		0x01
+#define VIRTIO_CONFIG_STATUS_DRIVER		0x02
+#define VIRTIO_CONFIG_STATUS_DRIVER_OK		0x04
+#define VIRTIO_CONFIG_STATUS_FEATURES_OK	0x08
+#define VIRTIO_CONFIG_STATUS_DEV_NEED_RESET	0x40
+#define VIRTIO_CONFIG_STATUS_FAILED		0x80
+
+/*
+ * This structure is just a reference to read net device specific
+ * config space; it is just a shadow structure.
+ *
+ */
+struct virtio_net_config {
+	/* The config defining mac address (if VIRTIO_NET_F_MAC) */
+	uint8_t    mac[RTE_ETHER_ADDR_LEN];
+	/* See VIRTIO_NET_F_STATUS and VIRTIO_NET_S_* above */
+	uint16_t   status;
+	uint16_t   max_virtqueue_pairs;
+	uint16_t   mtu;
+	/*
+	 * speed, in units of 1Mb. All values 0 to INT_MAX are legal.
+	 * Any other value stands for unknown.
+	 */
+	uint32_t speed;
+	/*
+	 * 0x00 - half duplex
+	 * 0x01 - full duplex
+	 * Any other value stands for unknown.
+	 */
+	uint8_t duplex;
+
+} __rte_packed;
+
 struct virtio_hw {
 	struct virtqueue **vqs;
 	uint64_t guest_features;
@@ -182,5 +226,11 @@ virtio_with_packed_queue(struct virtio_hw *hw)
 }
 
 uint64_t virtio_negotiate_features(struct virtio_hw *hw, uint64_t host_features);
+uint8_t virtio_get_status(struct virtio_hw *hw);
+void virtio_set_status(struct virtio_hw *hw, uint8_t status);
+void virtio_write_dev_config(struct virtio_hw *hw, size_t offset, const void *src, int length);
+void virtio_read_dev_config(struct virtio_hw *hw, size_t offset, void *dst, int length);
+void virtio_reset(struct virtio_hw *hw);
+void virtio_reinit_complete(struct virtio_hw *hw);
 
 #endif /* _VIRTIO_H_ */
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index ea81340997..aacc335a85 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -714,7 +714,7 @@ virtio_dev_close(struct rte_eth_dev *dev)
 		dev->intr_handle->intr_vec = NULL;
 	}
 
-	vtpci_reset(hw);
+	virtio_reset(hw);
 	virtio_dev_free_mbufs(dev);
 	virtio_free_queues(hw);
 
@@ -1096,7 +1096,7 @@ virtio_dev_stats_reset(struct rte_eth_dev *dev)
 static void
 virtio_set_hwaddr(struct virtio_hw *hw)
 {
-	vtpci_write_dev_config(hw,
+	virtio_write_dev_config(hw,
 			offsetof(struct virtio_net_config, mac),
 			&hw->mac_addr, RTE_ETHER_ADDR_LEN);
 }
@@ -1105,7 +1105,7 @@ static void
 virtio_get_hwaddr(struct virtio_hw *hw)
 {
 	if (virtio_with_feature(hw, VIRTIO_NET_F_MAC)) {
-		vtpci_read_dev_config(hw,
+		virtio_read_dev_config(hw,
 			offsetof(struct virtio_net_config, mac),
 			&hw->mac_addr, RTE_ETHER_ADDR_LEN);
 	} else {
@@ -1313,7 +1313,7 @@ virtio_ethdev_negotiate_features(struct virtio_hw *hw, uint64_t req_features)
 	if (host_features & req_features & (1ULL << VIRTIO_NET_F_MTU)) {
 		struct virtio_net_config config;
 
-		vtpci_read_dev_config(hw,
+		virtio_read_dev_config(hw,
 			offsetof(struct virtio_net_config, mtu),
 			&config.mtu, sizeof(config.mtu));
 
@@ -1334,9 +1334,9 @@ virtio_ethdev_negotiate_features(struct virtio_hw *hw, uint64_t req_features)
 		return -1;
 
 	if (virtio_with_feature(hw, VIRTIO_F_VERSION_1)) {
-		vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_FEATURES_OK);
+		virtio_set_status(hw, VIRTIO_CONFIG_STATUS_FEATURES_OK);
 
-		if (!(vtpci_get_status(hw) & VIRTIO_CONFIG_STATUS_FEATURES_OK)) {
+		if (!(virtio_get_status(hw) & VIRTIO_CONFIG_STATUS_FEATURES_OK)) {
 			PMD_INIT_LOG(ERR, "Failed to set FEATURES_OK status!");
 			return -1;
 		}
@@ -1468,7 +1468,7 @@ virtio_interrupt_handler(void *param)
 						     NULL);
 
 		if (virtio_with_feature(hw, VIRTIO_NET_F_STATUS)) {
-			vtpci_read_dev_config(hw,
+			virtio_read_dev_config(hw,
 				offsetof(struct virtio_net_config, status),
 				&status, sizeof(status));
 			if (status & VIRTIO_NET_S_ANNOUNCE) {
@@ -1650,7 +1650,7 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 	int ret;
 
 	/* Reset the device although not necessary at startup */
-	vtpci_reset(hw);
+	virtio_reset(hw);
 
 	if (hw->vqs) {
 		virtio_dev_free_mbufs(eth_dev);
@@ -1658,10 +1658,10 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 	}
 
 	/* Tell the host we've noticed this device. */
-	vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_ACK);
+	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_ACK);
 
 	/* Tell the host we've known how to drive the device. */
-	vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);
+	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);
 	if (virtio_ethdev_negotiate_features(hw, req_features) < 0)
 		return -1;
 
@@ -1696,10 +1696,10 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 	if (hw->speed == ETH_SPEED_NUM_UNKNOWN) {
 		if (virtio_with_feature(hw, VIRTIO_NET_F_SPEED_DUPLEX)) {
 			config = &local_config;
-			vtpci_read_dev_config(hw,
+			virtio_read_dev_config(hw,
 				offsetof(struct virtio_net_config, speed),
 				&config->speed, sizeof(config->speed));
-			vtpci_read_dev_config(hw,
+			virtio_read_dev_config(hw,
 				offsetof(struct virtio_net_config, duplex),
 				&config->duplex, sizeof(config->duplex));
 			hw->speed = config->speed;
@@ -1713,12 +1713,12 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 	if (virtio_with_feature(hw, VIRTIO_NET_F_CTRL_VQ)) {
 		config = &local_config;
 
-		vtpci_read_dev_config(hw,
+		virtio_read_dev_config(hw,
 			offsetof(struct virtio_net_config, mac),
 			&config->mac, sizeof(config->mac));
 
 		if (virtio_with_feature(hw, VIRTIO_NET_F_STATUS)) {
-			vtpci_read_dev_config(hw,
+			virtio_read_dev_config(hw,
 				offsetof(struct virtio_net_config, status),
 				&config->status, sizeof(config->status));
 		} else {
@@ -1728,7 +1728,7 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 		}
 
 		if (virtio_with_feature(hw, VIRTIO_NET_F_MQ)) {
-			vtpci_read_dev_config(hw,
+			virtio_read_dev_config(hw,
 				offsetof(struct virtio_net_config, max_virtqueue_pairs),
 				&config->max_virtqueue_pairs,
 				sizeof(config->max_virtqueue_pairs));
@@ -1741,7 +1741,7 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 		hw->max_queue_pairs = config->max_virtqueue_pairs;
 
 		if (virtio_with_feature(hw, VIRTIO_NET_F_MTU)) {
-			vtpci_read_dev_config(hw,
+			virtio_read_dev_config(hw,
 				offsetof(struct virtio_net_config, mtu),
 				&config->mtu,
 				sizeof(config->mtu));
@@ -1793,7 +1793,7 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 		}
 	}
 
-	vtpci_reinit_complete(hw);
+	virtio_reinit_complete(hw);
 
 	return 0;
 }
@@ -2374,7 +2374,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 		link.link_speed = ETH_SPEED_NUM_NONE;
 	} else if (virtio_with_feature(hw, VIRTIO_NET_F_STATUS)) {
 		PMD_INIT_LOG(DEBUG, "Get link status from hw");
-		vtpci_read_dev_config(hw,
+		virtio_read_dev_config(hw,
 				offsetof(struct virtio_net_config, status),
 				&status, sizeof(status));
 		if ((status & VIRTIO_NET_S_LINK_UP) == 0) {
diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index 760d404a5a..b5748a3441 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -603,50 +603,6 @@ const struct virtio_ops modern_ops = {
 	.dev_close	= modern_dev_close,
 };
 
-
-void
-vtpci_read_dev_config(struct virtio_hw *hw, size_t offset,
-		      void *dst, int length)
-{
-	VIRTIO_OPS(hw)->read_dev_cfg(hw, offset, dst, length);
-}
-
-void
-vtpci_write_dev_config(struct virtio_hw *hw, size_t offset,
-		       const void *src, int length)
-{
-	VIRTIO_OPS(hw)->write_dev_cfg(hw, offset, src, length);
-}
-
-void
-vtpci_reset(struct virtio_hw *hw)
-{
-	VIRTIO_OPS(hw)->set_status(hw, VIRTIO_CONFIG_STATUS_RESET);
-	/* flush status write */
-	VIRTIO_OPS(hw)->get_status(hw);
-}
-
-void
-vtpci_reinit_complete(struct virtio_hw *hw)
-{
-	vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER_OK);
-}
-
-void
-vtpci_set_status(struct virtio_hw *hw, uint8_t status)
-{
-	if (status != VIRTIO_CONFIG_STATUS_RESET)
-		status |= VIRTIO_OPS(hw)->get_status(hw);
-
-	VIRTIO_OPS(hw)->set_status(hw, status);
-}
-
-uint8_t
-vtpci_get_status(struct virtio_hw *hw)
-{
-	return VIRTIO_OPS(hw)->get_status(hw);
-}
-
 uint8_t
 vtpci_isr(struct virtio_hw *hw)
 {
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 2c27c906fb..cc1a3a37fd 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -49,25 +49,6 @@ struct virtnet_ctl;
 /* Vector value used to disable MSI for queue. */
 #define VIRTIO_MSI_NO_VECTOR 0xFFFF
 
-/* VirtIO device IDs. */
-#define VIRTIO_ID_NETWORK  0x01
-#define VIRTIO_ID_BLOCK    0x02
-#define VIRTIO_ID_CONSOLE  0x03
-#define VIRTIO_ID_ENTROPY  0x04
-#define VIRTIO_ID_BALLOON  0x05
-#define VIRTIO_ID_IOMEMORY 0x06
-#define VIRTIO_ID_9P       0x09
-
-/* Status byte for guest to report progress. */
-#define VIRTIO_CONFIG_STATUS_RESET		0x00
-#define VIRTIO_CONFIG_STATUS_ACK		0x01
-#define VIRTIO_CONFIG_STATUS_DRIVER		0x02
-#define VIRTIO_CONFIG_STATUS_DRIVER_OK		0x04
-#define VIRTIO_CONFIG_STATUS_FEATURES_OK	0x08
-#define VIRTIO_CONFIG_STATUS_DEV_NEED_RESET	0x40
-#define VIRTIO_CONFIG_STATUS_FAILED		0x80
-
-
 /* Common configuration */
 #define VIRTIO_PCI_CAP_COMMON_CFG	1
 /* Notifications */
@@ -135,32 +116,6 @@ struct virtio_pci_dev {
 
 #define virtio_pci_get_dev(hwp) container_of(hwp, struct virtio_pci_dev, hw)
 
-/*
- * This structure is just a reference to read
- * net device specific config space; it just a chodu structure
- *
- */
-struct virtio_net_config {
-	/* The config defining mac address (if VIRTIO_NET_F_MAC) */
-	uint8_t    mac[RTE_ETHER_ADDR_LEN];
-	/* See VIRTIO_NET_F_STATUS and VIRTIO_NET_S_* above */
-	uint16_t   status;
-	uint16_t   max_virtqueue_pairs;
-	uint16_t   mtu;
-	/*
-	 * speed, in units of 1Mb. All values 0 to INT_MAX are legal.
-	 * Any other value stands for unknown.
-	 */
-	uint32_t speed;
-	/*
-	 * 0x00 - half duplex
-	 * 0x01 - full duplex
-	 * Any other value stands for unknown.
-	 */
-	uint8_t duplex;
-
-} __rte_packed;
-
 /*
  * How many bits to shift physical queue address written to QUEUE_PFN.
  * 12 is historical, and due to x86 page size.
@@ -181,16 +136,6 @@ enum virtio_msix_status {
  * Function declaration from virtio_pci.c
  */
 int vtpci_init(struct rte_pci_device *pci_dev, struct virtio_pci_dev *dev);
-void vtpci_reset(struct virtio_hw *);
-
-void vtpci_reinit_complete(struct virtio_hw *);
-
-uint8_t vtpci_get_status(struct virtio_hw *);
-void vtpci_set_status(struct virtio_hw *, uint8_t);
-
-void vtpci_write_dev_config(struct virtio_hw *, size_t, const void *, int);
-
-void vtpci_read_dev_config(struct virtio_hw *, size_t, void *, int);
 
 uint8_t vtpci_isr(struct virtio_hw *);
 
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index 8e609333c6..6e59fe4b58 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -79,11 +79,11 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev)
 	dev->vhostfd = connectfd;
 	old_status = dev->status;
 
-	vtpci_reset(hw);
+	virtio_reset(hw);
 
-	vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_ACK);
+	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_ACK);
 
-	vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);
+	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);
 
 	if (dev->ops->send_request(dev, VHOST_USER_GET_FEATURES,
 				   &dev->device_features) < 0) {
@@ -129,10 +129,10 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev)
 		virtio_user_reset_queues_packed(eth_dev);
 	}
 
-	vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_FEATURES_OK);
+	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_FEATURES_OK);
 
 	/* Start the device */
-	vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER_OK);
+	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER_OK);
 	if (!dev->started)
 		return -1;
 
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 22/44] net/virtio: make interrupt handling more generic
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (20 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 21/44] net/virtio: move config definitions to " Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 23/44] net/virtio: move vring alignment to generic header Maxime Coquelin
                   ` (21 subsequent siblings)
  43 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch aims at isolating MSIX notion into PCI
layer.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: David Marchand <david.marchand@redhat.com>
---
 drivers/net/virtio/virtio.c             |  6 ++++
 drivers/net/virtio/virtio.h             | 11 +++++--
 drivers/net/virtio/virtio_ethdev.c      |  7 ++---
 drivers/net/virtio/virtio_pci.c         | 41 ++++++++++++-------------
 drivers/net/virtio/virtio_pci.h         | 24 +++++----------
 drivers/net/virtio/virtio_user_ethdev.c |  9 ++----
 6 files changed, 48 insertions(+), 50 deletions(-)

diff --git a/drivers/net/virtio/virtio.c b/drivers/net/virtio/virtio.c
index ba3203e68b..7e1e77797f 100644
--- a/drivers/net/virtio/virtio.c
+++ b/drivers/net/virtio/virtio.c
@@ -63,3 +63,9 @@ virtio_get_status(struct virtio_hw *hw)
 {
 	return VIRTIO_OPS(hw)->get_status(hw);
 }
+
+uint8_t
+virtio_get_isr(struct virtio_hw *hw)
+{
+	return VIRTIO_OPS(hw)->get_isr(hw);
+}
diff --git a/drivers/net/virtio/virtio.h b/drivers/net/virtio/virtio.h
index 81eaff23ce..b2b96d9520 100644
--- a/drivers/net/virtio/virtio.h
+++ b/drivers/net/virtio/virtio.h
@@ -124,6 +124,13 @@
 #define VIRTIO_CONFIG_STATUS_DEV_NEED_RESET	0x40
 #define VIRTIO_CONFIG_STATUS_FAILED		0x80
 
+/* The bit of the ISR which indicates a device has an interrupt. */
+#define VIRTIO_ISR_INTR   0x1
+/* The bit of the ISR which indicates a device configuration change. */
+#define VIRTIO_ISR_CONFIG 0x2
+/* Vector value used to disable MSI for queue. */
+#define VIRTIO_MSI_NO_VECTOR 0xFFFF
+
 /*
  * This structure is just a reference to read net device specific
  * config space; it is just a shadow structure.
@@ -168,7 +175,7 @@ struct virtio_hw {
 	uint8_t mac_addr[RTE_ETHER_ADDR_LEN];
 	uint32_t speed;  /* link speed in MB */
 	uint8_t duplex;
-	uint8_t use_msix;
+	uint8_t intr_lsc;
 	uint16_t max_mtu;
 	/*
 	 * App management thread and virtio interrupt handler thread
@@ -232,5 +239,5 @@ void virtio_write_dev_config(struct virtio_hw *hw, size_t offset, const void *sr
 void virtio_read_dev_config(struct virtio_hw *hw, size_t offset, void *dst, int length);
 void virtio_reset(struct virtio_hw *hw);
 void virtio_reinit_complete(struct virtio_hw *hw);
-
+uint8_t virtio_get_isr(struct virtio_hw *hw);
 #endif /* _VIRTIO_H_ */
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index aacc335a85..e8e7fda099 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1455,13 +1455,13 @@ virtio_interrupt_handler(void *param)
 	uint16_t status;
 
 	/* Read interrupt status which clears interrupt */
-	isr = vtpci_isr(hw);
+	isr = virtio_get_isr(hw);
 	PMD_DRV_LOG(INFO, "interrupt status = %#x", isr);
 
 	if (virtio_intr_unmask(dev) < 0)
 		PMD_DRV_LOG(ERR, "interrupt enable failed");
 
-	if (isr & VIRTIO_PCI_ISR_CONFIG) {
+	if (isr & VIRTIO_ISR_CONFIG) {
 		if (virtio_dev_link_update(dev, 0) == 0)
 			rte_eth_dev_callback_process(dev,
 						     RTE_ETH_EVENT_INTR_LSC,
@@ -1668,8 +1668,7 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 	hw->weak_barriers = !virtio_with_feature(hw, VIRTIO_F_ORDER_PLATFORM);
 
 	/* If host does not support both status and MSI-X then disable LSC */
-	if (virtio_with_feature(hw, VIRTIO_NET_F_STATUS) &&
-	    hw->use_msix != VIRTIO_MSIX_NONE)
+	if (virtio_with_feature(hw, VIRTIO_NET_F_STATUS) && hw->intr_lsc)
 		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
 	else
 		eth_dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC;
diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index b5748a3441..9fe7fc2019 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -28,8 +28,8 @@
  * The remaining space is defined by each driver as the per-driver
  * configuration space.
  */
-#define VIRTIO_PCI_CONFIG(hw) \
-		(((hw)->use_msix == VIRTIO_MSIX_ENABLED) ? 24 : 20)
+#define VIRTIO_PCI_CONFIG(dev) \
+		(((dev)->msix_status == VIRTIO_MSIX_ENABLED) ? 24 : 20)
 
 
 struct virtio_pci_internal {
@@ -121,6 +121,7 @@ static void
 legacy_read_dev_config(struct virtio_hw *hw, size_t offset,
 		       void *dst, int length)
 {
+	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
 #ifdef RTE_ARCH_PPC_64
 	int size;
 
@@ -128,17 +129,17 @@ legacy_read_dev_config(struct virtio_hw *hw, size_t offset,
 		if (length >= 4) {
 			size = 4;
 			rte_pci_ioport_read(VTPCI_IO(hw), dst, size,
-				VIRTIO_PCI_CONFIG(hw) + offset);
+				VIRTIO_PCI_CONFIG(dev) + offset);
 			*(uint32_t *)dst = rte_be_to_cpu_32(*(uint32_t *)dst);
 		} else if (length >= 2) {
 			size = 2;
 			rte_pci_ioport_read(VTPCI_IO(hw), dst, size,
-				VIRTIO_PCI_CONFIG(hw) + offset);
+				VIRTIO_PCI_CONFIG(dev) + offset);
 			*(uint16_t *)dst = rte_be_to_cpu_16(*(uint16_t *)dst);
 		} else {
 			size = 1;
 			rte_pci_ioport_read(VTPCI_IO(hw), dst, size,
-				VIRTIO_PCI_CONFIG(hw) + offset);
+				VIRTIO_PCI_CONFIG(dev) + offset);
 		}
 
 		dst = (char *)dst + size;
@@ -147,7 +148,7 @@ legacy_read_dev_config(struct virtio_hw *hw, size_t offset,
 	}
 #else
 	rte_pci_ioport_read(VTPCI_IO(hw), dst, length,
-		VIRTIO_PCI_CONFIG(hw) + offset);
+		VIRTIO_PCI_CONFIG(dev) + offset);
 #endif
 }
 
@@ -155,6 +156,7 @@ static void
 legacy_write_dev_config(struct virtio_hw *hw, size_t offset,
 			const void *src, int length)
 {
+	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
 #ifdef RTE_ARCH_PPC_64
 	union {
 		uint32_t u32;
@@ -167,16 +169,16 @@ legacy_write_dev_config(struct virtio_hw *hw, size_t offset,
 			size = 4;
 			tmp.u32 = rte_cpu_to_be_32(*(const uint32_t *)src);
 			rte_pci_ioport_write(VTPCI_IO(hw), &tmp.u32, size,
-				VIRTIO_PCI_CONFIG(hw) + offset);
+				VIRTIO_PCI_CONFIG(dev) + offset);
 		} else if (length >= 2) {
 			size = 2;
 			tmp.u16 = rte_cpu_to_be_16(*(const uint16_t *)src);
 			rte_pci_ioport_write(VTPCI_IO(hw), &tmp.u16, size,
-				VIRTIO_PCI_CONFIG(hw) + offset);
+				VIRTIO_PCI_CONFIG(dev) + offset);
 		} else {
 			size = 1;
 			rte_pci_ioport_write(VTPCI_IO(hw), src, size,
-				VIRTIO_PCI_CONFIG(hw) + offset);
+				VIRTIO_PCI_CONFIG(dev) + offset);
 		}
 
 		src = (const char *)src + size;
@@ -185,7 +187,7 @@ legacy_write_dev_config(struct virtio_hw *hw, size_t offset,
 	}
 #else
 	rte_pci_ioport_write(VTPCI_IO(hw), src, length,
-		VIRTIO_PCI_CONFIG(hw) + offset);
+		VIRTIO_PCI_CONFIG(dev) + offset);
 #endif
 }
 
@@ -311,7 +313,8 @@ legacy_intr_event(struct virtio_hw *hw)
 {
 	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
 
-	hw->use_msix = vtpci_msix_detect(dev->pci_dev);
+	dev->msix_status = vtpci_msix_detect(dev->pci_dev);
+	hw->intr_lsc = !!dev->msix_status;
 }
 
 static int
@@ -571,7 +574,8 @@ modern_intr_event(struct virtio_hw *hw)
 {
 	struct virtio_pci_dev *dev = virtio_pci_get_dev(hw);
 
-	hw->use_msix = vtpci_msix_detect(dev->pci_dev);
+	dev->msix_status = vtpci_msix_detect(dev->pci_dev);
+	hw->intr_lsc = !!dev->msix_status;
 }
 
 static int
@@ -603,12 +607,6 @@ const struct virtio_ops modern_ops = {
 	.dev_close	= modern_dev_close,
 };
 
-uint8_t
-vtpci_isr(struct virtio_hw *hw)
-{
-	return VIRTIO_OPS(hw)->get_isr(hw);
-}
-
 static void *
 get_cfg_addr(struct rte_pci_device *dev, struct virtio_pci_cap *cap)
 {
@@ -691,9 +689,9 @@ virtio_read_caps(struct rte_pci_device *pci_dev, struct virtio_hw *hw)
 			}
 
 			if (flags & PCI_MSIX_ENABLE)
-				hw->use_msix = VIRTIO_MSIX_ENABLED;
+				dev->msix_status = VIRTIO_MSIX_ENABLED;
 			else
-				hw->use_msix = VIRTIO_MSIX_DISABLED;
+				dev->msix_status = VIRTIO_MSIX_DISABLED;
 		}
 
 		if (cap.cap_vndr != PCI_CAP_ID_VNDR) {
@@ -806,7 +804,8 @@ vtpci_init(struct rte_pci_device *pci_dev, struct virtio_pci_dev *dev)
 	dev->modern = false;
 
 msix_detect:
-	hw->use_msix = vtpci_msix_detect(pci_dev);
+	dev->msix_status = vtpci_msix_detect(pci_dev);
+	hw->intr_lsc = !!dev->msix_status;
 
 	return 0;
 }
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index cc1a3a37fd..68f36dc0dd 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -42,13 +42,6 @@ struct virtnet_ctl;
 #define VIRTIO_MSI_QUEUE_VECTOR	  22 /* vector for selected VQ notifications
 				      (16, RW) */
 
-/* The bit of the ISR which indicates a device has an interrupt. */
-#define VIRTIO_PCI_ISR_INTR   0x1
-/* The bit of the ISR which indicates a device configuration change. */
-#define VIRTIO_PCI_ISR_CONFIG 0x2
-/* Vector value used to disable MSI for queue. */
-#define VIRTIO_MSI_NO_VECTOR 0xFFFF
-
 /* Common configuration */
 #define VIRTIO_PCI_CAP_COMMON_CFG	1
 /* Notifications */
@@ -103,11 +96,18 @@ struct virtio_pci_common_cfg {
 	uint32_t queue_used_hi;		/* read-write */
 };
 
+enum virtio_msix_status {
+	VIRTIO_MSIX_NONE = 0,
+	VIRTIO_MSIX_DISABLED = 1,
+	VIRTIO_MSIX_ENABLED = 2
+};
+
 struct virtio_pci_dev {
 	struct virtio_hw hw;
 	struct rte_pci_device *pci_dev;
 	struct virtio_pci_common_cfg *common_cfg;
 	struct virtio_net_config *dev_cfg;
+	enum virtio_msix_status msix_status;
 	uint8_t *isr;
 	uint16_t *notify_base;
 	uint32_t notify_off_multiplier;
@@ -125,20 +125,10 @@ struct virtio_pci_dev {
 /* The alignment to use between consumer and producer parts of vring. */
 #define VIRTIO_PCI_VRING_ALIGN 4096
 
-enum virtio_msix_status {
-	VIRTIO_MSIX_NONE = 0,
-	VIRTIO_MSIX_DISABLED = 1,
-	VIRTIO_MSIX_ENABLED = 2
-};
-
-
 /*
  * Function declaration from virtio_pci.c
  */
 int vtpci_init(struct rte_pci_device *pci_dev, struct virtio_pci_dev *dev);
-
-uint8_t vtpci_isr(struct virtio_hw *);
-
 void vtpci_legacy_ioport_unmap(struct virtio_hw *hw);
 int vtpci_legacy_ioport_map(struct virtio_hw *hw);
 
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index 6e59fe4b58..c3dc3908d6 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -339,7 +339,7 @@ virtio_user_get_isr(struct virtio_hw *hw __rte_unused)
 	/* rxq interrupts and config interrupt are separated in virtio-user,
 	 * here we only report config change.
 	 */
-	return VIRTIO_PCI_ISR_CONFIG;
+	return VIRTIO_ISR_CONFIG;
 }
 
 static uint16_t
@@ -636,11 +636,8 @@ virtio_user_eth_dev_alloc(struct rte_vdev_device *vdev)
 	hw->port_id = data->port_id;
 	dev->port_id = data->port_id;
 	VIRTIO_OPS(hw) = &virtio_user_ops;
-	/*
-	 * MSIX is required to enable LSC (see virtio_init_device).
-	 * Here just pretend that we support msix.
-	 */
-	hw->use_msix = 1;
+
+	hw->intr_lsc = 1;
 	hw->use_vec_rx = 0;
 	hw->use_vec_tx = 0;
 	hw->use_inorder_rx = 0;
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 23/44] net/virtio: move vring alignment to generic header
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (21 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 22/44] net/virtio: make interrupt handling more generic Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 24/44] net/virtio: remove last PCI refs in non-PCI code Maxime Coquelin
                   ` (20 subsequent siblings)
  43 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch moves vring alignment define to the generic
Virtio header.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
Reviewed-by: David Marchand <david.marchand@redhat.com>
---
 drivers/net/virtio/virtio.h             |  3 +++
 drivers/net/virtio/virtio_ethdev.c      | 10 +++++-----
 drivers/net/virtio/virtio_pci.c         |  2 +-
 drivers/net/virtio/virtio_pci.h         |  3 ---
 drivers/net/virtio/virtio_user_ethdev.c |  4 ++--
 5 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/net/virtio/virtio.h b/drivers/net/virtio/virtio.h
index b2b96d9520..5e0b26ff19 100644
--- a/drivers/net/virtio/virtio.h
+++ b/drivers/net/virtio/virtio.h
@@ -131,6 +131,9 @@
 /* Vector value used to disable MSI for queue. */
 #define VIRTIO_MSI_NO_VECTOR 0xFFFF
 
+/* The alignment to use between consumer and producer parts of vring. */
+#define VIRTIO_VRING_ALIGN 4096
+
 /*
  * This structure is just a reference to read net device specific
  * config space; it is just a shadow structure.
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index e8e7fda099..9215d4ab52 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -407,12 +407,12 @@ virtio_init_vring(struct virtqueue *vq)
 	memset(vq->vq_descx, 0, sizeof(struct vq_desc_extra) * vq->vq_nentries);
 	if (virtio_with_packed_queue(vq->hw)) {
 		vring_init_packed(&vq->vq_packed.ring, ring_mem,
-				  VIRTIO_PCI_VRING_ALIGN, size);
+				  VIRTIO_VRING_ALIGN, size);
 		vring_desc_init_packed(vq, size);
 	} else {
 		struct vring *vr = &vq->vq_split.ring;
 
-		vring_init_split(vr, ring_mem, VIRTIO_PCI_VRING_ALIGN, size);
+		vring_init_split(vr, ring_mem, VIRTIO_VRING_ALIGN, size);
 		vring_desc_init_split(vr->desc, size);
 	}
 	/*
@@ -497,14 +497,14 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
 	/*
 	 * Reserve a memzone for vring elements
 	 */
-	size = vring_size(hw, vq_size, VIRTIO_PCI_VRING_ALIGN);
-	vq->vq_ring_size = RTE_ALIGN_CEIL(size, VIRTIO_PCI_VRING_ALIGN);
+	size = vring_size(hw, vq_size, VIRTIO_VRING_ALIGN);
+	vq->vq_ring_size = RTE_ALIGN_CEIL(size, VIRTIO_VRING_ALIGN);
 	PMD_INIT_LOG(DEBUG, "vring_size: %d, rounded_vring_size: %d",
 		     size, vq->vq_ring_size);
 
 	mz = rte_memzone_reserve_aligned(vq_name, vq->vq_ring_size,
 			numa_node, RTE_MEMZONE_IOVA_CONTIG,
-			VIRTIO_PCI_VRING_ALIGN);
+			VIRTIO_VRING_ALIGN);
 	if (mz == NULL) {
 		if (rte_errno == EEXIST)
 			mz = rte_memzone_lookup(vq_name);
diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index 9fe7fc2019..cbcd19bd47 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -492,7 +492,7 @@ modern_setup_queue(struct virtio_hw *hw, struct virtqueue *vq)
 	avail_addr = desc_addr + vq->vq_nentries * sizeof(struct vring_desc);
 	used_addr = RTE_ALIGN_CEIL(avail_addr + offsetof(struct vring_avail,
 							 ring[vq->vq_nentries]),
-				   VIRTIO_PCI_VRING_ALIGN);
+				   VIRTIO_VRING_ALIGN);
 
 	rte_write16(vq->vq_queue_index, &dev->common_cfg->queue_select);
 
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 68f36dc0dd..6cdf2c55dd 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -122,9 +122,6 @@ struct virtio_pci_dev {
  */
 #define VIRTIO_PCI_QUEUE_ADDR_SHIFT 12
 
-/* The alignment to use between consumer and producer parts of vring. */
-#define VIRTIO_PCI_VRING_ALIGN 4096
-
 /*
  * Function declaration from virtio_pci.c
  */
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index c3dc3908d6..91794b8645 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -388,7 +388,7 @@ virtio_user_setup_queue_packed(struct virtqueue *vq,
 		sizeof(struct vring_packed_desc);
 	used_addr = RTE_ALIGN_CEIL(avail_addr +
 			   sizeof(struct vring_packed_desc_event),
-			   VIRTIO_PCI_VRING_ALIGN);
+			   VIRTIO_VRING_ALIGN);
 	vring->num = vq->vq_nentries;
 	vring->desc = (void *)(uintptr_t)desc_addr;
 	vring->driver = (void *)(uintptr_t)avail_addr;
@@ -410,7 +410,7 @@ virtio_user_setup_queue_split(struct virtqueue *vq, struct virtio_user_dev *dev)
 	avail_addr = desc_addr + vq->vq_nentries * sizeof(struct vring_desc);
 	used_addr = RTE_ALIGN_CEIL(avail_addr + offsetof(struct vring_avail,
 							 ring[vq->vq_nentries]),
-				   VIRTIO_PCI_VRING_ALIGN);
+				   VIRTIO_VRING_ALIGN);
 
 	dev->vrings[queue_idx].num = vq->vq_nentries;
 	dev->vrings[queue_idx].desc = (void *)(uintptr_t)desc_addr;
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 24/44] net/virtio: remove last PCI refs in non-PCI code
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (22 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 23/44] net/virtio: move vring alignment to generic header Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 25/44] net/virtio: make Vhost-user req sender consistent Maxime Coquelin
                   ` (19 subsequent siblings)
  43 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch finalizes the bus isolation part of this
refactoring.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
Reviewed-by: David Marchand <david.marchand@redhat.com>
---
 drivers/net/virtio/virtio_ethdev.c           | 21 +++++++++-----------
 drivers/net/virtio/virtio_rxtx.c             | 18 ++++++++---------
 drivers/net/virtio/virtio_rxtx_packed.h      |  2 +-
 drivers/net/virtio/virtio_rxtx_packed_avx.h  |  2 +-
 drivers/net/virtio/virtio_rxtx_packed_neon.h |  2 +-
 drivers/net/virtio/virtio_user/vhost.h       |  4 +++-
 drivers/net/virtio/virtqueue.c               |  2 +-
 drivers/net/virtio/virtqueue.h               |  8 ++++----
 8 files changed, 29 insertions(+), 30 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 9215d4ab52..4438b64c04 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -9,14 +9,11 @@
 #include <unistd.h>
 
 #include <rte_ethdev_driver.h>
-#include <rte_ethdev_pci.h>
 #include <rte_memcpy.h>
 #include <rte_string_fns.h>
 #include <rte_memzone.h>
 #include <rte_malloc.h>
 #include <rte_branch_prediction.h>
-#include <rte_pci.h>
-#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ip.h>
 #include <rte_arp.h>
@@ -32,7 +29,7 @@
 #include <rte_kvargs.h>
 
 #include "virtio_ethdev.h"
-#include "virtio_pci.h"
+#include "virtio.h"
 #include "virtio_logs.h"
 #include "virtqueue.h"
 #include "virtio_rxtx.h"
@@ -422,7 +419,7 @@ virtio_init_vring(struct virtqueue *vq)
 }
 
 static int
-virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
+virtio_init_queue(struct rte_eth_dev *dev, uint16_t queue_idx)
 {
 	char vq_name[VIRTQUEUE_MAX_NAME_SZ];
 	char vq_hdr_name[VIRTQUEUE_MAX_NAME_SZ];
@@ -435,18 +432,18 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
 	struct virtqueue *vq;
 	size_t sz_hdr_mz = 0;
 	void *sw_ring = NULL;
-	int queue_type = virtio_get_queue_type(hw, vtpci_queue_idx);
+	int queue_type = virtio_get_queue_type(hw, queue_idx);
 	int ret;
 	int numa_node = dev->device->numa_node;
 
 	PMD_INIT_LOG(INFO, "setting up queue: %u on NUMA node %d",
-			vtpci_queue_idx, numa_node);
+			queue_idx, numa_node);
 
 	/*
 	 * Read the virtqueue size from the Queue Size field
 	 * Always power of 2 and if 0 virtqueue does not exist
 	 */
-	vq_size = VIRTIO_OPS(hw)->get_queue_num(hw, vtpci_queue_idx);
+	vq_size = VIRTIO_OPS(hw)->get_queue_num(hw, queue_idx);
 	PMD_INIT_LOG(DEBUG, "vq_size: %u", vq_size);
 	if (vq_size == 0) {
 		PMD_INIT_LOG(ERR, "virtqueue does not exist");
@@ -459,7 +456,7 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
 	}
 
 	snprintf(vq_name, sizeof(vq_name), "port%d_vq%d",
-		 dev->data->port_id, vtpci_queue_idx);
+		 dev->data->port_id, queue_idx);
 
 	size = RTE_ALIGN_CEIL(sizeof(*vq) +
 				vq_size * sizeof(struct vq_desc_extra),
@@ -481,10 +478,10 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
 		PMD_INIT_LOG(ERR, "can not allocate vq");
 		return -ENOMEM;
 	}
-	hw->vqs[vtpci_queue_idx] = vq;
+	hw->vqs[queue_idx] = vq;
 
 	vq->hw = hw;
-	vq->vq_queue_index = vtpci_queue_idx;
+	vq->vq_queue_index = queue_idx;
 	vq->vq_nentries = vq_size;
 	if (virtio_with_packed_queue(hw)) {
 		vq->vq_packed.used_wrap_counter = 1;
@@ -527,7 +524,7 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
 
 	if (sz_hdr_mz) {
 		snprintf(vq_hdr_name, sizeof(vq_hdr_name), "port%d_vq%d_hdr",
-			 dev->data->port_id, vtpci_queue_idx);
+			 dev->data->port_id, queue_idx);
 		hdr_mz = rte_memzone_reserve_aligned(vq_hdr_name, sz_hdr_mz,
 				numa_node, RTE_MEMZONE_IOVA_CONTIG,
 				RTE_CACHE_LINE_SIZE);
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index 728085e99b..b5657d5c83 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -27,7 +27,7 @@
 
 #include "virtio_logs.h"
 #include "virtio_ethdev.h"
-#include "virtio_pci.h"
+#include "virtio.h"
 #include "virtqueue.h"
 #include "virtio_rxtx.h"
 #include "virtio_rxtx_simple.h"
@@ -628,9 +628,9 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			const struct rte_eth_rxconf *rx_conf,
 			struct rte_mempool *mp)
 {
-	uint16_t vtpci_queue_idx = 2 * queue_idx + VTNET_SQ_RQ_QUEUE_IDX;
+	uint16_t vq_idx = 2 * queue_idx + VTNET_SQ_RQ_QUEUE_IDX;
 	struct virtio_hw *hw = dev->data->dev_private;
-	struct virtqueue *vq = hw->vqs[vtpci_queue_idx];
+	struct virtqueue *vq = hw->vqs[vq_idx];
 	struct virtnet_rx *rxvq;
 	uint16_t rx_free_thresh;
 
@@ -678,9 +678,9 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
 int
 virtio_dev_rx_queue_setup_finish(struct rte_eth_dev *dev, uint16_t queue_idx)
 {
-	uint16_t vtpci_queue_idx = 2 * queue_idx + VTNET_SQ_RQ_QUEUE_IDX;
+	uint16_t vq_idx = 2 * queue_idx + VTNET_SQ_RQ_QUEUE_IDX;
 	struct virtio_hw *hw = dev->data->dev_private;
-	struct virtqueue *vq = hw->vqs[vtpci_queue_idx];
+	struct virtqueue *vq = hw->vqs[vq_idx];
 	struct virtnet_rx *rxvq = &vq->rxq;
 	struct rte_mbuf *m;
 	uint16_t desc_idx;
@@ -779,9 +779,9 @@ virtio_dev_tx_queue_setup(struct rte_eth_dev *dev,
 			unsigned int socket_id __rte_unused,
 			const struct rte_eth_txconf *tx_conf)
 {
-	uint8_t vtpci_queue_idx = 2 * queue_idx + VTNET_SQ_TQ_QUEUE_IDX;
+	uint8_t vq_idx = 2 * queue_idx + VTNET_SQ_TQ_QUEUE_IDX;
 	struct virtio_hw *hw = dev->data->dev_private;
-	struct virtqueue *vq = hw->vqs[vtpci_queue_idx];
+	struct virtqueue *vq = hw->vqs[vq_idx];
 	struct virtnet_tx *txvq;
 	uint16_t tx_free_thresh;
 
@@ -823,9 +823,9 @@ int
 virtio_dev_tx_queue_setup_finish(struct rte_eth_dev *dev,
 				uint16_t queue_idx)
 {
-	uint8_t vtpci_queue_idx = 2 * queue_idx + VTNET_SQ_TQ_QUEUE_IDX;
+	uint8_t vq_idx = 2 * queue_idx + VTNET_SQ_TQ_QUEUE_IDX;
 	struct virtio_hw *hw = dev->data->dev_private;
-	struct virtqueue *vq = hw->vqs[vtpci_queue_idx];
+	struct virtqueue *vq = hw->vqs[vq_idx];
 
 	PMD_INIT_FUNC_TRACE();
 
diff --git a/drivers/net/virtio/virtio_rxtx_packed.h b/drivers/net/virtio/virtio_rxtx_packed.h
index 8d99caeead..3037c8c871 100644
--- a/drivers/net/virtio/virtio_rxtx_packed.h
+++ b/drivers/net/virtio/virtio_rxtx_packed.h
@@ -15,7 +15,7 @@
 
 #include "virtio_logs.h"
 #include "virtio_ethdev.h"
-#include "virtio_pci.h"
+#include "virtio.h"
 #include "virtqueue.h"
 
 #define BYTE_SIZE 8
diff --git a/drivers/net/virtio/virtio_rxtx_packed_avx.h b/drivers/net/virtio/virtio_rxtx_packed_avx.h
index 2c610d57de..49e845d02a 100644
--- a/drivers/net/virtio/virtio_rxtx_packed_avx.h
+++ b/drivers/net/virtio/virtio_rxtx_packed_avx.h
@@ -12,7 +12,7 @@
 
 #include "virtio_logs.h"
 #include "virtio_ethdev.h"
-#include "virtio_pci.h"
+#include "virtio.h"
 #include "virtio_rxtx_packed.h"
 #include "virtqueue.h"
 
diff --git a/drivers/net/virtio/virtio_rxtx_packed_neon.h b/drivers/net/virtio/virtio_rxtx_packed_neon.h
index ae2d099c0b..af9dede41b 100644
--- a/drivers/net/virtio/virtio_rxtx_packed_neon.h
+++ b/drivers/net/virtio/virtio_rxtx_packed_neon.h
@@ -12,7 +12,7 @@
 #include <rte_vect.h>
 
 #include "virtio_ethdev.h"
-#include "virtio_pci.h"
+#include "virtio.h"
 #include "virtio_rxtx_packed.h"
 #include "virtqueue.h"
 
diff --git a/drivers/net/virtio/virtio_user/vhost.h b/drivers/net/virtio/virtio_user/vhost.h
index be286173b0..8ec3a6a62c 100644
--- a/drivers/net/virtio/virtio_user/vhost.h
+++ b/drivers/net/virtio/virtio_user/vhost.h
@@ -9,7 +9,9 @@
 #include <linux/types.h>
 #include <linux/ioctl.h>
 
-#include "../virtio_pci.h"
+#include <rte_errno.h>
+
+#include "../virtio.h"
 #include "../virtio_logs.h"
 #include "../virtqueue.h"
 
diff --git a/drivers/net/virtio/virtqueue.c b/drivers/net/virtio/virtqueue.c
index 59a2cb6599..1f9af3c31b 100644
--- a/drivers/net/virtio/virtqueue.c
+++ b/drivers/net/virtio/virtqueue.c
@@ -7,7 +7,7 @@
 
 #include "virtqueue.h"
 #include "virtio_logs.h"
-#include "virtio_pci.h"
+#include "virtio.h"
 #include "virtio_rxtx_simple.h"
 
 /*
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index f419c0aa99..71b66f3208 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -259,7 +259,7 @@ struct virtqueue {
 	 */
 	uint16_t  vq_desc_head_idx;
 	uint16_t  vq_desc_tail_idx;
-	uint16_t  vq_queue_index;   /**< PCI queue index */
+	uint16_t  vq_queue_index;
 	uint16_t offset; /**< relative offset to obtain addr in mbuf */
 	uint16_t  *notify_addr;
 	struct rte_mbuf **sw_ring;  /**< RX software ring. */
@@ -448,11 +448,11 @@ virtqueue_full(const struct virtqueue *vq)
 }
 
 static inline int
-virtio_get_queue_type(struct virtio_hw *hw, uint16_t vtpci_queue_idx)
+virtio_get_queue_type(struct virtio_hw *hw, uint16_t vq_idx)
 {
-	if (vtpci_queue_idx == hw->max_queue_pairs * 2)
+	if (vq_idx == hw->max_queue_pairs * 2)
 		return VTNET_CQ;
-	else if (vtpci_queue_idx % 2 == 0)
+	else if (vq_idx % 2 == 0)
 		return VTNET_RQ;
 	else
 		return VTNET_TQ;
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 25/44] net/virtio: make Vhost-user req sender consistent
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (23 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 24/44] net/virtio: remove last PCI refs in non-PCI code Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-21  8:50   ` Xia, Chenbo
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 26/44] net/virtio: add Virtio-user ops to set owner Maxime Coquelin
                   ` (18 subsequent siblings)
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch makes vhost_user_write() consistent with
vhost_user_read(), by passing a Vhost-user message
pointer instead of a buffer pointer and its length, which
is now calculated in the function.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_user/vhost_user.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/vhost_user.c b/drivers/net/virtio/virtio_user/vhost_user.c
index 350eed4182..55c813333a 100644
--- a/drivers/net/virtio/virtio_user/vhost_user.c
+++ b/drivers/net/virtio/virtio_user/vhost_user.c
@@ -51,7 +51,7 @@ struct vhost_user_msg {
 	(sizeof(struct vhost_user_msg) - VHOST_USER_HDR_SIZE)
 
 static int
-vhost_user_write(int fd, void *buf, int len, int *fds, int fd_num)
+vhost_user_write(int fd, struct vhost_user_msg *msg, int *fds, int fd_num)
 {
 	int r;
 	struct msghdr msgh;
@@ -63,8 +63,8 @@ vhost_user_write(int fd, void *buf, int len, int *fds, int fd_num)
 	memset(&msgh, 0, sizeof(msgh));
 	memset(control, 0, sizeof(control));
 
-	iov.iov_base = (uint8_t *)buf;
-	iov.iov_len = len;
+	iov.iov_base = (uint8_t *)msg;
+	iov.iov_len = VHOST_USER_HDR_SIZE + msg->size;
 
 	msgh.msg_iov = &iov;
 	msgh.msg_iovlen = 1;
@@ -259,7 +259,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
 	int has_reply_ack = 0;
 	int fds[VHOST_MEMORY_MAX_NREGIONS];
 	int fd_num = 0;
-	int len;
 	int vhostfd = dev->vhostfd;
 
 	RTE_SET_USED(m);
@@ -364,8 +363,7 @@ vhost_user_sock(struct virtio_user_dev *dev,
 		return -1;
 	}
 
-	len = VHOST_USER_HDR_SIZE + msg.size;
-	if (vhost_user_write(vhostfd, &msg, len, fds, fd_num) < 0) {
+	if (vhost_user_write(vhostfd, &msg, fds, fd_num) < 0) {
 		PMD_DRV_LOG(ERR, "%s failed: %s",
 			    vhost_msg_strings[req], strerror(errno));
 		return -1;
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 26/44] net/virtio: add Virtio-user ops to set owner
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (24 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 25/44] net/virtio: make Vhost-user req sender consistent Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-22  3:27   ` Xia, Chenbo
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 27/44] net/virtio: add Virtio-user features ops Maxime Coquelin
                   ` (17 subsequent siblings)
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch implements a dedicated callback for
sending owner request. All the requests will be
converted that way so that backends other than
Vhost-user don't have to work around being it.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_user/vhost.h        |  1 +
 drivers/net/virtio/virtio_user/vhost_kernel.c | 28 +++++++++++++++--
 drivers/net/virtio/virtio_user/vhost_user.c   | 21 +++++++++++--
 drivers/net/virtio/virtio_user/vhost_vdpa.c   | 30 ++++++++++++++++---
 .../net/virtio/virtio_user/virtio_user_dev.c  |  3 +-
 5 files changed, 72 insertions(+), 11 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/vhost.h b/drivers/net/virtio/virtio_user/vhost.h
index 8ec3a6a62c..5413ec6778 100644
--- a/drivers/net/virtio/virtio_user/vhost.h
+++ b/drivers/net/virtio/virtio_user/vhost.h
@@ -109,6 +109,7 @@ struct virtio_user_dev;
 
 struct virtio_user_backend_ops {
 	int (*setup)(struct virtio_user_dev *dev);
+	int (*set_owner)(struct virtio_user_dev *dev);
 	int (*send_request)(struct virtio_user_dev *dev,
 			    enum vhost_user_request req,
 			    void *arg);
diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c b/drivers/net/virtio/virtio_user/vhost_kernel.c
index 2c805077af..b79dcad179 100644
--- a/drivers/net/virtio/virtio_user/vhost_kernel.c
+++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
@@ -6,6 +6,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <errno.h>
 
 #include <rte_memory.h>
 
@@ -55,8 +56,28 @@ get_vhost_kernel_max_regions(void)
 	close(fd);
 }
 
+static int
+vhost_kernel_ioctl(int fd, uint64_t request, void *arg)
+{
+	int ret;
+
+	ret = ioctl(fd, request, arg);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Vhost-kernel ioctl %"PRIu64" failed (%s)",
+				request, strerror(errno));
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+vhost_kernel_set_owner(struct virtio_user_dev *dev)
+{
+	return vhost_kernel_ioctl(dev->vhostfds[0], VHOST_SET_OWNER, NULL);
+}
+
 static uint64_t vhost_req_user_to_kernel[] = {
-	[VHOST_USER_SET_OWNER] = VHOST_SET_OWNER,
 	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
 	[VHOST_USER_SET_FEATURES] = VHOST_SET_FEATURES,
 	[VHOST_USER_GET_FEATURES] = VHOST_GET_FEATURES,
@@ -175,7 +196,7 @@ tap_support_features(void)
 }
 
 static int
-vhost_kernel_ioctl(struct virtio_user_dev *dev,
+vhost_kernel_send_request(struct virtio_user_dev *dev,
 		   enum vhost_user_request req,
 		   void *arg)
 {
@@ -385,6 +406,7 @@ vhost_kernel_enable_queue_pair(struct virtio_user_dev *dev,
 
 struct virtio_user_backend_ops virtio_ops_kernel = {
 	.setup = vhost_kernel_setup,
-	.send_request = vhost_kernel_ioctl,
+	.set_owner = vhost_kernel_set_owner,
+	.send_request = vhost_kernel_send_request,
 	.enable_qp = vhost_kernel_enable_queue_pair
 };
diff --git a/drivers/net/virtio/virtio_user/vhost_user.c b/drivers/net/virtio/virtio_user/vhost_user.c
index 55c813333a..ea3bd4ca10 100644
--- a/drivers/net/virtio/virtio_user/vhost_user.c
+++ b/drivers/net/virtio/virtio_user/vhost_user.c
@@ -125,6 +125,24 @@ vhost_user_read(int fd, struct vhost_user_msg *msg)
 	return -1;
 }
 
+static int
+vhost_user_set_owner(struct virtio_user_dev *dev)
+{
+	int ret;
+	struct vhost_user_msg msg = {
+		.request = VHOST_USER_SET_OWNER,
+		.flags = VHOST_USER_VERSION,
+	};
+
+	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to set owner");
+		return -1;
+	}
+
+	return 0;
+}
+
 struct walk_arg {
 	struct vhost_memory *vm;
 	int *fds;
@@ -230,7 +248,6 @@ prepare_vhost_memory_user(struct vhost_user_msg *msg, int fds[])
 static struct vhost_user_msg m;
 
 const char * const vhost_msg_strings[] = {
-	[VHOST_USER_SET_OWNER] = "VHOST_SET_OWNER",
 	[VHOST_USER_RESET_OWNER] = "VHOST_RESET_OWNER",
 	[VHOST_USER_SET_FEATURES] = "VHOST_SET_FEATURES",
 	[VHOST_USER_GET_FEATURES] = "VHOST_GET_FEATURES",
@@ -308,7 +325,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
 		msg.size = sizeof(m.payload.u64);
 		break;
 
-	case VHOST_USER_SET_OWNER:
 	case VHOST_USER_RESET_OWNER:
 		break;
 
@@ -519,6 +535,7 @@ vhost_user_enable_queue_pair(struct virtio_user_dev *dev,
 
 struct virtio_user_backend_ops virtio_ops_user = {
 	.setup = vhost_user_setup,
+	.set_owner = vhost_user_set_owner,
 	.send_request = vhost_user_sock,
 	.enable_qp = vhost_user_enable_queue_pair
 };
diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c b/drivers/net/virtio/virtio_user/vhost_vdpa.c
index 004802b9eb..d9bc213e0d 100644
--- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
+++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
@@ -39,7 +39,6 @@
 #define VHOST_GET_BACKEND_FEATURES _IOR(VHOST_VIRTIO, 0x26, __u64)
 
 static uint64_t vhost_req_user_to_vdpa[] = {
-	[VHOST_USER_SET_OWNER] = VHOST_SET_OWNER,
 	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
 	[VHOST_USER_SET_FEATURES] = VHOST_SET_FEATURES,
 	[VHOST_USER_GET_FEATURES] = VHOST_GET_FEATURES,
@@ -86,6 +85,28 @@ struct vhost_msg {
 	};
 };
 
+
+static int
+vhost_vdpa_ioctl(int fd, uint64_t request, void *arg)
+{
+	int ret;
+
+	ret = ioctl(fd, request, arg);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Vhost-vDPA ioctl %"PRIu64" failed (%s)",
+				request, strerror(errno));
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+vhost_vdpa_set_owner(struct virtio_user_dev *dev)
+{
+	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_OWNER, NULL);
+}
+
 static int
 vhost_vdpa_iotlb_batch_begin(struct virtio_user_dev *dev)
 {
@@ -308,7 +329,7 @@ vhost_vdpa_dma_map_all(struct virtio_user_dev *dev)
 	 (1ULL << VIRTIO_NET_F_CSUM))
 
 static int
-vhost_vdpa_ioctl(struct virtio_user_dev *dev,
+vhost_vdpa_send_request(struct virtio_user_dev *dev,
 		   enum vhost_user_request req,
 		   void *arg)
 {
@@ -396,7 +417,7 @@ vhost_vdpa_enable_queue_pair(struct virtio_user_dev *dev,
 			.num   = enable,
 		};
 
-		if (vhost_vdpa_ioctl(dev, VHOST_USER_SET_VRING_ENABLE, &state))
+		if (vhost_vdpa_send_request(dev, VHOST_USER_SET_VRING_ENABLE, &state))
 			return -1;
 	}
 
@@ -407,7 +428,8 @@ vhost_vdpa_enable_queue_pair(struct virtio_user_dev *dev,
 
 struct virtio_user_backend_ops virtio_ops_vdpa = {
 	.setup = vhost_vdpa_setup,
-	.send_request = vhost_vdpa_ioctl,
+	.set_owner = vhost_vdpa_set_owner,
+	.send_request = vhost_vdpa_send_request,
 	.enable_qp = vhost_vdpa_enable_queue_pair,
 	.dma_map = vhost_vdpa_dma_map_batch,
 	.dma_unmap = vhost_vdpa_dma_unmap_batch,
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index 202431ca22..f4b97d8489 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -490,8 +490,7 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
 			(1ULL << VHOST_USER_F_PROTOCOL_FEATURES);
 
 	if (!dev->is_server) {
-		if (dev->ops->send_request(dev, VHOST_USER_SET_OWNER,
-					   NULL) < 0) {
+		if (dev->ops->set_owner(dev) < 0) {
 			PMD_INIT_LOG(ERR, "set_owner fails: %s",
 				     strerror(errno));
 			return -1;
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 27/44] net/virtio: add Virtio-user features ops
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (25 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 26/44] net/virtio: add Virtio-user ops to set owner Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-22  7:25   ` Xia, Chenbo
  2021-01-22  8:46   ` Xia, Chenbo
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 28/44] net/virtio: add Virtio-user protocol " Maxime Coquelin
                   ` (16 subsequent siblings)
  43 siblings, 2 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch introduces new callbacks for getting
and setting Virtio features, and implements them
for the different backend types.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_user/vhost.h        |   2 +
 drivers/net/virtio/virtio_user/vhost_kernel.c | 150 +++++++++---------
 .../net/virtio/virtio_user/vhost_kernel_tap.c |  23 +++
 .../net/virtio/virtio_user/vhost_kernel_tap.h |   1 +
 drivers/net/virtio/virtio_user/vhost_user.c   |  64 +++++++-
 drivers/net/virtio/virtio_user/vhost_vdpa.c   |  38 +++--
 .../net/virtio/virtio_user/virtio_user_dev.c  |   5 +-
 drivers/net/virtio/virtio_user_ethdev.c       |   3 +-
 8 files changed, 190 insertions(+), 96 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/vhost.h b/drivers/net/virtio/virtio_user/vhost.h
index 5413ec6778..13a88c7671 100644
--- a/drivers/net/virtio/virtio_user/vhost.h
+++ b/drivers/net/virtio/virtio_user/vhost.h
@@ -110,6 +110,8 @@ struct virtio_user_dev;
 struct virtio_user_backend_ops {
 	int (*setup)(struct virtio_user_dev *dev);
 	int (*set_owner)(struct virtio_user_dev *dev);
+	int (*get_features)(struct virtio_user_dev *dev, uint64_t *features);
+	int (*set_features)(struct virtio_user_dev *dev, uint64_t features);
 	int (*send_request)(struct virtio_user_dev *dev,
 			    enum vhost_user_request req,
 			    void *arg);
diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c b/drivers/net/virtio/virtio_user/vhost_kernel.c
index b79dcad179..f44df8ef1f 100644
--- a/drivers/net/virtio/virtio_user/vhost_kernel.c
+++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
@@ -38,6 +38,28 @@ struct vhost_memory_kernel {
 #define VHOST_SET_VRING_ERR _IOW(VHOST_VIRTIO, 0x22, struct vhost_vring_file)
 #define VHOST_NET_SET_BACKEND _IOW(VHOST_VIRTIO, 0x30, struct vhost_vring_file)
 
+/* with below features, vhost kernel does not need to do the checksum and TSO,
+ * these info will be passed to virtio_user through virtio net header.
+ */
+#define VHOST_KERNEL_GUEST_OFFLOADS_MASK	\
+	((1ULL << VIRTIO_NET_F_GUEST_CSUM) |	\
+	 (1ULL << VIRTIO_NET_F_GUEST_TSO4) |	\
+	 (1ULL << VIRTIO_NET_F_GUEST_TSO6) |	\
+	 (1ULL << VIRTIO_NET_F_GUEST_ECN)  |	\
+	 (1ULL << VIRTIO_NET_F_GUEST_UFO))
+
+/* with below features, when flows from virtio_user to vhost kernel
+ * (1) if flows goes up through the kernel networking stack, it does not need
+ * to verify checksum, which can save CPU cycles;
+ * (2) if flows goes through a Linux bridge and outside from an interface
+ * (kernel driver), checksum and TSO will be done by GSO in kernel or even
+ * offloaded into real physical device.
+ */
+#define VHOST_KERNEL_HOST_OFFLOADS_MASK		\
+	((1ULL << VIRTIO_NET_F_HOST_TSO4) |	\
+	 (1ULL << VIRTIO_NET_F_HOST_TSO6) |	\
+	 (1ULL << VIRTIO_NET_F_CSUM))
+
 static uint64_t max_regions = 64;
 
 static void
@@ -77,10 +99,57 @@ vhost_kernel_set_owner(struct virtio_user_dev *dev)
 	return vhost_kernel_ioctl(dev->vhostfds[0], VHOST_SET_OWNER, NULL);
 }
 
+static int
+vhost_kernel_get_features(struct virtio_user_dev *dev, uint64_t *features)
+{
+	int ret;
+	unsigned int tap_features;
+
+	ret = vhost_kernel_ioctl(dev->vhostfds[0], VHOST_GET_FEATURES, features);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to get features");
+		return -1;
+	}
+
+	ret = tap_support_features(&tap_features);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to get TAP features)");
+		return -1;
+	}
+
+	/* with tap as the backend, all these features are supported
+	 * but not claimed by vhost-net, so we add them back when
+	 * reporting to upper layer.
+	 */
+	if (tap_features & IFF_VNET_HDR) {
+		*features |= VHOST_KERNEL_GUEST_OFFLOADS_MASK;
+		*features |= VHOST_KERNEL_HOST_OFFLOADS_MASK;
+	}
+
+	/* vhost_kernel will not declare this feature, but it does
+	 * support multi-queue.
+	 */
+	if (tap_features & IFF_MULTI_QUEUE)
+		*features |= (1ull << VIRTIO_NET_F_MQ);
+
+	return 0;
+}
+
+static int
+vhost_kernel_set_features(struct virtio_user_dev *dev, uint64_t features)
+{
+	/* We don't need memory protection here */
+	features &= ~(1ULL << VIRTIO_F_IOMMU_PLATFORM);
+	/* VHOST kernel does not know about below flags */
+	features &= ~VHOST_KERNEL_GUEST_OFFLOADS_MASK;
+	features &= ~VHOST_KERNEL_HOST_OFFLOADS_MASK;
+	features &= ~(1ULL << VIRTIO_NET_F_MQ);
+
+	return vhost_kernel_ioctl(dev->vhostfds[0], VHOST_SET_FEATURES, &features);
+}
+
 static uint64_t vhost_req_user_to_kernel[] = {
 	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
-	[VHOST_USER_SET_FEATURES] = VHOST_SET_FEATURES,
-	[VHOST_USER_GET_FEATURES] = VHOST_GET_FEATURES,
 	[VHOST_USER_SET_VRING_CALL] = VHOST_SET_VRING_CALL,
 	[VHOST_USER_SET_VRING_NUM] = VHOST_SET_VRING_NUM,
 	[VHOST_USER_SET_VRING_BASE] = VHOST_SET_VRING_BASE,
@@ -150,51 +219,6 @@ prepare_vhost_memory_kernel(void)
 	return vm;
 }
 
-/* with below features, vhost kernel does not need to do the checksum and TSO,
- * these info will be passed to virtio_user through virtio net header.
- */
-#define VHOST_KERNEL_GUEST_OFFLOADS_MASK	\
-	((1ULL << VIRTIO_NET_F_GUEST_CSUM) |	\
-	 (1ULL << VIRTIO_NET_F_GUEST_TSO4) |	\
-	 (1ULL << VIRTIO_NET_F_GUEST_TSO6) |	\
-	 (1ULL << VIRTIO_NET_F_GUEST_ECN)  |	\
-	 (1ULL << VIRTIO_NET_F_GUEST_UFO))
-
-/* with below features, when flows from virtio_user to vhost kernel
- * (1) if flows goes up through the kernel networking stack, it does not need
- * to verify checksum, which can save CPU cycles;
- * (2) if flows goes through a Linux bridge and outside from an interface
- * (kernel driver), checksum and TSO will be done by GSO in kernel or even
- * offloaded into real physical device.
- */
-#define VHOST_KERNEL_HOST_OFFLOADS_MASK		\
-	((1ULL << VIRTIO_NET_F_HOST_TSO4) |	\
-	 (1ULL << VIRTIO_NET_F_HOST_TSO6) |	\
-	 (1ULL << VIRTIO_NET_F_CSUM))
-
-static unsigned int
-tap_support_features(void)
-{
-	int tapfd;
-	unsigned int tap_features;
-
-	tapfd = open(PATH_NET_TUN, O_RDWR);
-	if (tapfd < 0) {
-		PMD_DRV_LOG(ERR, "fail to open %s: %s",
-			    PATH_NET_TUN, strerror(errno));
-		return -1;
-	}
-
-	if (ioctl(tapfd, TUNGETFEATURES, &tap_features) == -1) {
-		PMD_DRV_LOG(ERR, "TUNGETFEATURES failed: %s", strerror(errno));
-		close(tapfd);
-		return -1;
-	}
-
-	close(tapfd);
-	return tap_features;
-}
-
 static int
 vhost_kernel_send_request(struct virtio_user_dev *dev,
 		   enum vhost_user_request req,
@@ -206,7 +230,6 @@ vhost_kernel_send_request(struct virtio_user_dev *dev,
 	struct vhost_memory_kernel *vm = NULL;
 	int vhostfd;
 	unsigned int queue_sel;
-	unsigned int features;
 
 	PMD_DRV_LOG(INFO, "%s", vhost_msg_strings[req]);
 
@@ -219,17 +242,6 @@ vhost_kernel_send_request(struct virtio_user_dev *dev,
 		arg = (void *)vm;
 	}
 
-	if (req_kernel == VHOST_SET_FEATURES) {
-		/* We don't need memory protection here */
-		*(uint64_t *)arg &= ~(1ULL << VIRTIO_F_IOMMU_PLATFORM);
-
-		/* VHOST kernel does not know about below flags */
-		*(uint64_t *)arg &= ~VHOST_KERNEL_GUEST_OFFLOADS_MASK;
-		*(uint64_t *)arg &= ~VHOST_KERNEL_HOST_OFFLOADS_MASK;
-
-		*(uint64_t *)arg &= ~(1ULL << VIRTIO_NET_F_MQ);
-	}
-
 	switch (req_kernel) {
 	case VHOST_SET_VRING_NUM:
 	case VHOST_SET_VRING_ADDR:
@@ -259,24 +271,6 @@ vhost_kernel_send_request(struct virtio_user_dev *dev,
 		ret = ioctl(vhostfd, req_kernel, arg);
 	}
 
-	if (!ret && req_kernel == VHOST_GET_FEATURES) {
-		features = tap_support_features();
-		/* with tap as the backend, all these features are supported
-		 * but not claimed by vhost-net, so we add them back when
-		 * reporting to upper layer.
-		 */
-		if (features & IFF_VNET_HDR) {
-			*((uint64_t *)arg) |= VHOST_KERNEL_GUEST_OFFLOADS_MASK;
-			*((uint64_t *)arg) |= VHOST_KERNEL_HOST_OFFLOADS_MASK;
-		}
-
-		/* vhost_kernel will not declare this feature, but it does
-		 * support multi-queue.
-		 */
-		if (features & IFF_MULTI_QUEUE)
-			*(uint64_t *)arg |= (1ull << VIRTIO_NET_F_MQ);
-	}
-
 	if (vm)
 		free(vm);
 
@@ -407,6 +401,8 @@ vhost_kernel_enable_queue_pair(struct virtio_user_dev *dev,
 struct virtio_user_backend_ops virtio_ops_kernel = {
 	.setup = vhost_kernel_setup,
 	.set_owner = vhost_kernel_set_owner,
+	.get_features = vhost_kernel_get_features,
+	.set_features = vhost_kernel_set_features,
 	.send_request = vhost_kernel_send_request,
 	.enable_qp = vhost_kernel_enable_queue_pair
 };
diff --git a/drivers/net/virtio/virtio_user/vhost_kernel_tap.c b/drivers/net/virtio/virtio_user/vhost_kernel_tap.c
index eade702c5c..99096bdf39 100644
--- a/drivers/net/virtio/virtio_user/vhost_kernel_tap.c
+++ b/drivers/net/virtio/virtio_user/vhost_kernel_tap.c
@@ -18,6 +18,29 @@
 #include "../virtio_logs.h"
 #include "../virtio.h"
 
+
+int
+tap_support_features(unsigned int *tap_features)
+{
+	int tapfd;
+
+	tapfd = open(PATH_NET_TUN, O_RDWR);
+	if (tapfd < 0) {
+		PMD_DRV_LOG(ERR, "fail to open %s: %s",
+			    PATH_NET_TUN, strerror(errno));
+		return -1;
+	}
+
+	if (ioctl(tapfd, TUNGETFEATURES, tap_features) == -1) {
+		PMD_DRV_LOG(ERR, "TUNGETFEATURES failed: %s", strerror(errno));
+		close(tapfd);
+		return -1;
+	}
+
+	close(tapfd);
+	return 0;
+}
+
 int
 vhost_kernel_tap_set_offload(int fd, uint64_t features)
 {
diff --git a/drivers/net/virtio/virtio_user/vhost_kernel_tap.h b/drivers/net/virtio/virtio_user/vhost_kernel_tap.h
index 5c4447b296..ed03fce21e 100644
--- a/drivers/net/virtio/virtio_user/vhost_kernel_tap.h
+++ b/drivers/net/virtio/virtio_user/vhost_kernel_tap.h
@@ -43,5 +43,6 @@ int vhost_kernel_open_tap(char **p_ifname, int hdr_size, int req_mq,
 			 const char *mac, uint64_t features);
 int vhost_kernel_tap_set_offload(int fd, uint64_t features);
 int vhost_kernel_tap_set_queue(int fd, bool attach);
+int tap_support_features(unsigned int *tap_features);
 
 #endif
diff --git a/drivers/net/virtio/virtio_user/vhost_user.c b/drivers/net/virtio/virtio_user/vhost_user.c
index ea3bd4ca10..8e5bf332d6 100644
--- a/drivers/net/virtio/virtio_user/vhost_user.c
+++ b/drivers/net/virtio/virtio_user/vhost_user.c
@@ -143,6 +143,64 @@ vhost_user_set_owner(struct virtio_user_dev *dev)
 	return 0;
 }
 
+static int
+vhost_user_get_features(struct virtio_user_dev *dev, uint64_t *features)
+{
+	int ret;
+	struct vhost_user_msg msg = {
+		.request = VHOST_USER_GET_FEATURES,
+		.flags = VHOST_USER_VERSION,
+	};
+
+	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+	if (ret < 0)
+		goto err;
+
+	ret = vhost_user_read(dev->vhostfd, &msg);
+	if (ret < 0)
+		goto err;
+
+	if (msg.request != VHOST_USER_GET_FEATURES) {
+		PMD_DRV_LOG(ERR, "Unexpected request type (%d)", msg.request);
+		goto err;
+	}
+
+	if (msg.size != sizeof(*features)) {
+		PMD_DRV_LOG(ERR, "Unexpected payload size (%u)", msg.size);
+		goto err;
+	}
+
+	*features = msg.payload.u64;
+
+	return 0;
+err:
+	PMD_DRV_LOG(ERR, "Failed to get backend features");
+
+	return -1;
+}
+
+static int
+vhost_user_set_features(struct virtio_user_dev *dev, uint64_t features)
+{
+	int ret;
+	struct vhost_user_msg msg = {
+		.request = VHOST_USER_SET_FEATURES,
+		.flags = VHOST_USER_VERSION,
+		.size = sizeof(features),
+		.payload.u64 = features,
+	};
+
+	msg.payload.u64 |= dev->device_features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES);
+
+	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to set features");
+		return -1;
+	}
+
+	return 0;
+}
+
 struct walk_arg {
 	struct vhost_memory *vm;
 	int *fds;
@@ -249,8 +307,6 @@ static struct vhost_user_msg m;
 
 const char * const vhost_msg_strings[] = {
 	[VHOST_USER_RESET_OWNER] = "VHOST_RESET_OWNER",
-	[VHOST_USER_SET_FEATURES] = "VHOST_SET_FEATURES",
-	[VHOST_USER_GET_FEATURES] = "VHOST_GET_FEATURES",
 	[VHOST_USER_SET_VRING_CALL] = "VHOST_SET_VRING_CALL",
 	[VHOST_USER_SET_VRING_NUM] = "VHOST_SET_VRING_NUM",
 	[VHOST_USER_SET_VRING_BASE] = "VHOST_SET_VRING_BASE",
@@ -299,7 +355,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
 				(1ULL << VHOST_USER_PROTOCOL_F_STATUS))))
 			return -ENOTSUP;
 		/* Fallthrough */
-	case VHOST_USER_GET_FEATURES:
 	case VHOST_USER_GET_PROTOCOL_FEATURES:
 		need_reply = 1;
 		break;
@@ -398,7 +453,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
 		}
 
 		switch (req) {
-		case VHOST_USER_GET_FEATURES:
 		case VHOST_USER_GET_STATUS:
 		case VHOST_USER_GET_PROTOCOL_FEATURES:
 			if (msg.size != sizeof(m.payload.u64)) {
@@ -536,6 +590,8 @@ vhost_user_enable_queue_pair(struct virtio_user_dev *dev,
 struct virtio_user_backend_ops virtio_ops_user = {
 	.setup = vhost_user_setup,
 	.set_owner = vhost_user_set_owner,
+	.get_features = vhost_user_get_features,
+	.set_features = vhost_user_set_features,
 	.send_request = vhost_user_sock,
 	.enable_qp = vhost_user_enable_queue_pair
 };
diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c b/drivers/net/virtio/virtio_user/vhost_vdpa.c
index d9bc213e0d..22a329526a 100644
--- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
+++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
@@ -40,8 +40,6 @@
 
 static uint64_t vhost_req_user_to_vdpa[] = {
 	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
-	[VHOST_USER_SET_FEATURES] = VHOST_SET_FEATURES,
-	[VHOST_USER_GET_FEATURES] = VHOST_GET_FEATURES,
 	[VHOST_USER_SET_VRING_CALL] = VHOST_SET_VRING_CALL,
 	[VHOST_USER_SET_VRING_NUM] = VHOST_SET_VRING_NUM,
 	[VHOST_USER_SET_VRING_BASE] = VHOST_SET_VRING_BASE,
@@ -107,6 +105,32 @@ vhost_vdpa_set_owner(struct virtio_user_dev *dev)
 	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_OWNER, NULL);
 }
 
+static int
+vhost_vdpa_get_features(struct virtio_user_dev *dev, uint64_t *features)
+{
+	int ret;
+
+	ret = vhost_vdpa_ioctl(dev->vhostfd, VHOST_GET_FEATURES, features);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to get features");
+		return -1;
+	}
+
+	/* Multiqueue not supported for now */
+	*features &= ~(1ULL << VIRTIO_NET_F_MQ);
+
+	return 0;
+}
+
+static int
+vhost_vdpa_set_features(struct virtio_user_dev *dev, uint64_t features)
+{
+	/* WORKAROUND */
+	features |= 1ULL << VIRTIO_F_IOMMU_PLATFORM;
+
+	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_FEATURES, &features);
+}
+
 static int
 vhost_vdpa_iotlb_batch_begin(struct virtio_user_dev *dev)
 {
@@ -343,14 +367,6 @@ vhost_vdpa_send_request(struct virtio_user_dev *dev,
 	if (req_vdpa == VHOST_SET_MEM_TABLE)
 		return vhost_vdpa_dma_map_all(dev);
 
-	if (req_vdpa == VHOST_SET_FEATURES) {
-		/* WORKAROUND */
-		*(uint64_t *)arg |= 1ULL << VIRTIO_F_IOMMU_PLATFORM;
-
-		/* Multiqueue not supported for now */
-		*(uint64_t *)arg &= ~(1ULL << VIRTIO_NET_F_MQ);
-	}
-
 	switch (req_vdpa) {
 	case VHOST_SET_VRING_NUM:
 	case VHOST_SET_VRING_ADDR:
@@ -429,6 +445,8 @@ vhost_vdpa_enable_queue_pair(struct virtio_user_dev *dev,
 struct virtio_user_backend_ops virtio_ops_vdpa = {
 	.setup = vhost_vdpa_setup,
 	.set_owner = vhost_vdpa_set_owner,
+	.get_features = vhost_vdpa_get_features,
+	.set_features = vhost_vdpa_set_features,
 	.send_request = vhost_vdpa_send_request,
 	.enable_qp = vhost_vdpa_enable_queue_pair,
 	.dma_map = vhost_vdpa_dma_map_batch,
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index f4b97d8489..1f3bbae663 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -141,7 +141,7 @@ virtio_user_dev_set_features(struct virtio_user_dev *dev)
 	/* Strip VIRTIO_NET_F_CTRL_VQ, as devices do not really need to know */
 	features &= ~(1ull << VIRTIO_NET_F_CTRL_VQ);
 	features &= ~(1ull << VIRTIO_NET_F_STATUS);
-	ret = dev->ops->send_request(dev, VHOST_USER_SET_FEATURES, &features);
+	ret = dev->ops->set_features(dev, features);
 	if (ret < 0)
 		goto error;
 	PMD_DRV_LOG(INFO, "set features: %" PRIx64, features);
@@ -496,8 +496,7 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
 			return -1;
 		}
 
-		if (dev->ops->send_request(dev, VHOST_USER_GET_FEATURES,
-					   &dev->device_features) < 0) {
+		if (dev->ops->get_features(dev, &dev->device_features) < 0) {
 			PMD_INIT_LOG(ERR, "get_features failed: %s",
 				     strerror(errno));
 			return -1;
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index 91794b8645..56c379bc15 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -85,8 +85,7 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev)
 
 	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);
 
-	if (dev->ops->send_request(dev, VHOST_USER_GET_FEATURES,
-				   &dev->device_features) < 0) {
+	if (dev->ops->get_features(dev, &dev->device_features) < 0) {
 		PMD_INIT_LOG(ERR, "get_features failed: %s",
 			     strerror(errno));
 		return -1;
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 28/44] net/virtio: add Virtio-user protocol features ops
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (26 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 27/44] net/virtio: add Virtio-user features ops Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-22  7:27   ` Xia, Chenbo
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 29/44] net/virtio: add Virtio-user memory tables ops Maxime Coquelin
                   ` (15 subsequent siblings)
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch introduces new callbacks for getting
and setting Vhost-user protocol features.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_user/vhost.h        |  2 +
 drivers/net/virtio/virtio_user/vhost_user.c   | 64 +++++++++++++++++--
 drivers/net/virtio/virtio_user/vhost_vdpa.c   | 14 ++++
 .../net/virtio/virtio_user/virtio_user_dev.c  | 14 ++--
 drivers/net/virtio/virtio_user_ethdev.c       | 14 ++--
 5 files changed, 82 insertions(+), 26 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/vhost.h b/drivers/net/virtio/virtio_user/vhost.h
index 13a88c7671..d805526130 100644
--- a/drivers/net/virtio/virtio_user/vhost.h
+++ b/drivers/net/virtio/virtio_user/vhost.h
@@ -112,6 +112,8 @@ struct virtio_user_backend_ops {
 	int (*set_owner)(struct virtio_user_dev *dev);
 	int (*get_features)(struct virtio_user_dev *dev, uint64_t *features);
 	int (*set_features)(struct virtio_user_dev *dev, uint64_t features);
+	int (*get_protocol_features)(struct virtio_user_dev *dev, uint64_t *features);
+	int (*set_protocol_features)(struct virtio_user_dev *dev, uint64_t features);
 	int (*send_request)(struct virtio_user_dev *dev,
 			    enum vhost_user_request req,
 			    void *arg);
diff --git a/drivers/net/virtio/virtio_user/vhost_user.c b/drivers/net/virtio/virtio_user/vhost_user.c
index 8e5bf332d6..4877574f72 100644
--- a/drivers/net/virtio/virtio_user/vhost_user.c
+++ b/drivers/net/virtio/virtio_user/vhost_user.c
@@ -201,6 +201,62 @@ vhost_user_set_features(struct virtio_user_dev *dev, uint64_t features)
 	return 0;
 }
 
+static int
+vhost_user_get_protocol_features(struct virtio_user_dev *dev, uint64_t *features)
+{
+	int ret;
+	struct vhost_user_msg msg = {
+		.request = VHOST_USER_GET_PROTOCOL_FEATURES,
+		.flags = VHOST_USER_VERSION,
+	};
+
+	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+	if (ret < 0)
+		goto err;
+
+	ret = vhost_user_read(dev->vhostfd, &msg);
+	if (ret < 0)
+		goto err;
+
+	if (msg.request != VHOST_USER_GET_PROTOCOL_FEATURES) {
+		PMD_DRV_LOG(ERR, "Unexpected request type (%d)", msg.request);
+		goto err;
+	}
+
+	if (msg.size != sizeof(*features)) {
+		PMD_DRV_LOG(ERR, "Unexpected payload size (%u)", msg.size);
+		goto err;
+	}
+
+	*features = msg.payload.u64;
+
+	return 0;
+err:
+	PMD_DRV_LOG(ERR, "Failed to get backend protocol features");
+
+	return -1;
+}
+
+static int
+vhost_user_set_protocol_features(struct virtio_user_dev *dev, uint64_t features)
+{
+	int ret;
+	struct vhost_user_msg msg = {
+		.request = VHOST_USER_SET_PROTOCOL_FEATURES,
+		.flags = VHOST_USER_VERSION,
+		.size = sizeof(features),
+		.payload.u64 = features,
+	};
+
+	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to set protocol features");
+		return -1;
+	}
+
+	return 0;
+}
+
 struct walk_arg {
 	struct vhost_memory *vm;
 	int *fds;
@@ -315,8 +371,6 @@ const char * const vhost_msg_strings[] = {
 	[VHOST_USER_SET_VRING_KICK] = "VHOST_SET_VRING_KICK",
 	[VHOST_USER_SET_MEM_TABLE] = "VHOST_SET_MEM_TABLE",
 	[VHOST_USER_SET_VRING_ENABLE] = "VHOST_SET_VRING_ENABLE",
-	[VHOST_USER_GET_PROTOCOL_FEATURES] = "VHOST_USER_GET_PROTOCOL_FEATURES",
-	[VHOST_USER_SET_PROTOCOL_FEATURES] = "VHOST_USER_SET_PROTOCOL_FEATURES",
 	[VHOST_USER_SET_STATUS] = "VHOST_SET_STATUS",
 	[VHOST_USER_GET_STATUS] = "VHOST_GET_STATUS",
 };
@@ -354,8 +408,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
 		    (!(dev->protocol_features &
 				(1ULL << VHOST_USER_PROTOCOL_F_STATUS))))
 			return -ENOTSUP;
-		/* Fallthrough */
-	case VHOST_USER_GET_PROTOCOL_FEATURES:
 		need_reply = 1;
 		break;
 
@@ -368,7 +420,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
 		if (has_reply_ack)
 			msg.flags |= VHOST_USER_NEED_REPLY_MASK;
 		/* Fallthrough */
-	case VHOST_USER_SET_PROTOCOL_FEATURES:
 	case VHOST_USER_SET_LOG_BASE:
 		msg.payload.u64 = *((__u64 *)arg);
 		msg.size = sizeof(m.payload.u64);
@@ -454,7 +505,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
 
 		switch (req) {
 		case VHOST_USER_GET_STATUS:
-		case VHOST_USER_GET_PROTOCOL_FEATURES:
 			if (msg.size != sizeof(m.payload.u64)) {
 				PMD_DRV_LOG(ERR, "Received bad msg size");
 				return -1;
@@ -592,6 +642,8 @@ struct virtio_user_backend_ops virtio_ops_user = {
 	.set_owner = vhost_user_set_owner,
 	.get_features = vhost_user_get_features,
 	.set_features = vhost_user_set_features,
+	.get_protocol_features = vhost_user_get_protocol_features,
+	.set_protocol_features = vhost_user_set_protocol_features,
 	.send_request = vhost_user_sock,
 	.enable_qp = vhost_user_enable_queue_pair
 };
diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c b/drivers/net/virtio/virtio_user/vhost_vdpa.c
index 22a329526a..f627afbcfc 100644
--- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
+++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
@@ -105,6 +105,18 @@ vhost_vdpa_set_owner(struct virtio_user_dev *dev)
 	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_OWNER, NULL);
 }
 
+static int
+vhost_vdpa_get_backend_features(struct virtio_user_dev *dev, uint64_t *features)
+{
+	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_GET_BACKEND_FEATURES, features);
+}
+
+static int
+vhost_vdpa_set_backend_features(struct virtio_user_dev *dev, uint64_t features)
+{
+	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_BACKEND_FEATURES, &features);
+}
+
 static int
 vhost_vdpa_get_features(struct virtio_user_dev *dev, uint64_t *features)
 {
@@ -447,6 +459,8 @@ struct virtio_user_backend_ops virtio_ops_vdpa = {
 	.set_owner = vhost_vdpa_set_owner,
 	.get_features = vhost_vdpa_get_features,
 	.set_features = vhost_vdpa_set_features,
+	.get_protocol_features = vhost_vdpa_get_backend_features,
+	.set_protocol_features = vhost_vdpa_set_backend_features,
 	.send_request = vhost_vdpa_send_request,
 	.enable_qp = vhost_vdpa_enable_queue_pair,
 	.dma_map = vhost_vdpa_dma_map_batch,
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index 1f3bbae663..45417bbc5d 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -505,22 +505,16 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
 
 		if ((dev->device_features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)) ||
 				(dev->backend_type == VIRTIO_USER_BACKEND_VHOST_VDPA)) {
-			if (dev->ops->send_request(dev,
-					VHOST_USER_GET_PROTOCOL_FEATURES,
-					&protocol_features))
+			if (dev->ops->get_protocol_features(dev, &protocol_features))
 				return -1;
 
 			dev->protocol_features &= protocol_features;
 
-			if (dev->ops->send_request(dev,
-					VHOST_USER_SET_PROTOCOL_FEATURES,
-					&dev->protocol_features))
+			if (dev->ops->set_protocol_features(dev, dev->protocol_features))
 				return -1;
 
-			if (!(dev->protocol_features &
-					(1ULL << VHOST_USER_PROTOCOL_F_MQ)))
-				dev->unsupported_features |=
-					(1ull << VIRTIO_NET_F_MQ);
+			if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
+				dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
 		}
 	} else {
 		/* We just pretend vhost-user can support all these features.
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index 56c379bc15..5e256f4e6d 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -93,23 +93,17 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev)
 
 	if (dev->device_features &
 			(1ULL << VHOST_USER_F_PROTOCOL_FEATURES)) {
-		if (dev->ops->send_request(dev,
-					VHOST_USER_GET_PROTOCOL_FEATURES,
-					&protocol_features))
+		if (dev->ops->get_protocol_features(dev, &protocol_features))
 			return -1;
 
 		/* Offer VHOST_USER_PROTOCOL_F_STATUS */
-		dev->protocol_features |=
-			(1ULL << VHOST_USER_PROTOCOL_F_STATUS);
+		dev->protocol_features |= (1ULL << VHOST_USER_PROTOCOL_F_STATUS);
 		dev->protocol_features &= protocol_features;
 
-		if (dev->ops->send_request(dev,
-					VHOST_USER_SET_PROTOCOL_FEATURES,
-					&dev->protocol_features))
+		if (dev->ops->set_protocol_features(dev, dev->protocol_features))
 			return -1;
 
-		if (!(dev->protocol_features &
-				(1ULL << VHOST_USER_PROTOCOL_F_MQ)))
+		if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
 			dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
 	}
 
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 29/44] net/virtio: add Virtio-user memory tables ops
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (27 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 28/44] net/virtio: add Virtio-user protocol " Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-22  7:34   ` Xia, Chenbo
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 30/44] net/virtio: add Virtio-user vring setting ops Maxime Coquelin
                   ` (14 subsequent siblings)
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch implements a dedicated callback for
preparing and sending memory table to the backends.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_user/vhost.h        |  1 +
 drivers/net/virtio/virtio_user/vhost_kernel.c | 60 ++++++-------
 drivers/net/virtio/virtio_user/vhost_user.c   | 86 ++++++++++++++-----
 drivers/net/virtio/virtio_user/vhost_vdpa.c   |  8 +-
 .../net/virtio/virtio_user/virtio_user_dev.c  |  4 +-
 5 files changed, 101 insertions(+), 58 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/vhost.h b/drivers/net/virtio/virtio_user/vhost.h
index d805526130..463801f563 100644
--- a/drivers/net/virtio/virtio_user/vhost.h
+++ b/drivers/net/virtio/virtio_user/vhost.h
@@ -114,6 +114,7 @@ struct virtio_user_backend_ops {
 	int (*set_features)(struct virtio_user_dev *dev, uint64_t features);
 	int (*get_protocol_features)(struct virtio_user_dev *dev, uint64_t *features);
 	int (*set_protocol_features)(struct virtio_user_dev *dev, uint64_t features);
+	int (*set_memory_table)(struct virtio_user_dev *dev);
 	int (*send_request)(struct virtio_user_dev *dev,
 			    enum vhost_user_request req,
 			    void *arg);
diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c b/drivers/net/virtio/virtio_user/vhost_kernel.c
index f44df8ef1f..2d30f572b6 100644
--- a/drivers/net/virtio/virtio_user/vhost_kernel.c
+++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
@@ -148,17 +148,6 @@ vhost_kernel_set_features(struct virtio_user_dev *dev, uint64_t features)
 	return vhost_kernel_ioctl(dev->vhostfds[0], VHOST_SET_FEATURES, &features);
 }
 
-static uint64_t vhost_req_user_to_kernel[] = {
-	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
-	[VHOST_USER_SET_VRING_CALL] = VHOST_SET_VRING_CALL,
-	[VHOST_USER_SET_VRING_NUM] = VHOST_SET_VRING_NUM,
-	[VHOST_USER_SET_VRING_BASE] = VHOST_SET_VRING_BASE,
-	[VHOST_USER_GET_VRING_BASE] = VHOST_GET_VRING_BASE,
-	[VHOST_USER_SET_VRING_ADDR] = VHOST_SET_VRING_ADDR,
-	[VHOST_USER_SET_VRING_KICK] = VHOST_SET_VRING_KICK,
-	[VHOST_USER_SET_MEM_TABLE] = VHOST_SET_MEM_TABLE,
-};
-
 static int
 add_memseg_list(const struct rte_memseg_list *msl, void *arg)
 {
@@ -193,16 +182,17 @@ add_memseg_list(const struct rte_memseg_list *msl, void *arg)
  * have much more memory regions. Below function will treat each
  * contiguous memory space reserved by DPDK as one region.
  */
-static struct vhost_memory_kernel *
-prepare_vhost_memory_kernel(void)
+static int
+vhost_kernel_set_memory_table(struct virtio_user_dev *dev)
 {
 	struct vhost_memory_kernel *vm;
+	int ret;
 
 	vm = malloc(sizeof(struct vhost_memory_kernel) +
 			max_regions *
 			sizeof(struct vhost_memory_region));
 	if (!vm)
-		return NULL;
+		goto err;
 
 	vm->nregions = 0;
 	vm->padding = 0;
@@ -211,14 +201,34 @@ prepare_vhost_memory_kernel(void)
 	 * The memory lock has already been taken by memory subsystem
 	 * or virtio_user_start_device().
 	 */
-	if (rte_memseg_list_walk_thread_unsafe(add_memseg_list, vm) < 0) {
-		free(vm);
-		return NULL;
-	}
+	ret = rte_memseg_list_walk_thread_unsafe(add_memseg_list, vm);
+	if (ret < 0)
+		goto err_free;
+
+	ret = vhost_kernel_ioctl(dev->vhostfds[0], VHOST_SET_MEM_TABLE, vm);
+	if (ret < 0)
+		goto err_free;
 
-	return vm;
+	free(vm);
+
+	return 0;
+err_free:
+	free(vm);
+err:
+	PMD_DRV_LOG(ERR, "Failed to set memory table");
+	return -1;
 }
 
+static uint64_t vhost_req_user_to_kernel[] = {
+	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
+	[VHOST_USER_SET_VRING_CALL] = VHOST_SET_VRING_CALL,
+	[VHOST_USER_SET_VRING_NUM] = VHOST_SET_VRING_NUM,
+	[VHOST_USER_SET_VRING_BASE] = VHOST_SET_VRING_BASE,
+	[VHOST_USER_GET_VRING_BASE] = VHOST_GET_VRING_BASE,
+	[VHOST_USER_SET_VRING_ADDR] = VHOST_SET_VRING_ADDR,
+	[VHOST_USER_SET_VRING_KICK] = VHOST_SET_VRING_KICK,
+};
+
 static int
 vhost_kernel_send_request(struct virtio_user_dev *dev,
 		   enum vhost_user_request req,
@@ -227,7 +237,6 @@ vhost_kernel_send_request(struct virtio_user_dev *dev,
 	int ret = -1;
 	unsigned int i;
 	uint64_t req_kernel;
-	struct vhost_memory_kernel *vm = NULL;
 	int vhostfd;
 	unsigned int queue_sel;
 
@@ -235,13 +244,6 @@ vhost_kernel_send_request(struct virtio_user_dev *dev,
 
 	req_kernel = vhost_req_user_to_kernel[req];
 
-	if (req_kernel == VHOST_SET_MEM_TABLE) {
-		vm = prepare_vhost_memory_kernel();
-		if (!vm)
-			return -1;
-		arg = (void *)vm;
-	}
-
 	switch (req_kernel) {
 	case VHOST_SET_VRING_NUM:
 	case VHOST_SET_VRING_ADDR:
@@ -271,9 +273,6 @@ vhost_kernel_send_request(struct virtio_user_dev *dev,
 		ret = ioctl(vhostfd, req_kernel, arg);
 	}
 
-	if (vm)
-		free(vm);
-
 	if (ret < 0)
 		PMD_DRV_LOG(ERR, "%s failed: %s",
 			    vhost_msg_strings[req], strerror(errno));
@@ -403,6 +402,7 @@ struct virtio_user_backend_ops virtio_ops_kernel = {
 	.set_owner = vhost_kernel_set_owner,
 	.get_features = vhost_kernel_get_features,
 	.set_features = vhost_kernel_set_features,
+	.set_memory_table = vhost_kernel_set_memory_table,
 	.send_request = vhost_kernel_send_request,
 	.enable_qp = vhost_kernel_enable_queue_pair
 };
diff --git a/drivers/net/virtio/virtio_user/vhost_user.c b/drivers/net/virtio/virtio_user/vhost_user.c
index 4877574f72..94533e31ce 100644
--- a/drivers/net/virtio/virtio_user/vhost_user.c
+++ b/drivers/net/virtio/virtio_user/vhost_user.c
@@ -81,6 +81,9 @@ vhost_user_write(int fd, struct vhost_user_msg *msg, int *fds, int fd_num)
 		r = sendmsg(fd, &msgh, 0);
 	} while (r < 0 && errno == EINTR);
 
+	if (r < 0)
+		PMD_DRV_LOG(ERR, "Failed to send msg: %s", strerror(errno));
+
 	return r;
 }
 
@@ -125,6 +128,39 @@ vhost_user_read(int fd, struct vhost_user_msg *msg)
 	return -1;
 }
 
+static int
+vhost_user_check_reply_ack(struct virtio_user_dev *dev, struct vhost_user_msg *msg)
+{
+	enum vhost_user_request req = msg->request;
+	int ret;
+
+	if (!(msg->flags & VHOST_USER_NEED_REPLY_MASK))
+		return 0;
+
+	ret = vhost_user_read(dev->vhostfd, msg);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to read reply-ack");
+		return -1;
+	}
+
+	if (req != msg->request) {
+		PMD_DRV_LOG(ERR, "Unexpected reply-ack request type (%d)", msg->request);
+		return -1;
+	}
+
+	if (msg->size != sizeof(msg->payload.u64)) {
+		PMD_DRV_LOG(ERR, "Unexpected reply-ack payload size (%d)", msg->size);
+		return -1;
+	}
+
+	if (msg->payload.u64) {
+		PMD_DRV_LOG(ERR, "Slave replied NACK to request type %d", msg->request);
+		return -1;
+	}
+
+	return 0;
+}
+
 static int
 vhost_user_set_owner(struct virtio_user_dev *dev)
 {
@@ -338,25 +374,47 @@ update_memory_region(const struct rte_memseg_list *msl __rte_unused,
 }
 
 static int
-prepare_vhost_memory_user(struct vhost_user_msg *msg, int fds[])
+vhost_user_set_memory_table(struct virtio_user_dev *dev)
 {
 	struct walk_arg wa;
+	int fds[VHOST_MEMORY_MAX_NREGIONS];
+	int ret, fd_num;
+	struct vhost_user_msg msg = {
+		.request = VHOST_USER_SET_MEM_TABLE,
+		.flags = VHOST_USER_VERSION,
+	};
+
+	if (dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK))
+		msg.flags |= VHOST_USER_NEED_REPLY_MASK;
 
 	wa.region_nr = 0;
-	wa.vm = &msg->payload.memory;
+	wa.vm = &msg.payload.memory;
 	wa.fds = fds;
 
 	/*
 	 * The memory lock has already been taken by memory subsystem
 	 * or virtio_user_start_device().
 	 */
-	if (rte_memseg_walk_thread_unsafe(update_memory_region, &wa) < 0)
-		return -1;
+	ret = rte_memseg_walk_thread_unsafe(update_memory_region, &wa);
+	if (ret < 0)
+		goto err;
 
-	msg->payload.memory.nregions = wa.region_nr;
-	msg->payload.memory.padding = 0;
+	fd_num = wa.region_nr;
+	msg.payload.memory.nregions = wa.region_nr;
+	msg.payload.memory.padding = 0;
 
-	return 0;
+	msg.size = sizeof(msg.payload.memory.nregions);
+	msg.size += sizeof(msg.payload.memory.padding);
+	msg.size += fd_num * sizeof(struct vhost_memory_region);
+
+	ret = vhost_user_write(dev->vhostfd, &msg, fds, fd_num);
+	if (ret < 0)
+		goto err;
+
+	return vhost_user_check_reply_ack(dev, &msg);
+err:
+	PMD_DRV_LOG(ERR, "Failed to set memory table");
+	return -1;
 }
 
 static struct vhost_user_msg m;
@@ -369,7 +427,6 @@ const char * const vhost_msg_strings[] = {
 	[VHOST_USER_GET_VRING_BASE] = "VHOST_GET_VRING_BASE",
 	[VHOST_USER_SET_VRING_ADDR] = "VHOST_SET_VRING_ADDR",
 	[VHOST_USER_SET_VRING_KICK] = "VHOST_SET_VRING_KICK",
-	[VHOST_USER_SET_MEM_TABLE] = "VHOST_SET_MEM_TABLE",
 	[VHOST_USER_SET_VRING_ENABLE] = "VHOST_SET_VRING_ENABLE",
 	[VHOST_USER_SET_STATUS] = "VHOST_SET_STATUS",
 	[VHOST_USER_GET_STATUS] = "VHOST_GET_STATUS",
@@ -434,18 +491,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
 	case VHOST_USER_RESET_OWNER:
 		break;
 
-	case VHOST_USER_SET_MEM_TABLE:
-		if (prepare_vhost_memory_user(&msg, fds) < 0)
-			return -1;
-		fd_num = msg.payload.memory.nregions;
-		msg.size = sizeof(m.payload.memory.nregions);
-		msg.size += sizeof(m.payload.memory.padding);
-		msg.size += fd_num * sizeof(struct vhost_memory_region);
-
-		if (has_reply_ack)
-			msg.flags |= VHOST_USER_NEED_REPLY_MASK;
-		break;
-
 	case VHOST_USER_SET_LOG_FD:
 		fds[fd_num++] = *((int *)arg);
 		break;
@@ -644,6 +689,7 @@ struct virtio_user_backend_ops virtio_ops_user = {
 	.set_features = vhost_user_set_features,
 	.get_protocol_features = vhost_user_get_protocol_features,
 	.set_protocol_features = vhost_user_set_protocol_features,
+	.set_memory_table = vhost_user_set_memory_table,
 	.send_request = vhost_user_sock,
 	.enable_qp = vhost_user_enable_queue_pair
 };
diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c b/drivers/net/virtio/virtio_user/vhost_vdpa.c
index f627afbcfc..bd7daebf0c 100644
--- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
+++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
@@ -19,7 +19,6 @@
 #define VHOST_SET_FEATURES _IOW(VHOST_VIRTIO, 0x00, __u64)
 #define VHOST_SET_OWNER _IO(VHOST_VIRTIO, 0x01)
 #define VHOST_RESET_OWNER _IO(VHOST_VIRTIO, 0x02)
-#define VHOST_SET_MEM_TABLE _IOW(VHOST_VIRTIO, 0x03, void *)
 #define VHOST_SET_LOG_BASE _IOW(VHOST_VIRTIO, 0x04, __u64)
 #define VHOST_SET_LOG_FD _IOW(VHOST_VIRTIO, 0x07, int)
 #define VHOST_SET_VRING_NUM _IOW(VHOST_VIRTIO, 0x10, struct vhost_vring_state)
@@ -46,7 +45,6 @@ static uint64_t vhost_req_user_to_vdpa[] = {
 	[VHOST_USER_GET_VRING_BASE] = VHOST_GET_VRING_BASE,
 	[VHOST_USER_SET_VRING_ADDR] = VHOST_SET_VRING_ADDR,
 	[VHOST_USER_SET_VRING_KICK] = VHOST_SET_VRING_KICK,
-	[VHOST_USER_SET_MEM_TABLE] = VHOST_SET_MEM_TABLE,
 	[VHOST_USER_SET_STATUS] = VHOST_VDPA_SET_STATUS,
 	[VHOST_USER_GET_STATUS] = VHOST_VDPA_GET_STATUS,
 	[VHOST_USER_SET_VRING_ENABLE] = VHOST_VDPA_SET_VRING_ENABLE,
@@ -319,7 +317,7 @@ vhost_vdpa_map(const struct rte_memseg_list *msl, const struct rte_memseg *ms,
 }
 
 static int
-vhost_vdpa_dma_map_all(struct virtio_user_dev *dev)
+vhost_vdpa_set_memory_table(struct virtio_user_dev *dev)
 {
 	int ret;
 
@@ -376,9 +374,6 @@ vhost_vdpa_send_request(struct virtio_user_dev *dev,
 
 	req_vdpa = vhost_req_user_to_vdpa[req];
 
-	if (req_vdpa == VHOST_SET_MEM_TABLE)
-		return vhost_vdpa_dma_map_all(dev);
-
 	switch (req_vdpa) {
 	case VHOST_SET_VRING_NUM:
 	case VHOST_SET_VRING_ADDR:
@@ -461,6 +456,7 @@ struct virtio_user_backend_ops virtio_ops_vdpa = {
 	.set_features = vhost_vdpa_set_features,
 	.get_protocol_features = vhost_vdpa_get_backend_features,
 	.set_protocol_features = vhost_vdpa_set_backend_features,
+	.set_memory_table = vhost_vdpa_set_memory_table,
 	.send_request = vhost_vdpa_send_request,
 	.enable_qp = vhost_vdpa_enable_queue_pair,
 	.dma_map = vhost_vdpa_dma_map_batch,
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index 45417bbc5d..cb8f8a872c 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -177,7 +177,7 @@ virtio_user_start_device(struct virtio_user_dev *dev)
 		goto error;
 
 	/* Step 2: share memory regions */
-	ret = dev->ops->send_request(dev, VHOST_USER_SET_MEM_TABLE, NULL);
+	ret = dev->ops->set_memory_table(dev);
 	if (ret < 0)
 		goto error;
 
@@ -352,7 +352,7 @@ virtio_user_mem_event_cb(enum rte_mem_event type __rte_unused,
 		dev->ops->enable_qp(dev, i, 0);
 
 	/* Step 2: update memory regions */
-	dev->ops->send_request(dev, VHOST_USER_SET_MEM_TABLE, NULL);
+	dev->ops->set_memory_table(dev);
 
 	/* Step 3: resume the active queues */
 	for (i = 0; i < dev->queue_pairs; i++)
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 30/44] net/virtio: add Virtio-user vring setting ops
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (28 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 29/44] net/virtio: add Virtio-user memory tables ops Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-22  7:49   ` Xia, Chenbo
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 31/44] net/virtio: add Virtio-user vring file ops Maxime Coquelin
                   ` (13 subsequent siblings)
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch introduces new callbacks for setting
and getting vring state.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_user/vhost.h        |   3 +
 drivers/net/virtio/virtio_user/vhost_kernel.c |  49 +++++++-
 drivers/net/virtio/virtio_user/vhost_user.c   | 113 +++++++++++++-----
 drivers/net/virtio/virtio_user/vhost_vdpa.c   |  41 +++++--
 .../net/virtio/virtio_user/virtio_user_dev.c  |   9 +-
 5 files changed, 165 insertions(+), 50 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/vhost.h b/drivers/net/virtio/virtio_user/vhost.h
index 463801f563..2d433d5966 100644
--- a/drivers/net/virtio/virtio_user/vhost.h
+++ b/drivers/net/virtio/virtio_user/vhost.h
@@ -115,6 +115,9 @@ struct virtio_user_backend_ops {
 	int (*get_protocol_features)(struct virtio_user_dev *dev, uint64_t *features);
 	int (*set_protocol_features)(struct virtio_user_dev *dev, uint64_t features);
 	int (*set_memory_table)(struct virtio_user_dev *dev);
+	int (*set_vring_num)(struct virtio_user_dev *dev, struct vhost_vring_state *state);
+	int (*set_vring_base)(struct virtio_user_dev *dev, struct vhost_vring_state *state);
+	int (*get_vring_base)(struct virtio_user_dev *dev, struct vhost_vring_state *state);
 	int (*send_request)(struct virtio_user_dev *dev,
 			    enum vhost_user_request req,
 			    void *arg);
diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c b/drivers/net/virtio/virtio_user/vhost_kernel.c
index 2d30f572b6..e12fe74f46 100644
--- a/drivers/net/virtio/virtio_user/vhost_kernel.c
+++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
@@ -219,12 +219,49 @@ vhost_kernel_set_memory_table(struct virtio_user_dev *dev)
 	return -1;
 }
 
+static int
+vhost_kernel_set_vring(struct virtio_user_dev *dev, uint64_t req, struct vhost_vring_state *state)
+{
+	int ret, fd;
+	unsigned int index = state->index;
+
+	/* Convert from queue index to queue-pair & offset */
+	fd = dev->vhostfds[state->index / 2];
+	state->index %= 2;
+
+	ret = vhost_kernel_ioctl(fd, req, state);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to set vring (request %" PRIu64 ")", req);
+		return -1;
+	}
+
+	/* restore index back to queue index */
+	state->index = index;
+
+	return 0;
+}
+
+static int
+vhost_kernel_set_vring_num(struct virtio_user_dev *dev, struct vhost_vring_state *state)
+{
+	return vhost_kernel_set_vring(dev, VHOST_SET_VRING_NUM, state);
+}
+
+static int
+vhost_kernel_set_vring_base(struct virtio_user_dev *dev, struct vhost_vring_state *state)
+{
+	return vhost_kernel_set_vring(dev, VHOST_SET_VRING_BASE, state);
+}
+
+static int
+vhost_kernel_get_vring_base(struct virtio_user_dev *dev, struct vhost_vring_state *state)
+{
+	return vhost_kernel_set_vring(dev, VHOST_GET_VRING_BASE, state);
+}
+
 static uint64_t vhost_req_user_to_kernel[] = {
 	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
 	[VHOST_USER_SET_VRING_CALL] = VHOST_SET_VRING_CALL,
-	[VHOST_USER_SET_VRING_NUM] = VHOST_SET_VRING_NUM,
-	[VHOST_USER_SET_VRING_BASE] = VHOST_SET_VRING_BASE,
-	[VHOST_USER_GET_VRING_BASE] = VHOST_GET_VRING_BASE,
 	[VHOST_USER_SET_VRING_ADDR] = VHOST_SET_VRING_ADDR,
 	[VHOST_USER_SET_VRING_KICK] = VHOST_SET_VRING_KICK,
 };
@@ -245,10 +282,7 @@ vhost_kernel_send_request(struct virtio_user_dev *dev,
 	req_kernel = vhost_req_user_to_kernel[req];
 
 	switch (req_kernel) {
-	case VHOST_SET_VRING_NUM:
 	case VHOST_SET_VRING_ADDR:
-	case VHOST_SET_VRING_BASE:
-	case VHOST_GET_VRING_BASE:
 	case VHOST_SET_VRING_KICK:
 	case VHOST_SET_VRING_CALL:
 		queue_sel = *(unsigned int *)arg;
@@ -403,6 +437,9 @@ struct virtio_user_backend_ops virtio_ops_kernel = {
 	.get_features = vhost_kernel_get_features,
 	.set_features = vhost_kernel_set_features,
 	.set_memory_table = vhost_kernel_set_memory_table,
+	.set_vring_num = vhost_kernel_set_vring_num,
+	.set_vring_base = vhost_kernel_set_vring_base,
+	.get_vring_base = vhost_kernel_get_vring_base,
 	.send_request = vhost_kernel_send_request,
 	.enable_qp = vhost_kernel_enable_queue_pair
 };
diff --git a/drivers/net/virtio/virtio_user/vhost_user.c b/drivers/net/virtio/virtio_user/vhost_user.c
index 94533e31ce..c39be24ce4 100644
--- a/drivers/net/virtio/virtio_user/vhost_user.c
+++ b/drivers/net/virtio/virtio_user/vhost_user.c
@@ -417,17 +417,94 @@ vhost_user_set_memory_table(struct virtio_user_dev *dev)
 	return -1;
 }
 
+static int
+vhost_user_set_vring(struct virtio_user_dev *dev, enum vhost_user_request req,
+		struct vhost_vring_state *state)
+{
+	int ret;
+	struct vhost_user_msg msg = {
+		.request = req,
+		.flags = VHOST_USER_VERSION,
+		.size = sizeof(*state),
+		.payload.state = *state,
+	};
+
+	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to set vring state (request %d)", req);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+vhost_user_set_vring_enable(struct virtio_user_dev *dev, struct vhost_vring_state *state)
+{
+	return vhost_user_set_vring(dev, VHOST_USER_SET_VRING_ENABLE, state);
+}
+
+static int
+vhost_user_set_vring_num(struct virtio_user_dev *dev, struct vhost_vring_state *state)
+{
+	return vhost_user_set_vring(dev, VHOST_USER_SET_VRING_NUM, state);
+}
+
+static int
+vhost_user_set_vring_base(struct virtio_user_dev *dev, struct vhost_vring_state *state)
+{
+	return vhost_user_set_vring(dev, VHOST_USER_SET_VRING_BASE, state);
+}
+
+static int
+vhost_user_get_vring_base(struct virtio_user_dev *dev, struct vhost_vring_state *state)
+{
+	int ret;
+	struct vhost_user_msg msg;
+	unsigned int index = state->index;
+
+	ret = vhost_user_set_vring(dev, VHOST_USER_GET_VRING_BASE, state);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to send request");
+		goto err;
+	}
+
+	ret = vhost_user_read(dev->vhostfd, &msg);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to read reply");
+		goto err;
+	}
+
+	if (msg.request != VHOST_USER_GET_VRING_BASE) {
+		PMD_DRV_LOG(ERR, "Unexpected request type (%d)", msg.request);
+		goto err;
+	}
+
+	if (msg.size != sizeof(*state)) {
+		PMD_DRV_LOG(ERR, "Unexpected payload size (%u)", msg.size);
+		goto err;
+	}
+
+	if (msg.payload.state.index != index) {
+		PMD_DRV_LOG(ERR, "Unexpected ring index (%u)", state->index);
+		goto err;
+	}
+
+	*state = msg.payload.state;
+
+	return 0;
+err:
+	PMD_DRV_LOG(ERR, "Failed to get vring base");
+	return -1;
+}
+
 static struct vhost_user_msg m;
 
 const char * const vhost_msg_strings[] = {
 	[VHOST_USER_RESET_OWNER] = "VHOST_RESET_OWNER",
 	[VHOST_USER_SET_VRING_CALL] = "VHOST_SET_VRING_CALL",
-	[VHOST_USER_SET_VRING_NUM] = "VHOST_SET_VRING_NUM",
-	[VHOST_USER_SET_VRING_BASE] = "VHOST_SET_VRING_BASE",
-	[VHOST_USER_GET_VRING_BASE] = "VHOST_GET_VRING_BASE",
 	[VHOST_USER_SET_VRING_ADDR] = "VHOST_SET_VRING_ADDR",
 	[VHOST_USER_SET_VRING_KICK] = "VHOST_SET_VRING_KICK",
-	[VHOST_USER_SET_VRING_ENABLE] = "VHOST_SET_VRING_ENABLE",
 	[VHOST_USER_SET_STATUS] = "VHOST_SET_STATUS",
 	[VHOST_USER_GET_STATUS] = "VHOST_GET_STATUS",
 };
@@ -495,19 +572,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
 		fds[fd_num++] = *((int *)arg);
 		break;
 
-	case VHOST_USER_SET_VRING_NUM:
-	case VHOST_USER_SET_VRING_BASE:
-	case VHOST_USER_SET_VRING_ENABLE:
-		memcpy(&msg.payload.state, arg, sizeof(msg.payload.state));
-		msg.size = sizeof(m.payload.state);
-		break;
-
-	case VHOST_USER_GET_VRING_BASE:
-		memcpy(&msg.payload.state, arg, sizeof(msg.payload.state));
-		msg.size = sizeof(m.payload.state);
-		need_reply = 1;
-		break;
-
 	case VHOST_USER_SET_VRING_ADDR:
 		memcpy(&msg.payload.addr, arg, sizeof(msg.payload.addr));
 		msg.size = sizeof(m.payload.addr);
@@ -556,14 +620,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
 			}
 			*((__u64 *)arg) = msg.payload.u64;
 			break;
-		case VHOST_USER_GET_VRING_BASE:
-			if (msg.size != sizeof(m.payload.state)) {
-				PMD_DRV_LOG(ERR, "Received bad msg size");
-				return -1;
-			}
-			memcpy(arg, &msg.payload.state,
-			       sizeof(struct vhost_vring_state));
-			break;
 		default:
 			/* Reply-ack handling */
 			if (msg.size != sizeof(m.payload.u64)) {
@@ -671,10 +727,10 @@ vhost_user_enable_queue_pair(struct virtio_user_dev *dev,
 	for (i = 0; i < 2; ++i) {
 		struct vhost_vring_state state = {
 			.index = pair_idx * 2 + i,
-			.num   = enable,
+			.num = enable,
 		};
 
-		if (vhost_user_sock(dev, VHOST_USER_SET_VRING_ENABLE, &state))
+		if (vhost_user_set_vring_enable(dev, &state))
 			return -1;
 	}
 
@@ -690,6 +746,9 @@ struct virtio_user_backend_ops virtio_ops_user = {
 	.get_protocol_features = vhost_user_get_protocol_features,
 	.set_protocol_features = vhost_user_set_protocol_features,
 	.set_memory_table = vhost_user_set_memory_table,
+	.set_vring_num = vhost_user_set_vring_num,
+	.set_vring_base = vhost_user_set_vring_base,
+	.get_vring_base = vhost_user_get_vring_base,
 	.send_request = vhost_user_sock,
 	.enable_qp = vhost_user_enable_queue_pair
 };
diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c b/drivers/net/virtio/virtio_user/vhost_vdpa.c
index bd7daebf0c..323751093a 100644
--- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
+++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
@@ -32,24 +32,17 @@
 #define VHOST_VDPA_GET_DEVICE_ID _IOR(VHOST_VIRTIO, 0x70, __u32)
 #define VHOST_VDPA_GET_STATUS _IOR(VHOST_VIRTIO, 0x71, __u8)
 #define VHOST_VDPA_SET_STATUS _IOW(VHOST_VIRTIO, 0x72, __u8)
-#define VHOST_VDPA_SET_VRING_ENABLE	_IOW(VHOST_VIRTIO, 0x75, \
-					     struct vhost_vring_state)
+#define VHOST_VDPA_SET_VRING_ENABLE _IOW(VHOST_VIRTIO, 0x75, struct vhost_vring_state)
 #define VHOST_SET_BACKEND_FEATURES _IOW(VHOST_VIRTIO, 0x25, __u64)
 #define VHOST_GET_BACKEND_FEATURES _IOR(VHOST_VIRTIO, 0x26, __u64)
 
 static uint64_t vhost_req_user_to_vdpa[] = {
 	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
 	[VHOST_USER_SET_VRING_CALL] = VHOST_SET_VRING_CALL,
-	[VHOST_USER_SET_VRING_NUM] = VHOST_SET_VRING_NUM,
-	[VHOST_USER_SET_VRING_BASE] = VHOST_SET_VRING_BASE,
-	[VHOST_USER_GET_VRING_BASE] = VHOST_GET_VRING_BASE,
 	[VHOST_USER_SET_VRING_ADDR] = VHOST_SET_VRING_ADDR,
 	[VHOST_USER_SET_VRING_KICK] = VHOST_SET_VRING_KICK,
 	[VHOST_USER_SET_STATUS] = VHOST_VDPA_SET_STATUS,
 	[VHOST_USER_GET_STATUS] = VHOST_VDPA_GET_STATUS,
-	[VHOST_USER_SET_VRING_ENABLE] = VHOST_VDPA_SET_VRING_ENABLE,
-	[VHOST_USER_GET_PROTOCOL_FEATURES] = VHOST_GET_BACKEND_FEATURES,
-	[VHOST_USER_SET_PROTOCOL_FEATURES] = VHOST_SET_BACKEND_FEATURES,
 };
 
 /* no alignment requirement */
@@ -347,6 +340,30 @@ vhost_vdpa_set_memory_table(struct virtio_user_dev *dev)
 	return ret;
 }
 
+static int
+vhost_vdpa_set_vring_enable(struct virtio_user_dev *dev, struct vhost_vring_state *state)
+{
+	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_VDPA_SET_VRING_ENABLE, state);
+}
+
+static int
+vhost_vdpa_set_vring_num(struct virtio_user_dev *dev, struct vhost_vring_state *state)
+{
+	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_NUM, state);
+}
+
+static int
+vhost_vdpa_set_vring_base(struct virtio_user_dev *dev, struct vhost_vring_state *state)
+{
+	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_BASE, state);
+}
+
+static int
+vhost_vdpa_get_vring_base(struct virtio_user_dev *dev, struct vhost_vring_state *state)
+{
+	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_GET_VRING_BASE, state);
+}
+
 /* with below features, vhost vdpa does not need to do the checksum and TSO,
  * these info will be passed to virtio_user through virtio net header.
  */
@@ -375,10 +392,7 @@ vhost_vdpa_send_request(struct virtio_user_dev *dev,
 	req_vdpa = vhost_req_user_to_vdpa[req];
 
 	switch (req_vdpa) {
-	case VHOST_SET_VRING_NUM:
 	case VHOST_SET_VRING_ADDR:
-	case VHOST_SET_VRING_BASE:
-	case VHOST_GET_VRING_BASE:
 	case VHOST_SET_VRING_KICK:
 	case VHOST_SET_VRING_CALL:
 		PMD_DRV_LOG(DEBUG, "vhostfd=%d, index=%u",
@@ -440,7 +454,7 @@ vhost_vdpa_enable_queue_pair(struct virtio_user_dev *dev,
 			.num   = enable,
 		};
 
-		if (vhost_vdpa_send_request(dev, VHOST_USER_SET_VRING_ENABLE, &state))
+		if (vhost_vdpa_set_vring_enable(dev, &state))
 			return -1;
 	}
 
@@ -457,6 +471,9 @@ struct virtio_user_backend_ops virtio_ops_vdpa = {
 	.get_protocol_features = vhost_vdpa_get_backend_features,
 	.set_protocol_features = vhost_vdpa_set_backend_features,
 	.set_memory_table = vhost_vdpa_set_memory_table,
+	.set_vring_num = vhost_vdpa_set_vring_num,
+	.set_vring_base = vhost_vdpa_set_vring_base,
+	.get_vring_base = vhost_vdpa_get_vring_base,
 	.send_request = vhost_vdpa_send_request,
 	.enable_qp = vhost_vdpa_enable_queue_pair,
 	.dma_map = vhost_vdpa_dma_map_batch,
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index cb8f8a872c..0b30c10016 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -73,13 +73,13 @@ virtio_user_kick_queue(struct virtio_user_dev *dev, uint32_t queue_sel)
 
 	state.index = queue_sel;
 	state.num = vring->num;
-	dev->ops->send_request(dev, VHOST_USER_SET_VRING_NUM, &state);
+	dev->ops->set_vring_num(dev, &state);
 
 	state.index = queue_sel;
 	state.num = 0; /* no reservation */
 	if (dev->features & (1ULL << VIRTIO_F_RING_PACKED))
 		state.num |= (1 << 15);
-	dev->ops->send_request(dev, VHOST_USER_SET_VRING_BASE, &state);
+	dev->ops->set_vring_base(dev, &state);
 
 	dev->ops->send_request(dev, VHOST_USER_SET_VRING_ADDR, &addr);
 
@@ -218,9 +218,8 @@ int virtio_user_stop_device(struct virtio_user_dev *dev)
 	/* Stop the backend. */
 	for (i = 0; i < dev->max_queue_pairs * 2; ++i) {
 		state.index = i;
-		if (dev->ops->send_request(dev, VHOST_USER_GET_VRING_BASE,
-					   &state) < 0) {
-			PMD_DRV_LOG(ERR, "get_vring_base failed, index=%u\n",
+		if (dev->ops->get_vring_base(dev, &state) < 0) {
+			PMD_DRV_LOG(ERR, "get_vring_base failed, index=%u",
 				    i);
 			error = -1;
 			goto out;
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 31/44] net/virtio: add Virtio-user vring file ops
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (29 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 30/44] net/virtio: add Virtio-user vring setting ops Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-22  8:01   ` Xia, Chenbo
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 32/44] net/virtio: add Virtio-user vring address ops Maxime Coquelin
                   ` (12 subsequent siblings)
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch introduces new callbacks for setting
vring files (kick and call).

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_user/vhost.h        |  2 +
 drivers/net/virtio/virtio_user/vhost_kernel.c | 41 +++++++++++++++--
 drivers/net/virtio/virtio_user/vhost_user.c   | 46 +++++++++++++++++--
 drivers/net/virtio/virtio_user/vhost_vdpa.c   | 18 ++++++--
 .../net/virtio/virtio_user/virtio_user_dev.c  |  4 +-
 5 files changed, 97 insertions(+), 14 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/vhost.h b/drivers/net/virtio/virtio_user/vhost.h
index 2d433d5966..94c524547e 100644
--- a/drivers/net/virtio/virtio_user/vhost.h
+++ b/drivers/net/virtio/virtio_user/vhost.h
@@ -118,6 +118,8 @@ struct virtio_user_backend_ops {
 	int (*set_vring_num)(struct virtio_user_dev *dev, struct vhost_vring_state *state);
 	int (*set_vring_base)(struct virtio_user_dev *dev, struct vhost_vring_state *state);
 	int (*get_vring_base)(struct virtio_user_dev *dev, struct vhost_vring_state *state);
+	int (*set_vring_call)(struct virtio_user_dev *dev, struct vhost_vring_file *file);
+	int (*set_vring_kick)(struct virtio_user_dev *dev, struct vhost_vring_file *file);
 	int (*send_request)(struct virtio_user_dev *dev,
 			    enum vhost_user_request req,
 			    void *arg);
diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c b/drivers/net/virtio/virtio_user/vhost_kernel.c
index e12fe74f46..dc5358bc15 100644
--- a/drivers/net/virtio/virtio_user/vhost_kernel.c
+++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
@@ -259,11 +259,44 @@ vhost_kernel_get_vring_base(struct virtio_user_dev *dev, struct vhost_vring_stat
 	return vhost_kernel_set_vring(dev, VHOST_GET_VRING_BASE, state);
 }
 
+static int
+vhost_kernel_set_vring_file(struct virtio_user_dev *dev, uint64_t req,
+		struct vhost_vring_file *file)
+{
+	int ret, fd;
+	unsigned int index = file->index;
+
+	/* Convert from queue index to queue-pair & offset */
+	fd = dev->vhostfds[file->index / 2];
+	file->index %= 2;
+
+	ret = vhost_kernel_ioctl(fd, req, file);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to set vring file (request %" PRIu64 ")", req);
+		return -1;
+	}
+
+	/* restore index back to queue index */
+	file->index = index;
+
+	return 0;
+}
+
+static int
+vhost_kernel_set_vring_kick(struct virtio_user_dev *dev, struct vhost_vring_file *file)
+{
+	return vhost_kernel_set_vring_file(dev, VHOST_SET_VRING_KICK, file);
+}
+
+static int
+vhost_kernel_set_vring_call(struct virtio_user_dev *dev, struct vhost_vring_file *file)
+{
+	return vhost_kernel_set_vring_file(dev, VHOST_SET_VRING_CALL, file);
+}
+
 static uint64_t vhost_req_user_to_kernel[] = {
 	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
-	[VHOST_USER_SET_VRING_CALL] = VHOST_SET_VRING_CALL,
 	[VHOST_USER_SET_VRING_ADDR] = VHOST_SET_VRING_ADDR,
-	[VHOST_USER_SET_VRING_KICK] = VHOST_SET_VRING_KICK,
 };
 
 static int
@@ -283,8 +316,6 @@ vhost_kernel_send_request(struct virtio_user_dev *dev,
 
 	switch (req_kernel) {
 	case VHOST_SET_VRING_ADDR:
-	case VHOST_SET_VRING_KICK:
-	case VHOST_SET_VRING_CALL:
 		queue_sel = *(unsigned int *)arg;
 		vhostfd = dev->vhostfds[queue_sel / 2];
 		*(unsigned int *)arg = queue_sel % 2;
@@ -440,6 +471,8 @@ struct virtio_user_backend_ops virtio_ops_kernel = {
 	.set_vring_num = vhost_kernel_set_vring_num,
 	.set_vring_base = vhost_kernel_set_vring_base,
 	.get_vring_base = vhost_kernel_get_vring_base,
+	.set_vring_call = vhost_kernel_set_vring_call,
+	.set_vring_kick = vhost_kernel_set_vring_kick,
 	.send_request = vhost_kernel_send_request,
 	.enable_qp = vhost_kernel_enable_queue_pair
 };
diff --git a/drivers/net/virtio/virtio_user/vhost_user.c b/drivers/net/virtio/virtio_user/vhost_user.c
index c39be24ce4..06d17cadcb 100644
--- a/drivers/net/virtio/virtio_user/vhost_user.c
+++ b/drivers/net/virtio/virtio_user/vhost_user.c
@@ -498,13 +498,51 @@ vhost_user_get_vring_base(struct virtio_user_dev *dev, struct vhost_vring_state
 	return -1;
 }
 
+static int
+vhost_user_set_vring_file(struct virtio_user_dev *dev, enum vhost_user_request req,
+		struct vhost_vring_file *file)
+{
+	int ret;
+	int fd = file->fd;
+	int num_fd = 0;
+	struct vhost_user_msg msg = {
+		.request = req,
+		.flags = VHOST_USER_VERSION,
+		.size = sizeof(msg.payload.u64),
+		.payload.u64 = file->index & VHOST_USER_VRING_IDX_MASK,
+	};
+
+	if (fd >= 0)
+		num_fd++;
+	else
+		msg.payload.u64 |= VHOST_USER_VRING_NOFD_MASK;
+
+	ret = vhost_user_write(dev->vhostfd, &msg, &fd, num_fd);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to set vring file (request %d)", req);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+vhost_user_set_vring_call(struct virtio_user_dev *dev, struct vhost_vring_file *file)
+{
+	return vhost_user_set_vring_file(dev, VHOST_USER_SET_VRING_CALL, file);
+}
+
+static int
+vhost_user_set_vring_kick(struct virtio_user_dev *dev, struct vhost_vring_file *file)
+{
+	return vhost_user_set_vring_file(dev, VHOST_USER_SET_VRING_KICK, file);
+}
+
 static struct vhost_user_msg m;
 
 const char * const vhost_msg_strings[] = {
 	[VHOST_USER_RESET_OWNER] = "VHOST_RESET_OWNER",
-	[VHOST_USER_SET_VRING_CALL] = "VHOST_SET_VRING_CALL",
 	[VHOST_USER_SET_VRING_ADDR] = "VHOST_SET_VRING_ADDR",
-	[VHOST_USER_SET_VRING_KICK] = "VHOST_SET_VRING_KICK",
 	[VHOST_USER_SET_STATUS] = "VHOST_SET_STATUS",
 	[VHOST_USER_GET_STATUS] = "VHOST_GET_STATUS",
 };
@@ -577,8 +615,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
 		msg.size = sizeof(m.payload.addr);
 		break;
 
-	case VHOST_USER_SET_VRING_KICK:
-	case VHOST_USER_SET_VRING_CALL:
 	case VHOST_USER_SET_VRING_ERR:
 		file = arg;
 		msg.payload.u64 = file->index & VHOST_USER_VRING_IDX_MASK;
@@ -749,6 +785,8 @@ struct virtio_user_backend_ops virtio_ops_user = {
 	.set_vring_num = vhost_user_set_vring_num,
 	.set_vring_base = vhost_user_set_vring_base,
 	.get_vring_base = vhost_user_get_vring_base,
+	.set_vring_call = vhost_user_set_vring_call,
+	.set_vring_kick = vhost_user_set_vring_kick,
 	.send_request = vhost_user_sock,
 	.enable_qp = vhost_user_enable_queue_pair
 };
diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c b/drivers/net/virtio/virtio_user/vhost_vdpa.c
index 323751093a..304a808b55 100644
--- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
+++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
@@ -38,9 +38,7 @@
 
 static uint64_t vhost_req_user_to_vdpa[] = {
 	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
-	[VHOST_USER_SET_VRING_CALL] = VHOST_SET_VRING_CALL,
 	[VHOST_USER_SET_VRING_ADDR] = VHOST_SET_VRING_ADDR,
-	[VHOST_USER_SET_VRING_KICK] = VHOST_SET_VRING_KICK,
 	[VHOST_USER_SET_STATUS] = VHOST_VDPA_SET_STATUS,
 	[VHOST_USER_GET_STATUS] = VHOST_VDPA_GET_STATUS,
 };
@@ -364,6 +362,18 @@ vhost_vdpa_get_vring_base(struct virtio_user_dev *dev, struct vhost_vring_state
 	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_GET_VRING_BASE, state);
 }
 
+static int
+vhost_vdpa_set_vring_call(struct virtio_user_dev *dev, struct vhost_vring_file *file)
+{
+	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_CALL, file);
+}
+
+static int
+vhost_vdpa_set_vring_kick(struct virtio_user_dev *dev, struct vhost_vring_file *file)
+{
+	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_KICK, file);
+}
+
 /* with below features, vhost vdpa does not need to do the checksum and TSO,
  * these info will be passed to virtio_user through virtio net header.
  */
@@ -393,8 +403,6 @@ vhost_vdpa_send_request(struct virtio_user_dev *dev,
 
 	switch (req_vdpa) {
 	case VHOST_SET_VRING_ADDR:
-	case VHOST_SET_VRING_KICK:
-	case VHOST_SET_VRING_CALL:
 		PMD_DRV_LOG(DEBUG, "vhostfd=%d, index=%u",
 			    dev->vhostfd, *(unsigned int *)arg);
 		break;
@@ -474,6 +482,8 @@ struct virtio_user_backend_ops virtio_ops_vdpa = {
 	.set_vring_num = vhost_vdpa_set_vring_num,
 	.set_vring_base = vhost_vdpa_set_vring_base,
 	.get_vring_base = vhost_vdpa_get_vring_base,
+	.set_vring_call = vhost_vdpa_set_vring_call,
+	.set_vring_kick = vhost_vdpa_set_vring_kick,
 	.send_request = vhost_vdpa_send_request,
 	.enable_qp = vhost_vdpa_enable_queue_pair,
 	.dma_map = vhost_vdpa_dma_map_batch,
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index 0b30c10016..4383e403da 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -40,7 +40,7 @@ virtio_user_create_queue(struct virtio_user_dev *dev, uint32_t queue_sel)
 
 	file.index = queue_sel;
 	file.fd = dev->callfds[queue_sel];
-	dev->ops->send_request(dev, VHOST_USER_SET_VRING_CALL, &file);
+	dev->ops->set_vring_call(dev, &file);
 
 	return 0;
 }
@@ -89,7 +89,7 @@ virtio_user_kick_queue(struct virtio_user_dev *dev, uint32_t queue_sel)
 	 */
 	file.index = queue_sel;
 	file.fd = dev->kickfds[queue_sel];
-	dev->ops->send_request(dev, VHOST_USER_SET_VRING_KICK, &file);
+	dev->ops->set_vring_kick(dev, &file);
 
 	return 0;
 }
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 32/44] net/virtio: add Virtio-user vring address ops
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (30 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 31/44] net/virtio: add Virtio-user vring file ops Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-22  8:02   ` Xia, Chenbo
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 33/44] net/virtio: add Virtio-user status ops Maxime Coquelin
                   ` (11 subsequent siblings)
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch introduces a new callback for setting
vrings addresses.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_user/vhost.h        |  1 +
 drivers/net/virtio/virtio_user/vhost_kernel.c | 32 +++++++++++++------
 drivers/net/virtio/virtio_user/vhost_user.c   | 29 +++++++++++++----
 drivers/net/virtio/virtio_user/vhost_vdpa.c   |  8 ++++-
 .../net/virtio/virtio_user/virtio_user_dev.c  |  2 +-
 5 files changed, 55 insertions(+), 17 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/vhost.h b/drivers/net/virtio/virtio_user/vhost.h
index 94c524547e..19040dfdc2 100644
--- a/drivers/net/virtio/virtio_user/vhost.h
+++ b/drivers/net/virtio/virtio_user/vhost.h
@@ -120,6 +120,7 @@ struct virtio_user_backend_ops {
 	int (*get_vring_base)(struct virtio_user_dev *dev, struct vhost_vring_state *state);
 	int (*set_vring_call)(struct virtio_user_dev *dev, struct vhost_vring_file *file);
 	int (*set_vring_kick)(struct virtio_user_dev *dev, struct vhost_vring_file *file);
+	int (*set_vring_addr)(struct virtio_user_dev *dev, struct vhost_vring_addr *addr);
 	int (*send_request)(struct virtio_user_dev *dev,
 			    enum vhost_user_request req,
 			    void *arg);
diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c b/drivers/net/virtio/virtio_user/vhost_kernel.c
index dc5358bc15..566f42f0cb 100644
--- a/drivers/net/virtio/virtio_user/vhost_kernel.c
+++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
@@ -294,9 +294,30 @@ vhost_kernel_set_vring_call(struct virtio_user_dev *dev, struct vhost_vring_file
 	return vhost_kernel_set_vring_file(dev, VHOST_SET_VRING_CALL, file);
 }
 
+static int
+vhost_kernel_set_vring_addr(struct virtio_user_dev *dev, struct vhost_vring_addr *addr)
+{
+	int ret, fd;
+	unsigned int index = addr->index;
+
+	/* Convert from queue index to queue-pair & offset */
+	fd = dev->vhostfds[addr->index / 2];
+	addr->index %= 2;
+
+	ret = vhost_kernel_ioctl(fd, VHOST_SET_VRING_ADDR, addr);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to set vring address");
+		return -1;
+	}
+
+	/* restore index back to queue index */
+	addr->index = index;
+
+	return 0;
+}
+
 static uint64_t vhost_req_user_to_kernel[] = {
 	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
-	[VHOST_USER_SET_VRING_ADDR] = VHOST_SET_VRING_ADDR,
 };
 
 static int
@@ -308,20 +329,12 @@ vhost_kernel_send_request(struct virtio_user_dev *dev,
 	unsigned int i;
 	uint64_t req_kernel;
 	int vhostfd;
-	unsigned int queue_sel;
 
 	PMD_DRV_LOG(INFO, "%s", vhost_msg_strings[req]);
 
 	req_kernel = vhost_req_user_to_kernel[req];
 
 	switch (req_kernel) {
-	case VHOST_SET_VRING_ADDR:
-		queue_sel = *(unsigned int *)arg;
-		vhostfd = dev->vhostfds[queue_sel / 2];
-		*(unsigned int *)arg = queue_sel % 2;
-		PMD_DRV_LOG(DEBUG, "vhostfd=%d, index=%u",
-			    vhostfd, *(unsigned int *)arg);
-		break;
 	default:
 		vhostfd = -1;
 	}
@@ -473,6 +486,7 @@ struct virtio_user_backend_ops virtio_ops_kernel = {
 	.get_vring_base = vhost_kernel_get_vring_base,
 	.set_vring_call = vhost_kernel_set_vring_call,
 	.set_vring_kick = vhost_kernel_set_vring_kick,
+	.set_vring_addr = vhost_kernel_set_vring_addr,
 	.send_request = vhost_kernel_send_request,
 	.enable_qp = vhost_kernel_enable_queue_pair
 };
diff --git a/drivers/net/virtio/virtio_user/vhost_user.c b/drivers/net/virtio/virtio_user/vhost_user.c
index 06d17cadcb..ca70a8a4e7 100644
--- a/drivers/net/virtio/virtio_user/vhost_user.c
+++ b/drivers/net/virtio/virtio_user/vhost_user.c
@@ -538,11 +538,32 @@ vhost_user_set_vring_kick(struct virtio_user_dev *dev, struct vhost_vring_file *
 	return vhost_user_set_vring_file(dev, VHOST_USER_SET_VRING_KICK, file);
 }
 
+
+static int
+vhost_user_set_vring_addr(struct virtio_user_dev *dev, struct vhost_vring_addr *addr)
+{
+	int ret;
+	struct vhost_user_msg msg = {
+		.request = VHOST_USER_SET_VRING_ADDR,
+		.flags = VHOST_USER_VERSION,
+		.size = sizeof(*addr),
+		.payload.addr = *addr,
+	};
+
+	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to send vring addresses");
+		return -1;
+	}
+
+	return 0;
+}
+
+
 static struct vhost_user_msg m;
 
 const char * const vhost_msg_strings[] = {
 	[VHOST_USER_RESET_OWNER] = "VHOST_RESET_OWNER",
-	[VHOST_USER_SET_VRING_ADDR] = "VHOST_SET_VRING_ADDR",
 	[VHOST_USER_SET_STATUS] = "VHOST_SET_STATUS",
 	[VHOST_USER_GET_STATUS] = "VHOST_GET_STATUS",
 };
@@ -610,11 +631,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
 		fds[fd_num++] = *((int *)arg);
 		break;
 
-	case VHOST_USER_SET_VRING_ADDR:
-		memcpy(&msg.payload.addr, arg, sizeof(msg.payload.addr));
-		msg.size = sizeof(m.payload.addr);
-		break;
-
 	case VHOST_USER_SET_VRING_ERR:
 		file = arg;
 		msg.payload.u64 = file->index & VHOST_USER_VRING_IDX_MASK;
@@ -787,6 +803,7 @@ struct virtio_user_backend_ops virtio_ops_user = {
 	.get_vring_base = vhost_user_get_vring_base,
 	.set_vring_call = vhost_user_set_vring_call,
 	.set_vring_kick = vhost_user_set_vring_kick,
+	.set_vring_addr = vhost_user_set_vring_addr,
 	.send_request = vhost_user_sock,
 	.enable_qp = vhost_user_enable_queue_pair
 };
diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c b/drivers/net/virtio/virtio_user/vhost_vdpa.c
index 304a808b55..1ec6bb26f2 100644
--- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
+++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
@@ -38,7 +38,6 @@
 
 static uint64_t vhost_req_user_to_vdpa[] = {
 	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
-	[VHOST_USER_SET_VRING_ADDR] = VHOST_SET_VRING_ADDR,
 	[VHOST_USER_SET_STATUS] = VHOST_VDPA_SET_STATUS,
 	[VHOST_USER_GET_STATUS] = VHOST_VDPA_GET_STATUS,
 };
@@ -374,6 +373,12 @@ vhost_vdpa_set_vring_kick(struct virtio_user_dev *dev, struct vhost_vring_file *
 	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_KICK, file);
 }
 
+static int
+vhost_vdpa_set_vring_addr(struct virtio_user_dev *dev, struct vhost_vring_addr *addr)
+{
+	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_ADDR, addr);
+}
+
 /* with below features, vhost vdpa does not need to do the checksum and TSO,
  * these info will be passed to virtio_user through virtio net header.
  */
@@ -484,6 +489,7 @@ struct virtio_user_backend_ops virtio_ops_vdpa = {
 	.get_vring_base = vhost_vdpa_get_vring_base,
 	.set_vring_call = vhost_vdpa_set_vring_call,
 	.set_vring_kick = vhost_vdpa_set_vring_kick,
+	.set_vring_addr = vhost_vdpa_set_vring_addr,
 	.send_request = vhost_vdpa_send_request,
 	.enable_qp = vhost_vdpa_enable_queue_pair,
 	.dma_map = vhost_vdpa_dma_map_batch,
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index 4383e403da..7e365d0570 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -81,7 +81,7 @@ virtio_user_kick_queue(struct virtio_user_dev *dev, uint32_t queue_sel)
 		state.num |= (1 << 15);
 	dev->ops->set_vring_base(dev, &state);
 
-	dev->ops->send_request(dev, VHOST_USER_SET_VRING_ADDR, &addr);
+	dev->ops->set_vring_addr(dev, &addr);
 
 	/* Of all per virtqueue MSGs, make sure VHOST_USER_SET_VRING_KICK comes
 	 * lastly because vhost depends on this msg to judge if
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 33/44] net/virtio: add Virtio-user status ops
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (31 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 32/44] net/virtio: add Virtio-user vring address ops Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-22  8:02   ` Xia, Chenbo
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 34/44] net/virtio: remove useless request ops Maxime Coquelin
                   ` (10 subsequent siblings)
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch introduces new callbacks to
get and set the device status.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_user/vhost.h        |   2 +
 drivers/net/virtio/virtio_user/vhost_kernel.c |  14 ++
 drivers/net/virtio/virtio_user/vhost_user.c   | 121 +++++++++++++-----
 drivers/net/virtio/virtio_user/vhost_vdpa.c   |  16 ++-
 .../net/virtio/virtio_user/virtio_user_dev.c  |  42 ++----
 5 files changed, 129 insertions(+), 66 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/vhost.h b/drivers/net/virtio/virtio_user/vhost.h
index 19040dfdc2..c896f0836d 100644
--- a/drivers/net/virtio/virtio_user/vhost.h
+++ b/drivers/net/virtio/virtio_user/vhost.h
@@ -121,6 +121,8 @@ struct virtio_user_backend_ops {
 	int (*set_vring_call)(struct virtio_user_dev *dev, struct vhost_vring_file *file);
 	int (*set_vring_kick)(struct virtio_user_dev *dev, struct vhost_vring_file *file);
 	int (*set_vring_addr)(struct virtio_user_dev *dev, struct vhost_vring_addr *addr);
+	int (*get_status)(struct virtio_user_dev *dev, uint8_t *status);
+	int (*set_status)(struct virtio_user_dev *dev, uint8_t status);
 	int (*send_request)(struct virtio_user_dev *dev,
 			    enum vhost_user_request req,
 			    void *arg);
diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c b/drivers/net/virtio/virtio_user/vhost_kernel.c
index 566f42f0cb..d85358fc34 100644
--- a/drivers/net/virtio/virtio_user/vhost_kernel.c
+++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
@@ -316,6 +316,18 @@ vhost_kernel_set_vring_addr(struct virtio_user_dev *dev, struct vhost_vring_addr
 	return 0;
 }
 
+static int
+vhost_kernel_get_status(struct virtio_user_dev *dev __rte_unused, uint8_t *status __rte_unused)
+{
+	return -ENOTSUP;
+}
+
+static int
+vhost_kernel_set_status(struct virtio_user_dev *dev __rte_unused, uint8_t status __rte_unused)
+{
+	return -ENOTSUP;
+}
+
 static uint64_t vhost_req_user_to_kernel[] = {
 	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
 };
@@ -487,6 +499,8 @@ struct virtio_user_backend_ops virtio_ops_kernel = {
 	.set_vring_call = vhost_kernel_set_vring_call,
 	.set_vring_kick = vhost_kernel_set_vring_kick,
 	.set_vring_addr = vhost_kernel_set_vring_addr,
+	.get_status = vhost_kernel_get_status,
+	.set_status = vhost_kernel_set_status,
 	.send_request = vhost_kernel_send_request,
 	.enable_qp = vhost_kernel_enable_queue_pair
 };
diff --git a/drivers/net/virtio/virtio_user/vhost_user.c b/drivers/net/virtio/virtio_user/vhost_user.c
index ca70a8a4e7..cb0cd1cea8 100644
--- a/drivers/net/virtio/virtio_user/vhost_user.c
+++ b/drivers/net/virtio/virtio_user/vhost_user.c
@@ -559,13 +559,100 @@ vhost_user_set_vring_addr(struct virtio_user_dev *dev, struct vhost_vring_addr *
 	return 0;
 }
 
+static int
+vhost_user_get_status(struct virtio_user_dev *dev, uint8_t *status)
+{
+	int ret;
+	struct vhost_user_msg msg = {
+		.request = VHOST_USER_GET_STATUS,
+		.flags = VHOST_USER_VERSION,
+	};
+
+	/*
+	 * If features have not been negotiated, we don't know if the backend
+	 * supports protocol features
+	 */
+	if (!(dev->status & VIRTIO_CONFIG_STATUS_FEATURES_OK))
+		return -ENOTSUP;
+
+	/* Status protocol feature requires protocol features support */
+	if (!(dev->device_features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)))
+		return -ENOTSUP;
+
+	if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_STATUS)))
+		return -ENOTSUP;
+
+	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to send request");
+		goto err;
+	}
+
+	ret = vhost_user_read(dev->vhostfd, &msg);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to recv request");
+		goto err;
+	}
+
+	if (msg.request != VHOST_USER_GET_STATUS) {
+		PMD_DRV_LOG(ERR, "Unexpected request type (%d)", msg.request);
+		goto err;
+	}
+
+	if (msg.size != sizeof(msg.payload.u64)) {
+		PMD_DRV_LOG(ERR, "Unexpected payload size (%u)", msg.size);
+		goto err;
+	}
+
+	*status = (uint8_t)msg.payload.u64;
+
+	return 0;
+err:
+	PMD_DRV_LOG(ERR, "Failed to get device status");
+	return -1;
+}
+
+static int
+vhost_user_set_status(struct virtio_user_dev *dev, uint8_t status)
+{
+	int ret;
+	struct vhost_user_msg msg = {
+		.request = VHOST_USER_SET_STATUS,
+		.flags = VHOST_USER_VERSION,
+		.size = sizeof(msg.payload.u64),
+		.payload.u64 = status,
+	};
+
+	/*
+	 * If features have not been negotiated, we don't know if the backend
+	 * supports protocol features
+	 */
+	if (!(dev->status & VIRTIO_CONFIG_STATUS_FEATURES_OK))
+		return -ENOTSUP;
+
+	/* Status protocol feature requires protocol features support */
+	if (!(dev->device_features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)))
+		return -ENOTSUP;
+
+	if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_STATUS)))
+		return -ENOTSUP;
+
+	if (dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK))
+		msg.flags |= VHOST_USER_NEED_REPLY_MASK;
+
+	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to send get status request");
+		return -1;
+	}
+
+	return vhost_user_check_reply_ack(dev, &msg);
+}
 
 static struct vhost_user_msg m;
 
 const char * const vhost_msg_strings[] = {
 	[VHOST_USER_RESET_OWNER] = "VHOST_RESET_OWNER",
-	[VHOST_USER_SET_STATUS] = "VHOST_SET_STATUS",
-	[VHOST_USER_GET_STATUS] = "VHOST_GET_STATUS",
 };
 
 static int
@@ -576,7 +663,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
 	struct vhost_user_msg msg;
 	struct vhost_vring_file *file = 0;
 	int need_reply = 0;
-	int has_reply_ack = 0;
 	int fds[VHOST_MEMORY_MAX_NREGIONS];
 	int fd_num = 0;
 	int vhostfd = dev->vhostfd;
@@ -588,31 +674,11 @@ vhost_user_sock(struct virtio_user_dev *dev,
 	if (dev->is_server && vhostfd < 0)
 		return -1;
 
-	if (dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK))
-		has_reply_ack = 1;
-
 	msg.request = req;
 	msg.flags = VHOST_USER_VERSION;
 	msg.size = 0;
 
 	switch (req) {
-	case VHOST_USER_GET_STATUS:
-		if (!(dev->status & VIRTIO_CONFIG_STATUS_FEATURES_OK) ||
-		    (!(dev->protocol_features &
-				(1ULL << VHOST_USER_PROTOCOL_F_STATUS))))
-			return -ENOTSUP;
-		need_reply = 1;
-		break;
-
-	case VHOST_USER_SET_STATUS:
-		if (!(dev->status & VIRTIO_CONFIG_STATUS_FEATURES_OK) ||
-		    (!(dev->protocol_features &
-				(1ULL << VHOST_USER_PROTOCOL_F_STATUS))))
-			return -ENOTSUP;
-
-		if (has_reply_ack)
-			msg.flags |= VHOST_USER_NEED_REPLY_MASK;
-		/* Fallthrough */
 	case VHOST_USER_SET_LOG_BASE:
 		msg.payload.u64 = *((__u64 *)arg);
 		msg.size = sizeof(m.payload.u64);
@@ -665,13 +731,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
 		}
 
 		switch (req) {
-		case VHOST_USER_GET_STATUS:
-			if (msg.size != sizeof(m.payload.u64)) {
-				PMD_DRV_LOG(ERR, "Received bad msg size");
-				return -1;
-			}
-			*((__u64 *)arg) = msg.payload.u64;
-			break;
 		default:
 			/* Reply-ack handling */
 			if (msg.size != sizeof(m.payload.u64)) {
@@ -804,6 +863,8 @@ struct virtio_user_backend_ops virtio_ops_user = {
 	.set_vring_call = vhost_user_set_vring_call,
 	.set_vring_kick = vhost_user_set_vring_kick,
 	.set_vring_addr = vhost_user_set_vring_addr,
+	.get_status = vhost_user_get_status,
+	.set_status = vhost_user_set_status,
 	.send_request = vhost_user_sock,
 	.enable_qp = vhost_user_enable_queue_pair
 };
diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c b/drivers/net/virtio/virtio_user/vhost_vdpa.c
index 1ec6bb26f2..8ebc679f1b 100644
--- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
+++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
@@ -38,8 +38,6 @@
 
 static uint64_t vhost_req_user_to_vdpa[] = {
 	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
-	[VHOST_USER_SET_STATUS] = VHOST_VDPA_SET_STATUS,
-	[VHOST_USER_GET_STATUS] = VHOST_VDPA_GET_STATUS,
 };
 
 /* no alignment requirement */
@@ -379,6 +377,18 @@ vhost_vdpa_set_vring_addr(struct virtio_user_dev *dev, struct vhost_vring_addr *
 	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_ADDR, addr);
 }
 
+static int
+vhost_vdpa_get_status(struct virtio_user_dev *dev, uint8_t *status)
+{
+	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_VDPA_GET_STATUS, status);
+}
+
+static int
+vhost_vdpa_set_status(struct virtio_user_dev *dev, uint8_t status)
+{
+	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_VDPA_SET_STATUS, &status);
+}
+
 /* with below features, vhost vdpa does not need to do the checksum and TSO,
  * these info will be passed to virtio_user through virtio net header.
  */
@@ -490,6 +500,8 @@ struct virtio_user_backend_ops virtio_ops_vdpa = {
 	.set_vring_call = vhost_vdpa_set_vring_call,
 	.set_vring_kick = vhost_vdpa_set_vring_kick,
 	.set_vring_addr = vhost_vdpa_set_vring_addr,
+	.get_status = vhost_vdpa_get_status,
+	.set_status = vhost_vdpa_set_status,
 	.send_request = vhost_vdpa_send_request,
 	.enable_qp = vhost_vdpa_enable_queue_pair,
 	.dma_map = vhost_vdpa_dma_map_batch,
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index 7e365d0570..33a25f4684 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -814,21 +814,12 @@ int
 virtio_user_dev_set_status(struct virtio_user_dev *dev, uint8_t status)
 {
 	int ret;
-	uint64_t arg = status;
 
 	pthread_mutex_lock(&dev->mutex);
 	dev->status = status;
-	if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER)
-		ret = dev->ops->send_request(dev,
-				VHOST_USER_SET_STATUS, &arg);
-	else if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_VDPA)
-		ret = dev->ops->send_request(dev,
-				VHOST_USER_SET_STATUS, &status);
-	else
-		ret = -ENOTSUP;
-
+	ret = dev->ops->set_status(dev, status);
 	if (ret && ret != -ENOTSUP) {
-		PMD_INIT_LOG(ERR, "VHOST_USER_SET_STATUS failed (%d): %s", ret,
+		PMD_INIT_LOG(ERR, "Virtio-user set status failed (%d): %s", ret,
 			     strerror(errno));
 	}
 
@@ -839,29 +830,13 @@ virtio_user_dev_set_status(struct virtio_user_dev *dev, uint8_t status)
 int
 virtio_user_dev_update_status(struct virtio_user_dev *dev)
 {
-	uint64_t ret;
+	int ret;
 	uint8_t status;
-	int err;
 
 	pthread_mutex_lock(&dev->mutex);
-	if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER) {
-		err = dev->ops->send_request(dev, VHOST_USER_GET_STATUS, &ret);
-		if (!err && ret > UINT8_MAX) {
-			PMD_INIT_LOG(ERR, "Invalid VHOST_USER_GET_STATUS "
-					"response 0x%" PRIx64 "\n", ret);
-			err = -1;
-			goto error;
-		}
 
-		status = ret;
-	} else if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_VDPA) {
-		err = dev->ops->send_request(dev, VHOST_USER_GET_STATUS,
-				&status);
-	} else {
-		err = -ENOTSUP;
-	}
-
-	if (!err) {
+	ret = dev->ops->get_status(dev, &status);
+	if (!ret) {
 		dev->status = status;
 		PMD_INIT_LOG(DEBUG, "Updated Device Status(0x%08x):\n"
 			"\t-RESET: %u\n"
@@ -879,12 +854,11 @@ virtio_user_dev_update_status(struct virtio_user_dev *dev)
 			!!(dev->status & VIRTIO_CONFIG_STATUS_FEATURES_OK),
 			!!(dev->status & VIRTIO_CONFIG_STATUS_DEV_NEED_RESET),
 			!!(dev->status & VIRTIO_CONFIG_STATUS_FAILED));
-	} else if (err != -ENOTSUP) {
-		PMD_INIT_LOG(ERR, "VHOST_USER_GET_STATUS failed (%d): %s", err,
+	} else if (ret != -ENOTSUP) {
+		PMD_INIT_LOG(ERR, "Virtio-user get status failed (%d): %s", ret,
 			     strerror(errno));
 	}
 
-error:
 	pthread_mutex_unlock(&dev->mutex);
-	return err;
+	return ret;
 }
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 34/44] net/virtio: remove useless request ops
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (32 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 33/44] net/virtio: add Virtio-user status ops Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-22  8:10   ` Xia, Chenbo
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 35/44] net/virtio: improve Virtio-user errors handling Maxime Coquelin
                   ` (9 subsequent siblings)
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

Now that all the ops have been implemented, we
can remove the send_request ops for all backends.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_user/vhost.h        |  15 +--
 drivers/net/virtio/virtio_user/vhost_kernel.c |  43 --------
 drivers/net/virtio/virtio_user/vhost_user.c   | 102 ------------------
 drivers/net/virtio/virtio_user/vhost_vdpa.c   |  49 ---------
 4 files changed, 3 insertions(+), 206 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/vhost.h b/drivers/net/virtio/virtio_user/vhost.h
index c896f0836d..6294b8afee 100644
--- a/drivers/net/virtio/virtio_user/vhost.h
+++ b/drivers/net/virtio/virtio_user/vhost.h
@@ -96,8 +96,6 @@ enum vhost_user_request {
 #define VHOST_BACKEND_F_IOTLB_BATCH 2
 #endif
 
-extern const char * const vhost_msg_strings[VHOST_USER_MAX];
-
 struct vhost_memory_region {
 	uint64_t guest_phys_addr;
 	uint64_t memory_size; /* bytes */
@@ -123,16 +121,9 @@ struct virtio_user_backend_ops {
 	int (*set_vring_addr)(struct virtio_user_dev *dev, struct vhost_vring_addr *addr);
 	int (*get_status)(struct virtio_user_dev *dev, uint8_t *status);
 	int (*set_status)(struct virtio_user_dev *dev, uint8_t status);
-	int (*send_request)(struct virtio_user_dev *dev,
-			    enum vhost_user_request req,
-			    void *arg);
-	int (*enable_qp)(struct virtio_user_dev *dev,
-			 uint16_t pair_idx,
-			 int enable);
-	int (*dma_map)(struct virtio_user_dev *dev, void *addr,
-				  uint64_t iova, size_t len);
-	int (*dma_unmap)(struct virtio_user_dev *dev, void *addr,
-				  uint64_t iova, size_t len);
+	int (*enable_qp)(struct virtio_user_dev *dev, uint16_t pair_idx, int enable);
+	int (*dma_map)(struct virtio_user_dev *dev, void *addr, uint64_t iova, size_t len);
+	int (*dma_unmap)(struct virtio_user_dev *dev, void *addr, uint64_t iova, size_t len);
 };
 
 extern struct virtio_user_backend_ops virtio_ops_user;
diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c b/drivers/net/virtio/virtio_user/vhost_kernel.c
index d85358fc34..68f0c0b83d 100644
--- a/drivers/net/virtio/virtio_user/vhost_kernel.c
+++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
@@ -328,48 +328,6 @@ vhost_kernel_set_status(struct virtio_user_dev *dev __rte_unused, uint8_t status
 	return -ENOTSUP;
 }
 
-static uint64_t vhost_req_user_to_kernel[] = {
-	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
-};
-
-static int
-vhost_kernel_send_request(struct virtio_user_dev *dev,
-		   enum vhost_user_request req,
-		   void *arg)
-{
-	int ret = -1;
-	unsigned int i;
-	uint64_t req_kernel;
-	int vhostfd;
-
-	PMD_DRV_LOG(INFO, "%s", vhost_msg_strings[req]);
-
-	req_kernel = vhost_req_user_to_kernel[req];
-
-	switch (req_kernel) {
-	default:
-		vhostfd = -1;
-	}
-	if (vhostfd == -1) {
-		for (i = 0; i < dev->max_queue_pairs; ++i) {
-			if (dev->vhostfds[i] < 0)
-				continue;
-
-			ret = ioctl(dev->vhostfds[i], req_kernel, arg);
-			if (ret < 0)
-				break;
-		}
-	} else {
-		ret = ioctl(vhostfd, req_kernel, arg);
-	}
-
-	if (ret < 0)
-		PMD_DRV_LOG(ERR, "%s failed: %s",
-			    vhost_msg_strings[req], strerror(errno));
-
-	return ret;
-}
-
 /**
  * Set up environment to talk with a vhost kernel backend.
  *
@@ -501,6 +459,5 @@ struct virtio_user_backend_ops virtio_ops_kernel = {
 	.set_vring_addr = vhost_kernel_set_vring_addr,
 	.get_status = vhost_kernel_get_status,
 	.set_status = vhost_kernel_set_status,
-	.send_request = vhost_kernel_send_request,
 	.enable_qp = vhost_kernel_enable_queue_pair
 };
diff --git a/drivers/net/virtio/virtio_user/vhost_user.c b/drivers/net/virtio/virtio_user/vhost_user.c
index cb0cd1cea8..d46e25b64b 100644
--- a/drivers/net/virtio/virtio_user/vhost_user.c
+++ b/drivers/net/virtio/virtio_user/vhost_user.c
@@ -649,107 +649,6 @@ vhost_user_set_status(struct virtio_user_dev *dev, uint8_t status)
 	return vhost_user_check_reply_ack(dev, &msg);
 }
 
-static struct vhost_user_msg m;
-
-const char * const vhost_msg_strings[] = {
-	[VHOST_USER_RESET_OWNER] = "VHOST_RESET_OWNER",
-};
-
-static int
-vhost_user_sock(struct virtio_user_dev *dev,
-		enum vhost_user_request req,
-		void *arg)
-{
-	struct vhost_user_msg msg;
-	struct vhost_vring_file *file = 0;
-	int need_reply = 0;
-	int fds[VHOST_MEMORY_MAX_NREGIONS];
-	int fd_num = 0;
-	int vhostfd = dev->vhostfd;
-
-	RTE_SET_USED(m);
-
-	PMD_DRV_LOG(INFO, "%s", vhost_msg_strings[req]);
-
-	if (dev->is_server && vhostfd < 0)
-		return -1;
-
-	msg.request = req;
-	msg.flags = VHOST_USER_VERSION;
-	msg.size = 0;
-
-	switch (req) {
-	case VHOST_USER_SET_LOG_BASE:
-		msg.payload.u64 = *((__u64 *)arg);
-		msg.size = sizeof(m.payload.u64);
-		break;
-
-	case VHOST_USER_SET_FEATURES:
-		msg.payload.u64 = *((__u64 *)arg) | (dev->device_features &
-			(1ULL << VHOST_USER_F_PROTOCOL_FEATURES));
-		msg.size = sizeof(m.payload.u64);
-		break;
-
-	case VHOST_USER_RESET_OWNER:
-		break;
-
-	case VHOST_USER_SET_LOG_FD:
-		fds[fd_num++] = *((int *)arg);
-		break;
-
-	case VHOST_USER_SET_VRING_ERR:
-		file = arg;
-		msg.payload.u64 = file->index & VHOST_USER_VRING_IDX_MASK;
-		msg.size = sizeof(m.payload.u64);
-		if (file->fd > 0)
-			fds[fd_num++] = file->fd;
-		else
-			msg.payload.u64 |= VHOST_USER_VRING_NOFD_MASK;
-		break;
-
-	default:
-		PMD_DRV_LOG(ERR, "trying to send unhandled msg type");
-		return -1;
-	}
-
-	if (vhost_user_write(vhostfd, &msg, fds, fd_num) < 0) {
-		PMD_DRV_LOG(ERR, "%s failed: %s",
-			    vhost_msg_strings[req], strerror(errno));
-		return -1;
-	}
-
-	if (need_reply || msg.flags & VHOST_USER_NEED_REPLY_MASK) {
-		if (vhost_user_read(vhostfd, &msg) < 0) {
-			PMD_DRV_LOG(ERR, "Received msg failed: %s",
-				    strerror(errno));
-			return -1;
-		}
-
-		if (req != msg.request) {
-			PMD_DRV_LOG(ERR, "Received unexpected msg type");
-			return -1;
-		}
-
-		switch (req) {
-		default:
-			/* Reply-ack handling */
-			if (msg.size != sizeof(m.payload.u64)) {
-				PMD_DRV_LOG(ERR, "Received bad msg size");
-				return -1;
-			}
-
-			if (msg.payload.u64 != 0) {
-				PMD_DRV_LOG(ERR, "Slave replied NACK");
-				return -1;
-			}
-
-			break;
-		}
-	}
-
-	return 0;
-}
-
 #define MAX_VIRTIO_USER_BACKLOG 1
 static int
 virtio_user_start_server(struct virtio_user_dev *dev, struct sockaddr_un *un)
@@ -865,6 +764,5 @@ struct virtio_user_backend_ops virtio_ops_user = {
 	.set_vring_addr = vhost_user_set_vring_addr,
 	.get_status = vhost_user_get_status,
 	.set_status = vhost_user_set_status,
-	.send_request = vhost_user_sock,
 	.enable_qp = vhost_user_enable_queue_pair
 };
diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c b/drivers/net/virtio/virtio_user/vhost_vdpa.c
index 8ebc679f1b..7fb1249569 100644
--- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
+++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
@@ -36,10 +36,6 @@
 #define VHOST_SET_BACKEND_FEATURES _IOW(VHOST_VIRTIO, 0x25, __u64)
 #define VHOST_GET_BACKEND_FEATURES _IOR(VHOST_VIRTIO, 0x26, __u64)
 
-static uint64_t vhost_req_user_to_vdpa[] = {
-	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
-};
-
 /* no alignment requirement */
 struct vhost_iotlb_msg {
 	uint64_t iova;
@@ -389,50 +385,6 @@ vhost_vdpa_set_status(struct virtio_user_dev *dev, uint8_t status)
 	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_VDPA_SET_STATUS, &status);
 }
 
-/* with below features, vhost vdpa does not need to do the checksum and TSO,
- * these info will be passed to virtio_user through virtio net header.
- */
-#define VHOST_VDPA_GUEST_OFFLOADS_MASK	\
-	((1ULL << VIRTIO_NET_F_GUEST_CSUM) |	\
-	 (1ULL << VIRTIO_NET_F_GUEST_TSO4) |	\
-	 (1ULL << VIRTIO_NET_F_GUEST_TSO6) |	\
-	 (1ULL << VIRTIO_NET_F_GUEST_ECN)  |	\
-	 (1ULL << VIRTIO_NET_F_GUEST_UFO))
-
-#define VHOST_VDPA_HOST_OFFLOADS_MASK		\
-	((1ULL << VIRTIO_NET_F_HOST_TSO4) |	\
-	 (1ULL << VIRTIO_NET_F_HOST_TSO6) |	\
-	 (1ULL << VIRTIO_NET_F_CSUM))
-
-static int
-vhost_vdpa_send_request(struct virtio_user_dev *dev,
-		   enum vhost_user_request req,
-		   void *arg)
-{
-	int ret = -1;
-	uint64_t req_vdpa;
-
-	PMD_DRV_LOG(INFO, "%s", vhost_msg_strings[req]);
-
-	req_vdpa = vhost_req_user_to_vdpa[req];
-
-	switch (req_vdpa) {
-	case VHOST_SET_VRING_ADDR:
-		PMD_DRV_LOG(DEBUG, "vhostfd=%d, index=%u",
-			    dev->vhostfd, *(unsigned int *)arg);
-		break;
-	default:
-		break;
-	}
-
-	ret = ioctl(dev->vhostfd, req_vdpa, arg);
-	if (ret < 0)
-		PMD_DRV_LOG(ERR, "%s failed: %s",
-			    vhost_msg_strings[req], strerror(errno));
-
-	return ret;
-}
-
 /**
  * Set up environment to talk with a vhost vdpa backend.
  *
@@ -502,7 +454,6 @@ struct virtio_user_backend_ops virtio_ops_vdpa = {
 	.set_vring_addr = vhost_vdpa_set_vring_addr,
 	.get_status = vhost_vdpa_get_status,
 	.set_status = vhost_vdpa_set_status,
-	.send_request = vhost_vdpa_send_request,
 	.enable_qp = vhost_vdpa_enable_queue_pair,
 	.dma_map = vhost_vdpa_dma_map_batch,
 	.dma_unmap = vhost_vdpa_dma_unmap_batch,
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 35/44] net/virtio: improve Virtio-user errors handling
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (33 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 34/44] net/virtio: remove useless request ops Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-22  8:10   ` Xia, Chenbo
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 36/44] net/virtio: move Vhost-user reqs to Vhost-user backend Maxime Coquelin
                   ` (8 subsequent siblings)
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch adds error logs and propagates errors reported
by the backend. It also adds the device path in error logs
to make it easier to distinguish which device is facing the
issue.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 .../net/virtio/virtio_user/virtio_user_dev.c  | 154 ++++++++++++------
 1 file changed, 104 insertions(+), 50 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index 33a25f4684..95204ea955 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -37,10 +37,15 @@ virtio_user_create_queue(struct virtio_user_dev *dev, uint32_t queue_sel)
 	 * pair.
 	 */
 	struct vhost_vring_file file;
+	int ret;
 
 	file.index = queue_sel;
 	file.fd = dev->callfds[queue_sel];
-	dev->ops->set_vring_call(dev, &file);
+	ret = dev->ops->set_vring_call(dev, &file);
+	if (ret < 0) {
+		PMD_INIT_LOG(ERR, "(%s) Failed to create queue %u\n", dev->path, queue_sel);
+		return -1;
+	}
 
 	return 0;
 }
@@ -48,6 +53,7 @@ virtio_user_create_queue(struct virtio_user_dev *dev, uint32_t queue_sel)
 static int
 virtio_user_kick_queue(struct virtio_user_dev *dev, uint32_t queue_sel)
 {
+	int ret;
 	struct vhost_vring_file file;
 	struct vhost_vring_state state;
 	struct vring *vring = &dev->vrings[queue_sel];
@@ -73,15 +79,21 @@ virtio_user_kick_queue(struct virtio_user_dev *dev, uint32_t queue_sel)
 
 	state.index = queue_sel;
 	state.num = vring->num;
-	dev->ops->set_vring_num(dev, &state);
+	ret = dev->ops->set_vring_num(dev, &state);
+	if (ret < 0)
+		goto err;
 
 	state.index = queue_sel;
 	state.num = 0; /* no reservation */
 	if (dev->features & (1ULL << VIRTIO_F_RING_PACKED))
 		state.num |= (1 << 15);
-	dev->ops->set_vring_base(dev, &state);
+	ret = dev->ops->set_vring_base(dev, &state);
+	if (ret < 0)
+		goto err;
 
-	dev->ops->set_vring_addr(dev, &addr);
+	ret = dev->ops->set_vring_addr(dev, &addr);
+	if (ret < 0)
+		goto err;
 
 	/* Of all per virtqueue MSGs, make sure VHOST_USER_SET_VRING_KICK comes
 	 * lastly because vhost depends on this msg to judge if
@@ -89,9 +101,15 @@ virtio_user_kick_queue(struct virtio_user_dev *dev, uint32_t queue_sel)
 	 */
 	file.index = queue_sel;
 	file.fd = dev->kickfds[queue_sel];
-	dev->ops->set_vring_kick(dev, &file);
+	ret = dev->ops->set_vring_kick(dev, &file);
+	if (ret < 0)
+		goto err;
 
 	return 0;
+err:
+	PMD_INIT_LOG(ERR, "(%s) Failed to kick queue %u\n", dev->path, queue_sel);
+
+	return -1;
 }
 
 static int
@@ -103,14 +121,14 @@ virtio_user_queue_setup(struct virtio_user_dev *dev,
 	for (i = 0; i < dev->max_queue_pairs; ++i) {
 		queue_sel = 2 * i + VTNET_SQ_RQ_QUEUE_IDX;
 		if (fn(dev, queue_sel) < 0) {
-			PMD_DRV_LOG(INFO, "setup rx vq fails: %u", i);
+			PMD_DRV_LOG(ERR, "(%s) setup rx vq %u failed", dev->path, i);
 			return -1;
 		}
 	}
 	for (i = 0; i < dev->max_queue_pairs; ++i) {
 		queue_sel = 2 * i + VTNET_SQ_TQ_QUEUE_IDX;
 		if (fn(dev, queue_sel) < 0) {
-			PMD_DRV_LOG(INFO, "setup tx vq fails: %u", i);
+			PMD_DRV_LOG(INFO, "(%s) setup tx vq %u failed", dev->path, i);
 			return -1;
 		}
 	}
@@ -144,7 +162,7 @@ virtio_user_dev_set_features(struct virtio_user_dev *dev)
 	ret = dev->ops->set_features(dev, features);
 	if (ret < 0)
 		goto error;
-	PMD_DRV_LOG(INFO, "set features: %" PRIx64, features);
+	PMD_DRV_LOG(INFO, "(%s) set features: 0x%" PRIx64, dev->path, features);
 error:
 	pthread_mutex_unlock(&dev->mutex);
 
@@ -172,9 +190,10 @@ virtio_user_start_device(struct virtio_user_dev *dev)
 	rte_mcfg_mem_read_lock();
 	pthread_mutex_lock(&dev->mutex);
 
+	/* Vhost-user client not connected yet, will start later */
 	if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER &&
 			dev->vhostfd < 0)
-		goto error;
+		goto out;
 
 	/* Step 2: share memory regions */
 	ret = dev->ops->set_memory_table(dev);
@@ -182,15 +201,19 @@ virtio_user_start_device(struct virtio_user_dev *dev)
 		goto error;
 
 	/* Step 3: kick queues */
-	if (virtio_user_queue_setup(dev, virtio_user_kick_queue) < 0)
+	ret = virtio_user_queue_setup(dev, virtio_user_kick_queue);
+	if (ret < 0)
 		goto error;
 
 	/* Step 4: enable queues
 	 * we enable the 1st queue pair by default.
 	 */
-	dev->ops->enable_qp(dev, 0, 1);
+	ret = dev->ops->enable_qp(dev, 0, 1);
+	if (ret < 0)
+		goto error;
 
 	dev->started = true;
+out:
 	pthread_mutex_unlock(&dev->mutex);
 	rte_mcfg_mem_read_unlock();
 
@@ -198,6 +221,9 @@ virtio_user_start_device(struct virtio_user_dev *dev)
 error:
 	pthread_mutex_unlock(&dev->mutex);
 	rte_mcfg_mem_read_unlock();
+
+	PMD_INIT_LOG(ERR, "(%s) Failed to start device\n", dev->path);
+
 	/* TODO: free resource here or caller to check */
 	return -1;
 }
@@ -206,31 +232,40 @@ int virtio_user_stop_device(struct virtio_user_dev *dev)
 {
 	struct vhost_vring_state state;
 	uint32_t i;
-	int error = 0;
+	int ret;
 
 	pthread_mutex_lock(&dev->mutex);
 	if (!dev->started)
 		goto out;
 
-	for (i = 0; i < dev->max_queue_pairs; ++i)
-		dev->ops->enable_qp(dev, i, 0);
+	for (i = 0; i < dev->max_queue_pairs; ++i) {
+		ret = dev->ops->enable_qp(dev, i, 0);
+		if (ret < 0)
+			goto err;
+	}
 
 	/* Stop the backend. */
 	for (i = 0; i < dev->max_queue_pairs * 2; ++i) {
 		state.index = i;
-		if (dev->ops->get_vring_base(dev, &state) < 0) {
-			PMD_DRV_LOG(ERR, "get_vring_base failed, index=%u",
-				    i);
-			error = -1;
-			goto out;
+		ret = dev->ops->get_vring_base(dev, &state);
+		if (ret < 0) {
+			PMD_DRV_LOG(ERR, "(%s) get_vring_base failed, index=%u", dev->path, i);
+			goto err;
 		}
 	}
 
 	dev->started = false;
+
 out:
 	pthread_mutex_unlock(&dev->mutex);
 
-	return error;
+	return 0;
+err:
+	pthread_mutex_unlock(&dev->mutex);
+
+	PMD_INIT_LOG(ERR, "(%s) Failed to stop device\n", dev->path);
+
+	return -1;
 }
 
 static inline void
@@ -270,13 +305,13 @@ virtio_user_dev_init_notify(struct virtio_user_dev *dev)
 		 */
 		callfd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
 		if (callfd < 0) {
-			PMD_DRV_LOG(ERR, "callfd error, %s", strerror(errno));
+			PMD_DRV_LOG(ERR, "(%s) callfd error, %s", dev->path, strerror(errno));
 			break;
 		}
 		kickfd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
 		if (kickfd < 0) {
 			close(callfd);
-			PMD_DRV_LOG(ERR, "kickfd error, %s", strerror(errno));
+			PMD_DRV_LOG(ERR, "(%s) kickfd error, %s", dev->path, strerror(errno));
 			break;
 		}
 		dev->callfds[i] = callfd;
@@ -304,7 +339,7 @@ virtio_user_fill_intr_handle(struct virtio_user_dev *dev)
 	if (!eth_dev->intr_handle) {
 		eth_dev->intr_handle = malloc(sizeof(*eth_dev->intr_handle));
 		if (!eth_dev->intr_handle) {
-			PMD_DRV_LOG(ERR, "fail to allocate intr_handle");
+			PMD_DRV_LOG(ERR, "(%s) failed to allocate intr_handle", dev->path);
 			return -1;
 		}
 		memset(eth_dev->intr_handle, 0, sizeof(*eth_dev->intr_handle));
@@ -335,6 +370,7 @@ virtio_user_mem_event_cb(enum rte_mem_event type __rte_unused,
 	struct virtio_user_dev *dev = arg;
 	struct rte_memseg_list *msl;
 	uint16_t i;
+	int ret = 0;
 
 	/* ignore externally allocated memory */
 	msl = rte_mem_virt2memseg_list(addr);
@@ -347,18 +383,29 @@ virtio_user_mem_event_cb(enum rte_mem_event type __rte_unused,
 		goto exit;
 
 	/* Step 1: pause the active queues */
-	for (i = 0; i < dev->queue_pairs; i++)
-		dev->ops->enable_qp(dev, i, 0);
+	for (i = 0; i < dev->queue_pairs; i++) {
+		ret = dev->ops->enable_qp(dev, i, 0);
+		if (ret < 0)
+			goto exit;
+	}
 
 	/* Step 2: update memory regions */
-	dev->ops->set_memory_table(dev);
+	ret = dev->ops->set_memory_table(dev);
+	if (ret < 0)
+		goto exit;
 
 	/* Step 3: resume the active queues */
-	for (i = 0; i < dev->queue_pairs; i++)
-		dev->ops->enable_qp(dev, i, 1);
+	for (i = 0; i < dev->queue_pairs; i++) {
+		ret = dev->ops->enable_qp(dev, i, 1);
+		if (ret < 0)
+			goto exit;
+	}
 
 exit:
 	pthread_mutex_unlock(&dev->mutex);
+
+	if (ret < 0)
+		PMD_DRV_LOG(ERR, "(%s) Failed to update memory table\n", dev->path);
 }
 
 static int
@@ -388,7 +435,7 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
 			dev->tapfds = malloc(dev->max_queue_pairs *
 					     sizeof(int));
 			if (!dev->vhostfds || !dev->tapfds) {
-				PMD_INIT_LOG(ERR, "Failed to malloc");
+				PMD_INIT_LOG(ERR, "(%s) Failed to allocate FDs", dev->path);
 				return -1;
 			}
 
@@ -400,19 +447,25 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
 				VIRTIO_USER_BACKEND_VHOST_VDPA) {
 			dev->ops = &virtio_ops_vdpa;
 		} else {
-			PMD_DRV_LOG(ERR, "Unknown backend type");
+			PMD_DRV_LOG(ERR, "(%s) Unknown backend type", dev->path);
 			return -1;
 		}
 	}
 
-	if (dev->ops->setup(dev) < 0)
+	if (dev->ops->setup(dev) < 0) {
+		PMD_INIT_LOG(ERR, "(%s) Failed to setup backend\n", dev->path);
 		return -1;
+	}
 
-	if (virtio_user_dev_init_notify(dev) < 0)
+	if (virtio_user_dev_init_notify(dev) < 0) {
+		PMD_INIT_LOG(ERR, "(%s) Failed to init notifiers\n", dev->path);
 		return -1;
+	}
 
-	if (virtio_user_fill_intr_handle(dev) < 0)
+	if (virtio_user_fill_intr_handle(dev) < 0) {
+		PMD_INIT_LOG(ERR, "(%s) Failed to init interrupt handler\n", dev->path);
 		return -1;
+	}
 
 	return 0;
 }
@@ -480,7 +533,7 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
 	}
 
 	if (virtio_user_dev_setup(dev) < 0) {
-		PMD_INIT_LOG(ERR, "backend set up fails");
+		PMD_INIT_LOG(ERR, "(%s) backend set up fails", dev->path);
 		return -1;
 	}
 
@@ -490,27 +543,31 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
 
 	if (!dev->is_server) {
 		if (dev->ops->set_owner(dev) < 0) {
-			PMD_INIT_LOG(ERR, "set_owner fails: %s",
-				     strerror(errno));
+			PMD_INIT_LOG(ERR, "(%s) Failed to set backend owner", dev->path);
 			return -1;
 		}
 
 		if (dev->ops->get_features(dev, &dev->device_features) < 0) {
-			PMD_INIT_LOG(ERR, "get_features failed: %s",
-				     strerror(errno));
+			PMD_INIT_LOG(ERR, "(%s) Failed to get backend features", dev->path);
 			return -1;
 		}
 
 
 		if ((dev->device_features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)) ||
 				(dev->backend_type == VIRTIO_USER_BACKEND_VHOST_VDPA)) {
-			if (dev->ops->get_protocol_features(dev, &protocol_features))
+			if (dev->ops->get_protocol_features(dev, &protocol_features)) {
+				PMD_INIT_LOG(ERR, "(%s) Failed to get backend protocol features",
+						dev->path);
 				return -1;
+			}
 
 			dev->protocol_features &= protocol_features;
 
-			if (dev->ops->set_protocol_features(dev, dev->protocol_features))
+			if (dev->ops->set_protocol_features(dev, dev->protocol_features)) {
+				PMD_INIT_LOG(ERR, "(%s) Failed to set backend protocol features",
+						dev->path);
 				return -1;
+			}
 
 			if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
 				dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
@@ -577,8 +634,8 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
 	if (rte_mem_event_callback_register(VIRTIO_USER_MEM_EVENT_CLB_NAME,
 				virtio_user_mem_event_cb, dev)) {
 		if (rte_errno != ENOTSUP) {
-			PMD_INIT_LOG(ERR, "Failed to register mem event"
-					" callback\n");
+			PMD_INIT_LOG(ERR, "(%s) Failed to register mem event callback\n",
+					dev->path);
 			return -1;
 		}
 	}
@@ -631,8 +688,8 @@ virtio_user_handle_mq(struct virtio_user_dev *dev, uint16_t q_pairs)
 	uint8_t ret = 0;
 
 	if (q_pairs > dev->max_queue_pairs) {
-		PMD_INIT_LOG(ERR, "multi-q config %u, but only %u supported",
-			     q_pairs, dev->max_queue_pairs);
+		PMD_INIT_LOG(ERR, "(%s) multi-q config %u, but only %u supported",
+			     dev->path, q_pairs, dev->max_queue_pairs);
 		return -1;
 	}
 
@@ -818,10 +875,8 @@ virtio_user_dev_set_status(struct virtio_user_dev *dev, uint8_t status)
 	pthread_mutex_lock(&dev->mutex);
 	dev->status = status;
 	ret = dev->ops->set_status(dev, status);
-	if (ret && ret != -ENOTSUP) {
-		PMD_INIT_LOG(ERR, "Virtio-user set status failed (%d): %s", ret,
-			     strerror(errno));
-	}
+	if (ret && ret != -ENOTSUP)
+		PMD_INIT_LOG(ERR, "(%s) Failed to set backend status\n", dev->path);
 
 	pthread_mutex_unlock(&dev->mutex);
 	return ret;
@@ -855,8 +910,7 @@ virtio_user_dev_update_status(struct virtio_user_dev *dev)
 			!!(dev->status & VIRTIO_CONFIG_STATUS_DEV_NEED_RESET),
 			!!(dev->status & VIRTIO_CONFIG_STATUS_FAILED));
 	} else if (ret != -ENOTSUP) {
-		PMD_INIT_LOG(ERR, "Virtio-user get status failed (%d): %s", ret,
-			     strerror(errno));
+		PMD_INIT_LOG(ERR, "(%s) Failed to get backend status\n", dev->path);
 	}
 
 	pthread_mutex_unlock(&dev->mutex);
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 36/44] net/virtio: move Vhost-user reqs to Vhost-user backend
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (34 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 35/44] net/virtio: improve Virtio-user errors handling Maxime Coquelin
@ 2021-01-19 21:24 ` Maxime Coquelin
  2021-01-21  8:56   ` Xia, Chenbo
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 37/44] net/virtio: make server mode blocking Maxime Coquelin
                   ` (7 subsequent siblings)
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:24 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

Now that we have a proper isolation of the backends,
we can move Vhost-user requests declaration to the
Vhost-user backend file.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_user/vhost.h      | 25 ---------------------
 drivers/net/virtio/virtio_user/vhost_user.c | 25 +++++++++++++++++++++
 2 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/vhost.h b/drivers/net/virtio/virtio_user/vhost.h
index 6294b8afee..2aa6b2cb70 100644
--- a/drivers/net/virtio/virtio_user/vhost.h
+++ b/drivers/net/virtio/virtio_user/vhost.h
@@ -63,31 +63,6 @@ struct vhost_vring_addr {
 #define VHOST_USER_PROTOCOL_F_STATUS 16
 #endif
 
-enum vhost_user_request {
-	VHOST_USER_NONE = 0,
-	VHOST_USER_GET_FEATURES = 1,
-	VHOST_USER_SET_FEATURES = 2,
-	VHOST_USER_SET_OWNER = 3,
-	VHOST_USER_RESET_OWNER = 4,
-	VHOST_USER_SET_MEM_TABLE = 5,
-	VHOST_USER_SET_LOG_BASE = 6,
-	VHOST_USER_SET_LOG_FD = 7,
-	VHOST_USER_SET_VRING_NUM = 8,
-	VHOST_USER_SET_VRING_ADDR = 9,
-	VHOST_USER_SET_VRING_BASE = 10,
-	VHOST_USER_GET_VRING_BASE = 11,
-	VHOST_USER_SET_VRING_KICK = 12,
-	VHOST_USER_SET_VRING_CALL = 13,
-	VHOST_USER_SET_VRING_ERR = 14,
-	VHOST_USER_GET_PROTOCOL_FEATURES = 15,
-	VHOST_USER_SET_PROTOCOL_FEATURES = 16,
-	VHOST_USER_GET_QUEUE_NUM = 17,
-	VHOST_USER_SET_VRING_ENABLE = 18,
-	VHOST_USER_SET_STATUS = 39,
-	VHOST_USER_GET_STATUS = 40,
-	VHOST_USER_MAX
-};
-
 #ifndef VHOST_BACKEND_F_IOTLB_MSG_V2
 #define VHOST_BACKEND_F_IOTLB_MSG_V2 1
 #endif
diff --git a/drivers/net/virtio/virtio_user/vhost_user.c b/drivers/net/virtio/virtio_user/vhost_user.c
index d46e25b64b..fb6fcc82c9 100644
--- a/drivers/net/virtio/virtio_user/vhost_user.c
+++ b/drivers/net/virtio/virtio_user/vhost_user.c
@@ -27,6 +27,31 @@ struct vhost_memory {
 	struct vhost_memory_region regions[VHOST_MEMORY_MAX_NREGIONS];
 };
 
+enum vhost_user_request {
+	VHOST_USER_NONE = 0,
+	VHOST_USER_GET_FEATURES = 1,
+	VHOST_USER_SET_FEATURES = 2,
+	VHOST_USER_SET_OWNER = 3,
+	VHOST_USER_RESET_OWNER = 4,
+	VHOST_USER_SET_MEM_TABLE = 5,
+	VHOST_USER_SET_LOG_BASE = 6,
+	VHOST_USER_SET_LOG_FD = 7,
+	VHOST_USER_SET_VRING_NUM = 8,
+	VHOST_USER_SET_VRING_ADDR = 9,
+	VHOST_USER_SET_VRING_BASE = 10,
+	VHOST_USER_GET_VRING_BASE = 11,
+	VHOST_USER_SET_VRING_KICK = 12,
+	VHOST_USER_SET_VRING_CALL = 13,
+	VHOST_USER_SET_VRING_ERR = 14,
+	VHOST_USER_GET_PROTOCOL_FEATURES = 15,
+	VHOST_USER_SET_PROTOCOL_FEATURES = 16,
+	VHOST_USER_GET_QUEUE_NUM = 17,
+	VHOST_USER_SET_VRING_ENABLE = 18,
+	VHOST_USER_SET_STATUS = 39,
+	VHOST_USER_GET_STATUS = 40,
+	VHOST_USER_MAX
+};
+
 struct vhost_user_msg {
 	enum vhost_user_request request;
 
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 37/44] net/virtio: make server mode blocking
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (35 preceding siblings ...)
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 36/44] net/virtio: move Vhost-user reqs to Vhost-user backend Maxime Coquelin
@ 2021-01-19 21:25 ` Maxime Coquelin
  2021-01-22  8:19   ` Xia, Chenbo
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 38/44] net/virtio: move protocol features to Vhost-user Maxime Coquelin
                   ` (6 subsequent siblings)
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:25 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch makes the Vhost-user backend server mode
blocking at init, waiting for the client connection.

The goal is to make the driver more reliable, as without
waiting for client connection, the Virtio driver has to
assume the Vhost-user backend will support all the
features it has advertized, which could lead to undefined
behaviour.

For example, without this patch, if the user enables packed
ring Virtio feature but the backend does not support it,
the ring initialized by the driver will not be compatible
with the backend.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_user/vhost_user.c   |   9 +-
 .../net/virtio/virtio_user/virtio_user_dev.c  | 121 +++++++-----------
 drivers/net/virtio/virtio_user_ethdev.c       |   5 -
 3 files changed, 55 insertions(+), 80 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/vhost_user.c b/drivers/net/virtio/virtio_user/vhost_user.c
index fb6fcc82c9..a48fadd8c9 100644
--- a/drivers/net/virtio/virtio_user/vhost_user.c
+++ b/drivers/net/virtio/virtio_user/vhost_user.c
@@ -692,6 +692,14 @@ virtio_user_start_server(struct virtio_user_dev *dev, struct sockaddr_un *un)
 	if (ret < 0)
 		return -1;
 
+	PMD_DRV_LOG(NOTICE, "(%s) waiting for client connection...", dev->path);
+	dev->vhostfd = accept(fd, NULL, NULL);
+	if (dev->vhostfd < 0) {
+		PMD_DRV_LOG(ERR, "Failed to accept initial client connection (%s)",
+				strerror(errno));
+		return -1;
+	}
+
 	flag = fcntl(fd, F_GETFL);
 	if (fcntl(fd, F_SETFL, flag | O_NONBLOCK) < 0) {
 		PMD_DRV_LOG(ERR, "fcntl failed, %s", strerror(errno));
@@ -736,7 +744,6 @@ vhost_user_setup(struct virtio_user_dev *dev)
 			close(fd);
 			return -1;
 		}
-		dev->vhostfd = -1;
 	} else {
 		if (connect(fd, (struct sockaddr *)&un, sizeof(un)) < 0) {
 			PMD_DRV_LOG(ERR, "connect error, %s", strerror(errno));
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index 95204ea955..c2a41fe3a0 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -144,10 +144,6 @@ virtio_user_dev_set_features(struct virtio_user_dev *dev)
 
 	pthread_mutex_lock(&dev->mutex);
 
-	if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER &&
-			dev->vhostfd < 0)
-		goto error;
-
 	/* Step 0: tell vhost to create queues */
 	if (virtio_user_queue_setup(dev, virtio_user_create_queue) < 0)
 		goto error;
@@ -190,11 +186,6 @@ virtio_user_start_device(struct virtio_user_dev *dev)
 	rte_mcfg_mem_read_lock();
 	pthread_mutex_lock(&dev->mutex);
 
-	/* Vhost-user client not connected yet, will start later */
-	if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER &&
-			dev->vhostfd < 0)
-		goto out;
-
 	/* Step 2: share memory regions */
 	ret = dev->ops->set_memory_table(dev);
 	if (ret < 0)
@@ -213,7 +204,7 @@ virtio_user_start_device(struct virtio_user_dev *dev)
 		goto error;
 
 	dev->started = true;
-out:
+
 	pthread_mutex_unlock(&dev->mutex);
 	rte_mcfg_mem_read_unlock();
 
@@ -422,36 +413,36 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
 			PMD_DRV_LOG(ERR, "Server mode only supports vhost-user!");
 			return -1;
 		}
+	}
+
+	if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER) {
 		dev->ops = &virtio_ops_user;
-	} else {
-		if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER) {
-			dev->ops = &virtio_ops_user;
-		} else if (dev->backend_type ==
-					VIRTIO_USER_BACKEND_VHOST_KERNEL) {
-			dev->ops = &virtio_ops_kernel;
-
-			dev->vhostfds = malloc(dev->max_queue_pairs *
-					       sizeof(int));
-			dev->tapfds = malloc(dev->max_queue_pairs *
-					     sizeof(int));
-			if (!dev->vhostfds || !dev->tapfds) {
-				PMD_INIT_LOG(ERR, "(%s) Failed to allocate FDs", dev->path);
-				return -1;
-			}
-
-			for (q = 0; q < dev->max_queue_pairs; ++q) {
-				dev->vhostfds[q] = -1;
-				dev->tapfds[q] = -1;
-			}
-		} else if (dev->backend_type ==
-				VIRTIO_USER_BACKEND_VHOST_VDPA) {
-			dev->ops = &virtio_ops_vdpa;
-		} else {
-			PMD_DRV_LOG(ERR, "(%s) Unknown backend type", dev->path);
+	} else if (dev->backend_type ==
+			VIRTIO_USER_BACKEND_VHOST_KERNEL) {
+		dev->ops = &virtio_ops_kernel;
+
+		dev->vhostfds = malloc(dev->max_queue_pairs *
+				sizeof(int));
+		dev->tapfds = malloc(dev->max_queue_pairs *
+				sizeof(int));
+		if (!dev->vhostfds || !dev->tapfds) {
+			PMD_INIT_LOG(ERR, "(%s) Failed to allocate FDs", dev->path);
 			return -1;
 		}
+
+		for (q = 0; q < dev->max_queue_pairs; ++q) {
+			dev->vhostfds[q] = -1;
+			dev->tapfds[q] = -1;
+		}
+	} else if (dev->backend_type ==
+			VIRTIO_USER_BACKEND_VHOST_VDPA) {
+		dev->ops = &virtio_ops_vdpa;
+	} else {
+		PMD_DRV_LOG(ERR, "(%s) Unknown backend type", dev->path);
+		return -1;
 	}
 
+
 	if (dev->ops->setup(dev) < 0) {
 		PMD_INIT_LOG(ERR, "(%s) Failed to setup backend\n", dev->path);
 		return -1;
@@ -541,54 +532,36 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
 		dev->unsupported_features |=
 			(1ULL << VHOST_USER_F_PROTOCOL_FEATURES);
 
-	if (!dev->is_server) {
-		if (dev->ops->set_owner(dev) < 0) {
-			PMD_INIT_LOG(ERR, "(%s) Failed to set backend owner", dev->path);
-			return -1;
-		}
+	if (dev->ops->set_owner(dev) < 0) {
+		PMD_INIT_LOG(ERR, "(%s) Failed to set backend owner", dev->path);
+		return -1;
+	}
+
+	if (dev->ops->get_features(dev, &dev->device_features) < 0) {
+		PMD_INIT_LOG(ERR, "(%s) Failed to get backend features", dev->path);
+		return -1;
+	}
 
-		if (dev->ops->get_features(dev, &dev->device_features) < 0) {
-			PMD_INIT_LOG(ERR, "(%s) Failed to get backend features", dev->path);
+	if ((dev->device_features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)) ||
+			dev->backend_type == VIRTIO_USER_BACKEND_VHOST_VDPA) {
+		if (dev->ops->get_protocol_features(dev, &protocol_features)) {
+			PMD_INIT_LOG(ERR, "(%s) Failed to get backend protocol features",
+					dev->path);
 			return -1;
 		}
 
+		dev->protocol_features &= protocol_features;
 
-		if ((dev->device_features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)) ||
-				(dev->backend_type == VIRTIO_USER_BACKEND_VHOST_VDPA)) {
-			if (dev->ops->get_protocol_features(dev, &protocol_features)) {
-				PMD_INIT_LOG(ERR, "(%s) Failed to get backend protocol features",
-						dev->path);
-				return -1;
-			}
-
-			dev->protocol_features &= protocol_features;
-
-			if (dev->ops->set_protocol_features(dev, dev->protocol_features)) {
-				PMD_INIT_LOG(ERR, "(%s) Failed to set backend protocol features",
-						dev->path);
-				return -1;
-			}
-
-			if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
-				dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
+		if (dev->ops->set_protocol_features(dev, dev->protocol_features)) {
+			PMD_INIT_LOG(ERR, "(%s) Failed to set backend protocol features",
+					dev->path);
+			return -1;
 		}
-	} else {
-		/* We just pretend vhost-user can support all these features.
-		 * Note that this could be problematic that if some feature is
-		 * negotiated but not supported by the vhost-user which comes
-		 * later.
-		 */
-		dev->device_features = VIRTIO_USER_SUPPORTED_FEATURES;
 
-		/* We cannot assume VHOST_USER_PROTOCOL_F_STATUS is supported
-		 * until it's negotiated
-		 */
-		dev->protocol_features &=
-			~(1ULL << VHOST_USER_PROTOCOL_F_STATUS);
+		if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
+			dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
 	}
 
-
-
 	if (!mrg_rxbuf)
 		dev->unsupported_features |= (1ull << VIRTIO_NET_F_MRG_RXBUF);
 
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index 5e256f4e6d..e822d93690 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -174,11 +174,6 @@ virtio_user_delayed_handler(void *param)
 		if (dev->vhostfd >= 0) {
 			close(dev->vhostfd);
 			dev->vhostfd = -1;
-			/* Until the featuers are negotiated again, don't assume
-			 * the backend supports VHOST_USER_PROTOCOL_F_STATUS
-			 */
-			dev->protocol_features &=
-				~(1ULL << VHOST_USER_PROTOCOL_F_STATUS);
 		}
 		eth_dev->intr_handle->fd = dev->listenfd;
 		rte_intr_callback_register(eth_dev->intr_handle,
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 38/44] net/virtio: move protocol features to Vhost-user
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (36 preceding siblings ...)
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 37/44] net/virtio: make server mode blocking Maxime Coquelin
@ 2021-01-19 21:25 ` Maxime Coquelin
  2021-01-22  8:20   ` Xia, Chenbo
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 39/44] net/virtio: introduce backend data Maxime Coquelin
                   ` (5 subsequent siblings)
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:25 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

Since only protocol features are specific to Vhost-user
backend, this patch moves all related code to Vhost-user
file.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_user/vhost.h        | 20 +----
 drivers/net/virtio/virtio_user/vhost_kernel.c |  9 ++
 drivers/net/virtio/virtio_user/vhost_user.c   | 83 +++++++++++++++----
 drivers/net/virtio/virtio_user/vhost_vdpa.c   | 34 +++++++-
 .../net/virtio/virtio_user/virtio_user_dev.c  | 47 ++---------
 drivers/net/virtio/virtio_user_ethdev.c       | 17 ----
 6 files changed, 113 insertions(+), 97 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/vhost.h b/drivers/net/virtio/virtio_user/vhost.h
index 2aa6b2cb70..dfa2735a20 100644
--- a/drivers/net/virtio/virtio_user/vhost.h
+++ b/drivers/net/virtio/virtio_user/vhost.h
@@ -46,23 +46,6 @@ struct vhost_vring_addr {
 	uint64_t log_guest_addr;
 };
 
-#ifndef VHOST_USER_F_PROTOCOL_FEATURES
-#define VHOST_USER_F_PROTOCOL_FEATURES 30
-#endif
-
-/** Protocol features. */
-#ifndef VHOST_USER_PROTOCOL_F_MQ
-#define VHOST_USER_PROTOCOL_F_MQ 0
-#endif
-
-#ifndef VHOST_USER_PROTOCOL_F_REPLY_ACK
-#define VHOST_USER_PROTOCOL_F_REPLY_ACK 3
-#endif
-
-#ifndef VHOST_USER_PROTOCOL_F_STATUS
-#define VHOST_USER_PROTOCOL_F_STATUS 16
-#endif
-
 #ifndef VHOST_BACKEND_F_IOTLB_MSG_V2
 #define VHOST_BACKEND_F_IOTLB_MSG_V2 1
 #endif
@@ -82,11 +65,10 @@ struct virtio_user_dev;
 
 struct virtio_user_backend_ops {
 	int (*setup)(struct virtio_user_dev *dev);
+	int (*get_backend_features)(uint64_t *features);
 	int (*set_owner)(struct virtio_user_dev *dev);
 	int (*get_features)(struct virtio_user_dev *dev, uint64_t *features);
 	int (*set_features)(struct virtio_user_dev *dev, uint64_t features);
-	int (*get_protocol_features)(struct virtio_user_dev *dev, uint64_t *features);
-	int (*set_protocol_features)(struct virtio_user_dev *dev, uint64_t features);
 	int (*set_memory_table)(struct virtio_user_dev *dev);
 	int (*set_vring_num)(struct virtio_user_dev *dev, struct vhost_vring_state *state);
 	int (*set_vring_base)(struct virtio_user_dev *dev, struct vhost_vring_state *state);
diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c b/drivers/net/virtio/virtio_user/vhost_kernel.c
index 68f0c0b83d..5477eb7015 100644
--- a/drivers/net/virtio/virtio_user/vhost_kernel.c
+++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
@@ -445,8 +445,17 @@ vhost_kernel_enable_queue_pair(struct virtio_user_dev *dev,
 	return 0;
 }
 
+static int
+vhost_kernel_get_backend_features(uint64_t *features)
+{
+	*features = 0;
+
+	return 0;
+}
+
 struct virtio_user_backend_ops virtio_ops_kernel = {
 	.setup = vhost_kernel_setup,
+	.get_backend_features = vhost_kernel_get_backend_features,
 	.set_owner = vhost_kernel_set_owner,
 	.get_features = vhost_kernel_get_features,
 	.set_features = vhost_kernel_set_features,
diff --git a/drivers/net/virtio/virtio_user/vhost_user.c b/drivers/net/virtio/virtio_user/vhost_user.c
index a48fadd8c9..986d8ac1ac 100644
--- a/drivers/net/virtio/virtio_user/vhost_user.c
+++ b/drivers/net/virtio/virtio_user/vhost_user.c
@@ -17,6 +17,29 @@
 #include "vhost.h"
 #include "virtio_user_dev.h"
 
+
+#ifndef VHOST_USER_F_PROTOCOL_FEATURES
+#define VHOST_USER_F_PROTOCOL_FEATURES 30
+#endif
+
+/** Protocol features. */
+#ifndef VHOST_USER_PROTOCOL_F_MQ
+#define VHOST_USER_PROTOCOL_F_MQ 0
+#endif
+
+#ifndef VHOST_USER_PROTOCOL_F_REPLY_ACK
+#define VHOST_USER_PROTOCOL_F_REPLY_ACK 3
+#endif
+
+#ifndef VHOST_USER_PROTOCOL_F_STATUS
+#define VHOST_USER_PROTOCOL_F_STATUS 16
+#endif
+
+#define VHOST_USER_SUPPORTED_PROTOCOL_FEATURES		\
+	(1ULL << VHOST_USER_PROTOCOL_F_MQ |		\
+	 1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK |	\
+	 1ULL << VHOST_USER_PROTOCOL_F_STATUS)
+
 /* The version of the protocol we support */
 #define VHOST_USER_VERSION    0x1
 
@@ -205,11 +228,11 @@ vhost_user_set_owner(struct virtio_user_dev *dev)
 }
 
 static int
-vhost_user_get_features(struct virtio_user_dev *dev, uint64_t *features)
+vhost_user_get_protocol_features(struct virtio_user_dev *dev, uint64_t *features)
 {
 	int ret;
 	struct vhost_user_msg msg = {
-		.request = VHOST_USER_GET_FEATURES,
+		.request = VHOST_USER_GET_PROTOCOL_FEATURES,
 		.flags = VHOST_USER_VERSION,
 	};
 
@@ -221,7 +244,7 @@ vhost_user_get_features(struct virtio_user_dev *dev, uint64_t *features)
 	if (ret < 0)
 		goto err;
 
-	if (msg.request != VHOST_USER_GET_FEATURES) {
+	if (msg.request != VHOST_USER_GET_PROTOCOL_FEATURES) {
 		PMD_DRV_LOG(ERR, "Unexpected request type (%d)", msg.request);
 		goto err;
 	}
@@ -235,27 +258,25 @@ vhost_user_get_features(struct virtio_user_dev *dev, uint64_t *features)
 
 	return 0;
 err:
-	PMD_DRV_LOG(ERR, "Failed to get backend features");
+	PMD_DRV_LOG(ERR, "Failed to get backend protocol features");
 
 	return -1;
 }
 
 static int
-vhost_user_set_features(struct virtio_user_dev *dev, uint64_t features)
+vhost_user_set_protocol_features(struct virtio_user_dev *dev, uint64_t features)
 {
 	int ret;
 	struct vhost_user_msg msg = {
-		.request = VHOST_USER_SET_FEATURES,
+		.request = VHOST_USER_SET_PROTOCOL_FEATURES,
 		.flags = VHOST_USER_VERSION,
 		.size = sizeof(features),
 		.payload.u64 = features,
 	};
 
-	msg.payload.u64 |= dev->device_features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES);
-
 	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
 	if (ret < 0) {
-		PMD_DRV_LOG(ERR, "Failed to set features");
+		PMD_DRV_LOG(ERR, "Failed to set protocol features");
 		return -1;
 	}
 
@@ -263,11 +284,11 @@ vhost_user_set_features(struct virtio_user_dev *dev, uint64_t features)
 }
 
 static int
-vhost_user_get_protocol_features(struct virtio_user_dev *dev, uint64_t *features)
+vhost_user_get_features(struct virtio_user_dev *dev, uint64_t *features)
 {
 	int ret;
 	struct vhost_user_msg msg = {
-		.request = VHOST_USER_GET_PROTOCOL_FEATURES,
+		.request = VHOST_USER_GET_FEATURES,
 		.flags = VHOST_USER_VERSION,
 	};
 
@@ -279,7 +300,7 @@ vhost_user_get_protocol_features(struct virtio_user_dev *dev, uint64_t *features
 	if (ret < 0)
 		goto err;
 
-	if (msg.request != VHOST_USER_GET_PROTOCOL_FEATURES) {
+	if (msg.request != VHOST_USER_GET_FEATURES) {
 		PMD_DRV_LOG(ERR, "Unexpected request type (%d)", msg.request);
 		goto err;
 	}
@@ -291,27 +312,46 @@ vhost_user_get_protocol_features(struct virtio_user_dev *dev, uint64_t *features
 
 	*features = msg.payload.u64;
 
+	if (!(*features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)))
+		return 0;
+
+	/* Negotiate protocol features */
+	ret = vhost_user_get_protocol_features(dev, &dev->protocol_features);
+	if (ret < 0)
+		goto err;
+
+	dev->protocol_features &= VHOST_USER_SUPPORTED_PROTOCOL_FEATURES;
+
+	ret = vhost_user_set_protocol_features(dev, dev->protocol_features);
+	if (ret < 0)
+		goto err;
+
+	if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
+		dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
+
 	return 0;
 err:
-	PMD_DRV_LOG(ERR, "Failed to get backend protocol features");
+	PMD_DRV_LOG(ERR, "Failed to get backend features");
 
 	return -1;
 }
 
 static int
-vhost_user_set_protocol_features(struct virtio_user_dev *dev, uint64_t features)
+vhost_user_set_features(struct virtio_user_dev *dev, uint64_t features)
 {
 	int ret;
 	struct vhost_user_msg msg = {
-		.request = VHOST_USER_SET_PROTOCOL_FEATURES,
+		.request = VHOST_USER_SET_FEATURES,
 		.flags = VHOST_USER_VERSION,
 		.size = sizeof(features),
 		.payload.u64 = features,
 	};
 
+	msg.payload.u64 |= dev->device_features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES);
+
 	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
 	if (ret < 0) {
-		PMD_DRV_LOG(ERR, "Failed to set protocol features");
+		PMD_DRV_LOG(ERR, "Failed to set features");
 		return -1;
 	}
 
@@ -780,13 +820,20 @@ vhost_user_enable_queue_pair(struct virtio_user_dev *dev,
 	return 0;
 }
 
+static int
+vhost_user_get_backend_features(uint64_t *features)
+{
+	*features = 1ULL << VHOST_USER_F_PROTOCOL_FEATURES;
+
+	return 0;
+}
+
 struct virtio_user_backend_ops virtio_ops_user = {
 	.setup = vhost_user_setup,
+	.get_backend_features = vhost_user_get_backend_features,
 	.set_owner = vhost_user_set_owner,
 	.get_features = vhost_user_get_features,
 	.set_features = vhost_user_set_features,
-	.get_protocol_features = vhost_user_get_protocol_features,
-	.set_protocol_features = vhost_user_set_protocol_features,
 	.set_memory_table = vhost_user_set_memory_table,
 	.set_vring_num = vhost_user_set_vring_num,
 	.set_vring_base = vhost_user_set_vring_base,
diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c b/drivers/net/virtio/virtio_user/vhost_vdpa.c
index 7fb1249569..8d354b298e 100644
--- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
+++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
@@ -13,6 +13,10 @@
 #include "vhost.h"
 #include "virtio_user_dev.h"
 
+#define VHOST_VDPA_SUPPORTED_BACKEND_FEATURES		\
+	(1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2	|	\
+	1ULL << VHOST_BACKEND_F_IOTLB_BATCH)
+
 /* vhost kernel & vdpa ioctls */
 #define VHOST_VIRTIO 0xAF
 #define VHOST_GET_FEATURES _IOR(VHOST_VIRTIO, 0x00, __u64)
@@ -88,13 +92,13 @@ vhost_vdpa_set_owner(struct virtio_user_dev *dev)
 }
 
 static int
-vhost_vdpa_get_backend_features(struct virtio_user_dev *dev, uint64_t *features)
+vhost_vdpa_get_protocol_features(struct virtio_user_dev *dev, uint64_t *features)
 {
 	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_GET_BACKEND_FEATURES, features);
 }
 
 static int
-vhost_vdpa_set_backend_features(struct virtio_user_dev *dev, uint64_t features)
+vhost_vdpa_set_protocol_features(struct virtio_user_dev *dev, uint64_t features)
 {
 	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_BACKEND_FEATURES, &features);
 }
@@ -113,6 +117,21 @@ vhost_vdpa_get_features(struct virtio_user_dev *dev, uint64_t *features)
 	/* Multiqueue not supported for now */
 	*features &= ~(1ULL << VIRTIO_NET_F_MQ);
 
+	/* Negotiated vDPA backend features */
+	ret = vhost_vdpa_get_protocol_features(dev, &dev->protocol_features);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to get backend features");
+		return -1;
+	}
+
+	dev->protocol_features &= VHOST_VDPA_SUPPORTED_BACKEND_FEATURES;
+
+	ret = vhost_vdpa_set_protocol_features(dev, dev->protocol_features);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to set backend features");
+		return -1;
+	}
+
 	return 0;
 }
 
@@ -438,13 +457,20 @@ vhost_vdpa_enable_queue_pair(struct virtio_user_dev *dev,
 	return 0;
 }
 
+static int
+vhost_vdpa_get_backend_features(uint64_t *features)
+{
+	*features = 0;
+
+	return 0;
+}
+
 struct virtio_user_backend_ops virtio_ops_vdpa = {
 	.setup = vhost_vdpa_setup,
+	.get_backend_features = vhost_vdpa_get_backend_features,
 	.set_owner = vhost_vdpa_set_owner,
 	.get_features = vhost_vdpa_get_features,
 	.set_features = vhost_vdpa_set_features,
-	.get_protocol_features = vhost_vdpa_get_backend_features,
-	.set_protocol_features = vhost_vdpa_set_backend_features,
 	.set_memory_table = vhost_vdpa_set_memory_table,
 	.set_vring_num = vhost_vdpa_set_vring_num,
 	.set_vring_base = vhost_vdpa_set_vring_base,
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index c2a41fe3a0..2614bcb349 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -480,24 +480,15 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
 	 1ULL << VIRTIO_NET_F_GUEST_TSO6	|	\
 	 1ULL << VIRTIO_F_IN_ORDER		|	\
 	 1ULL << VIRTIO_F_VERSION_1		|	\
-	 1ULL << VIRTIO_F_RING_PACKED		|	\
-	 1ULL << VHOST_USER_F_PROTOCOL_FEATURES)
+	 1ULL << VIRTIO_F_RING_PACKED)
 
-#define VHOST_USER_SUPPORTED_PROTOCOL_FEATURES		\
-	(1ULL << VHOST_USER_PROTOCOL_F_MQ |		\
-	 1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK |	\
-	 1ULL << VHOST_USER_PROTOCOL_F_STATUS)
-
-#define VHOST_VDPA_SUPPORTED_PROTOCOL_FEATURES		\
-	(1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2	|	\
-	1ULL << VHOST_BACKEND_F_IOTLB_BATCH)
 int
 virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
 		     int cq, int queue_size, const char *mac, char **ifname,
 		     int server, int mrg_rxbuf, int in_order, int packed_vq,
 		     enum virtio_user_backend_type backend_type)
 {
-	uint64_t protocol_features = 0;
+	uint64_t backend_features;
 
 	pthread_mutex_init(&dev->mutex, NULL);
 	strlcpy(dev->path, path, PATH_MAX);
@@ -508,14 +499,9 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
 	dev->is_server = server;
 	dev->mac_specified = 0;
 	dev->frontend_features = 0;
-	dev->unsupported_features = ~VIRTIO_USER_SUPPORTED_FEATURES;
+	dev->unsupported_features = 0;
 	dev->backend_type = backend_type;
 
-	if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER)
-		dev->protocol_features = VHOST_USER_SUPPORTED_PROTOCOL_FEATURES;
-	else if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_VDPA)
-		dev->protocol_features = VHOST_VDPA_SUPPORTED_PROTOCOL_FEATURES;
-
 	parse_mac(dev, mac);
 
 	if (*ifname) {
@@ -528,38 +514,21 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
 		return -1;
 	}
 
-	if (dev->backend_type != VIRTIO_USER_BACKEND_VHOST_USER)
-		dev->unsupported_features |=
-			(1ULL << VHOST_USER_F_PROTOCOL_FEATURES);
-
 	if (dev->ops->set_owner(dev) < 0) {
 		PMD_INIT_LOG(ERR, "(%s) Failed to set backend owner", dev->path);
 		return -1;
 	}
 
-	if (dev->ops->get_features(dev, &dev->device_features) < 0) {
+	if (dev->ops->get_backend_features(&backend_features) < 0) {
 		PMD_INIT_LOG(ERR, "(%s) Failed to get backend features", dev->path);
 		return -1;
 	}
 
-	if ((dev->device_features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)) ||
-			dev->backend_type == VIRTIO_USER_BACKEND_VHOST_VDPA) {
-		if (dev->ops->get_protocol_features(dev, &protocol_features)) {
-			PMD_INIT_LOG(ERR, "(%s) Failed to get backend protocol features",
-					dev->path);
-			return -1;
-		}
-
-		dev->protocol_features &= protocol_features;
-
-		if (dev->ops->set_protocol_features(dev, dev->protocol_features)) {
-			PMD_INIT_LOG(ERR, "(%s) Failed to set backend protocol features",
-					dev->path);
-			return -1;
-		}
+	dev->unsupported_features = ~(VIRTIO_USER_SUPPORTED_FEATURES | backend_features);
 
-		if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
-			dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
+	if (dev->ops->get_features(dev, &dev->device_features) < 0) {
+		PMD_INIT_LOG(ERR, "(%s) Failed to get device features", dev->path);
+		return -1;
 	}
 
 	if (!mrg_rxbuf)
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index e822d93690..e2c606a838 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -70,7 +70,6 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev)
 	int ret, connectfd, old_status;
 	struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->port_id];
 	struct virtio_hw *hw = &dev->hw;
-	uint64_t protocol_features;
 
 	connectfd = accept(dev->listenfd, NULL, NULL);
 	if (connectfd < 0)
@@ -91,22 +90,6 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev)
 		return -1;
 	}
 
-	if (dev->device_features &
-			(1ULL << VHOST_USER_F_PROTOCOL_FEATURES)) {
-		if (dev->ops->get_protocol_features(dev, &protocol_features))
-			return -1;
-
-		/* Offer VHOST_USER_PROTOCOL_F_STATUS */
-		dev->protocol_features |= (1ULL << VHOST_USER_PROTOCOL_F_STATUS);
-		dev->protocol_features &= protocol_features;
-
-		if (dev->ops->set_protocol_features(dev, dev->protocol_features))
-			return -1;
-
-		if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
-			dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
-	}
-
 	dev->device_features |= dev->frontend_features;
 
 	/* umask vhost-user unsupported features */
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 39/44] net/virtio: introduce backend data
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (37 preceding siblings ...)
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 38/44] net/virtio: move protocol features to Vhost-user Maxime Coquelin
@ 2021-01-19 21:25 ` Maxime Coquelin
  2021-01-22  8:26   ` Xia, Chenbo
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 40/44] net/virtio: move Vhost-user specifics to its backend Maxime Coquelin
                   ` (4 subsequent siblings)
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:25 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

The goal of this patch is to introduce backend-specific
data in order to better isolate what is backend-specific
from what is generic to Virtio-user.

For now, only Vhost-user protocol features are moved to
Vhost-user backend data.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_user/vhost.h        |  1 +
 drivers/net/virtio/virtio_user/vhost_kernel.c |  7 +++
 drivers/net/virtio/virtio_user/vhost_user.c   | 62 +++++++++++++++----
 drivers/net/virtio/virtio_user/vhost_vdpa.c   |  7 +++
 .../net/virtio/virtio_user/virtio_user_dev.c  |  2 +
 .../net/virtio/virtio_user/virtio_user_dev.h  |  2 +
 6 files changed, 68 insertions(+), 13 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/vhost.h b/drivers/net/virtio/virtio_user/vhost.h
index dfa2735a20..fc4f059c02 100644
--- a/drivers/net/virtio/virtio_user/vhost.h
+++ b/drivers/net/virtio/virtio_user/vhost.h
@@ -65,6 +65,7 @@ struct virtio_user_dev;
 
 struct virtio_user_backend_ops {
 	int (*setup)(struct virtio_user_dev *dev);
+	int (*destroy)(struct virtio_user_dev *dev);
 	int (*get_backend_features)(uint64_t *features);
 	int (*set_owner)(struct virtio_user_dev *dev);
 	int (*get_features)(struct virtio_user_dev *dev, uint64_t *features);
diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c b/drivers/net/virtio/virtio_user/vhost_kernel.c
index 5477eb7015..47fb4427be 100644
--- a/drivers/net/virtio/virtio_user/vhost_kernel.c
+++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
@@ -357,6 +357,12 @@ vhost_kernel_setup(struct virtio_user_dev *dev)
 	return 0;
 }
 
+static int
+vhost_kernel_destroy(struct virtio_user_dev *dev __rte_unused)
+{
+	return 0;
+}
+
 static int
 vhost_kernel_set_backend(int vhostfd, int tapfd)
 {
@@ -455,6 +461,7 @@ vhost_kernel_get_backend_features(uint64_t *features)
 
 struct virtio_user_backend_ops virtio_ops_kernel = {
 	.setup = vhost_kernel_setup,
+	.destroy = vhost_kernel_destroy,
 	.get_backend_features = vhost_kernel_get_backend_features,
 	.set_owner = vhost_kernel_set_owner,
 	.get_features = vhost_kernel_get_features,
diff --git a/drivers/net/virtio/virtio_user/vhost_user.c b/drivers/net/virtio/virtio_user/vhost_user.c
index 986d8ac1ac..0147b6d963 100644
--- a/drivers/net/virtio/virtio_user/vhost_user.c
+++ b/drivers/net/virtio/virtio_user/vhost_user.c
@@ -17,6 +17,9 @@
 #include "vhost.h"
 #include "virtio_user_dev.h"
 
+struct vhost_user_data {
+	uint64_t protocol_features;
+};
 
 #ifndef VHOST_USER_F_PROTOCOL_FEATURES
 #define VHOST_USER_F_PROTOCOL_FEATURES 30
@@ -287,6 +290,7 @@ static int
 vhost_user_get_features(struct virtio_user_dev *dev, uint64_t *features)
 {
 	int ret;
+	struct vhost_user_data *data = dev->backend_data;
 	struct vhost_user_msg msg = {
 		.request = VHOST_USER_GET_FEATURES,
 		.flags = VHOST_USER_VERSION,
@@ -316,17 +320,17 @@ vhost_user_get_features(struct virtio_user_dev *dev, uint64_t *features)
 		return 0;
 
 	/* Negotiate protocol features */
-	ret = vhost_user_get_protocol_features(dev, &dev->protocol_features);
+	ret = vhost_user_get_protocol_features(dev, &data->protocol_features);
 	if (ret < 0)
 		goto err;
 
-	dev->protocol_features &= VHOST_USER_SUPPORTED_PROTOCOL_FEATURES;
+	data->protocol_features &= VHOST_USER_SUPPORTED_PROTOCOL_FEATURES;
 
-	ret = vhost_user_set_protocol_features(dev, dev->protocol_features);
+	ret = vhost_user_set_protocol_features(dev, data->protocol_features);
 	if (ret < 0)
 		goto err;
 
-	if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
+	if (!(data->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
 		dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
 
 	return 0;
@@ -444,12 +448,13 @@ vhost_user_set_memory_table(struct virtio_user_dev *dev)
 	struct walk_arg wa;
 	int fds[VHOST_MEMORY_MAX_NREGIONS];
 	int ret, fd_num;
+	struct vhost_user_data *data = dev->backend_data;
 	struct vhost_user_msg msg = {
 		.request = VHOST_USER_SET_MEM_TABLE,
 		.flags = VHOST_USER_VERSION,
 	};
 
-	if (dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK))
+	if (data->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK))
 		msg.flags |= VHOST_USER_NEED_REPLY_MASK;
 
 	wa.region_nr = 0;
@@ -628,6 +633,7 @@ static int
 vhost_user_get_status(struct virtio_user_dev *dev, uint8_t *status)
 {
 	int ret;
+	struct vhost_user_data *data = dev->backend_data;
 	struct vhost_user_msg msg = {
 		.request = VHOST_USER_GET_STATUS,
 		.flags = VHOST_USER_VERSION,
@@ -644,7 +650,7 @@ vhost_user_get_status(struct virtio_user_dev *dev, uint8_t *status)
 	if (!(dev->device_features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)))
 		return -ENOTSUP;
 
-	if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_STATUS)))
+	if (!(data->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_STATUS)))
 		return -ENOTSUP;
 
 	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
@@ -681,6 +687,7 @@ static int
 vhost_user_set_status(struct virtio_user_dev *dev, uint8_t status)
 {
 	int ret;
+	struct vhost_user_data *data = dev->backend_data;
 	struct vhost_user_msg msg = {
 		.request = VHOST_USER_SET_STATUS,
 		.flags = VHOST_USER_VERSION,
@@ -699,10 +706,10 @@ vhost_user_set_status(struct virtio_user_dev *dev, uint8_t status)
 	if (!(dev->device_features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)))
 		return -ENOTSUP;
 
-	if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_STATUS)))
+	if (!(data->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_STATUS)))
 		return -ENOTSUP;
 
-	if (dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK))
+	if (data->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK))
 		msg.flags |= VHOST_USER_NEED_REPLY_MASK;
 
 	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
@@ -762,11 +769,22 @@ vhost_user_setup(struct virtio_user_dev *dev)
 	int fd;
 	int flag;
 	struct sockaddr_un un;
+	struct vhost_user_data *data;
+
+	data = malloc(sizeof(*data));
+	if (!data) {
+		PMD_DRV_LOG(ERR, "(%s) Failed to allocate Vhost-user data\n", dev->path);
+		return -1;
+	}
+
+	memset(data, 0, sizeof(*data));
+
+	dev->backend_data = data;
 
 	fd = socket(AF_UNIX, SOCK_STREAM, 0);
 	if (fd < 0) {
 		PMD_DRV_LOG(ERR, "socket() error, %s", strerror(errno));
-		return -1;
+		goto err_data;
 	}
 
 	flag = fcntl(fd, F_GETFD);
@@ -781,18 +799,35 @@ vhost_user_setup(struct virtio_user_dev *dev)
 		dev->listenfd = fd;
 		if (virtio_user_start_server(dev, &un) < 0) {
 			PMD_DRV_LOG(ERR, "virtio-user startup fails in server mode");
-			close(fd);
-			return -1;
+			goto err_socket;
 		}
 	} else {
 		if (connect(fd, (struct sockaddr *)&un, sizeof(un)) < 0) {
 			PMD_DRV_LOG(ERR, "connect error, %s", strerror(errno));
-			close(fd);
-			return -1;
+			goto err_socket;
 		}
 		dev->vhostfd = fd;
 	}
 
+	return 0;
+
+err_socket:
+	close(fd);
+err_data:
+	free(data);
+	dev->backend_data = NULL;
+
+	return -1;
+}
+
+static int
+vhost_user_destroy(struct virtio_user_dev *dev)
+{
+	if (dev->backend_data) {
+		free(dev->backend_data);
+		dev->backend_data = NULL;
+	}
+
 	return 0;
 }
 
@@ -830,6 +865,7 @@ vhost_user_get_backend_features(uint64_t *features)
 
 struct virtio_user_backend_ops virtio_ops_user = {
 	.setup = vhost_user_setup,
+	.destroy = vhost_user_destroy,
 	.get_backend_features = vhost_user_get_backend_features,
 	.set_owner = vhost_user_set_owner,
 	.get_features = vhost_user_get_features,
diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c b/drivers/net/virtio/virtio_user/vhost_vdpa.c
index 8d354b298e..f5a8943993 100644
--- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
+++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
@@ -432,6 +432,12 @@ vhost_vdpa_setup(struct virtio_user_dev *dev)
 	return 0;
 }
 
+static int
+vhost_vdpa_destroy(struct virtio_user_dev *dev __rte_unused)
+{
+	return 0;
+}
+
 static int
 vhost_vdpa_enable_queue_pair(struct virtio_user_dev *dev,
 			       uint16_t pair_idx,
@@ -467,6 +473,7 @@ vhost_vdpa_get_backend_features(uint64_t *features)
 
 struct virtio_user_backend_ops virtio_ops_vdpa = {
 	.setup = vhost_vdpa_setup,
+	.destroy = vhost_vdpa_destroy,
 	.get_backend_features = vhost_vdpa_get_backend_features,
 	.set_owner = vhost_vdpa_set_owner,
 	.get_features = vhost_vdpa_get_features,
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index 2614bcb349..215819d46d 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -621,6 +621,8 @@ virtio_user_dev_uninit(struct virtio_user_dev *dev)
 
 	if (dev->is_server)
 		unlink(dev->path);
+
+	dev->ops->destroy(dev);
 }
 
 uint8_t
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h b/drivers/net/virtio/virtio_user/virtio_user_dev.h
index ab62463a5b..7650097b6d 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
@@ -66,6 +66,8 @@ struct virtio_user_dev {
 	struct virtio_user_backend_ops *ops;
 	pthread_mutex_t	mutex;
 	bool		started;
+
+	void *backend_data;
 };
 
 int virtio_user_dev_set_features(struct virtio_user_dev *dev);
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 40/44] net/virtio: move Vhost-user specifics to its backend
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (38 preceding siblings ...)
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 39/44] net/virtio: introduce backend data Maxime Coquelin
@ 2021-01-19 21:25 ` Maxime Coquelin
  2021-01-22  8:49   ` Xia, Chenbo
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 41/44] net/virtio: move Vhost-kernel data " Maxime Coquelin
                   ` (3 subsequent siblings)
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:25 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch moves all the Vhost-user backend specific
logic like Vhost FD, listen FD and interrupt handling
to the vhost-user backend implementation.

In order to achieve that, new ops are created to update
the link status, disconnect and reconnect the server,
and fetch the link state interrupt FD.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_user/vhost.h        |   4 +
 drivers/net/virtio/virtio_user/vhost_kernel.c |  18 +-
 drivers/net/virtio/virtio_user/vhost_user.c   | 176 ++++++++++++++---
 drivers/net/virtio/virtio_user/vhost_vdpa.c   |  16 ++
 .../net/virtio/virtio_user/virtio_user_dev.c  | 181 +++++++++++++++---
 .../net/virtio/virtio_user/virtio_user_dev.h  |   9 +-
 drivers/net/virtio/virtio_user_ethdev.c       | 179 +----------------
 7 files changed, 350 insertions(+), 233 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/vhost.h b/drivers/net/virtio/virtio_user/vhost.h
index fc4f059c02..c49e88036d 100644
--- a/drivers/net/virtio/virtio_user/vhost.h
+++ b/drivers/net/virtio/virtio_user/vhost.h
@@ -82,6 +82,10 @@ struct virtio_user_backend_ops {
 	int (*enable_qp)(struct virtio_user_dev *dev, uint16_t pair_idx, int enable);
 	int (*dma_map)(struct virtio_user_dev *dev, void *addr, uint64_t iova, size_t len);
 	int (*dma_unmap)(struct virtio_user_dev *dev, void *addr, uint64_t iova, size_t len);
+	int (*update_link_state)(struct virtio_user_dev *dev);
+	int (*server_disconnect)(struct virtio_user_dev *dev);
+	int (*server_reconnect)(struct virtio_user_dev *dev);
+	int (*get_intr_fd)(struct virtio_user_dev *dev);
 };
 
 extern struct virtio_user_backend_ops virtio_ops_user;
diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c b/drivers/net/virtio/virtio_user/vhost_kernel.c
index 47fb4427be..aa1f9ece5e 100644
--- a/drivers/net/virtio/virtio_user/vhost_kernel.c
+++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
@@ -459,6 +459,20 @@ vhost_kernel_get_backend_features(uint64_t *features)
 	return 0;
 }
 
+static int
+vhost_kernel_update_link_state(struct virtio_user_dev *dev __rte_unused)
+{
+	/* Nothing to update (Maybe get TAP interface link state?) */
+	return 0;
+}
+
+static int
+vhost_kernel_get_intr_fd(struct virtio_user_dev *dev __rte_unused)
+{
+	/* No link state interrupt with Vhost-kernel */
+	return -1;
+}
+
 struct virtio_user_backend_ops virtio_ops_kernel = {
 	.setup = vhost_kernel_setup,
 	.destroy = vhost_kernel_destroy,
@@ -475,5 +489,7 @@ struct virtio_user_backend_ops virtio_ops_kernel = {
 	.set_vring_addr = vhost_kernel_set_vring_addr,
 	.get_status = vhost_kernel_get_status,
 	.set_status = vhost_kernel_set_status,
-	.enable_qp = vhost_kernel_enable_queue_pair
+	.enable_qp = vhost_kernel_enable_queue_pair,
+	.update_link_state = vhost_kernel_update_link_state,
+	.get_intr_fd = vhost_kernel_get_intr_fd,
 };
diff --git a/drivers/net/virtio/virtio_user/vhost_user.c b/drivers/net/virtio/virtio_user/vhost_user.c
index 0147b6d963..f046655af6 100644
--- a/drivers/net/virtio/virtio_user/vhost_user.c
+++ b/drivers/net/virtio/virtio_user/vhost_user.c
@@ -11,6 +11,7 @@
 #include <string.h>
 #include <errno.h>
 
+#include <rte_alarm.h>
 #include <rte_string_fns.h>
 #include <rte_fbarray.h>
 
@@ -18,6 +19,8 @@
 #include "virtio_user_dev.h"
 
 struct vhost_user_data {
+	int vhostfd;
+	int listenfd;
 	uint64_t protocol_features;
 };
 
@@ -182,13 +185,14 @@ vhost_user_read(int fd, struct vhost_user_msg *msg)
 static int
 vhost_user_check_reply_ack(struct virtio_user_dev *dev, struct vhost_user_msg *msg)
 {
+	struct vhost_user_data *data = dev->backend_data;
 	enum vhost_user_request req = msg->request;
 	int ret;
 
 	if (!(msg->flags & VHOST_USER_NEED_REPLY_MASK))
 		return 0;
 
-	ret = vhost_user_read(dev->vhostfd, msg);
+	ret = vhost_user_read(data->vhostfd, msg);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "Failed to read reply-ack");
 		return -1;
@@ -216,12 +220,13 @@ static int
 vhost_user_set_owner(struct virtio_user_dev *dev)
 {
 	int ret;
+	struct vhost_user_data *data = dev->backend_data;
 	struct vhost_user_msg msg = {
 		.request = VHOST_USER_SET_OWNER,
 		.flags = VHOST_USER_VERSION,
 	};
 
-	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+	ret = vhost_user_write(data->vhostfd, &msg, NULL, 0);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "Failed to set owner");
 		return -1;
@@ -234,16 +239,17 @@ static int
 vhost_user_get_protocol_features(struct virtio_user_dev *dev, uint64_t *features)
 {
 	int ret;
+	struct vhost_user_data *data = dev->backend_data;
 	struct vhost_user_msg msg = {
 		.request = VHOST_USER_GET_PROTOCOL_FEATURES,
 		.flags = VHOST_USER_VERSION,
 	};
 
-	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+	ret = vhost_user_write(data->vhostfd, &msg, NULL, 0);
 	if (ret < 0)
 		goto err;
 
-	ret = vhost_user_read(dev->vhostfd, &msg);
+	ret = vhost_user_read(data->vhostfd, &msg);
 	if (ret < 0)
 		goto err;
 
@@ -270,6 +276,7 @@ static int
 vhost_user_set_protocol_features(struct virtio_user_dev *dev, uint64_t features)
 {
 	int ret;
+	struct vhost_user_data *data = dev->backend_data;
 	struct vhost_user_msg msg = {
 		.request = VHOST_USER_SET_PROTOCOL_FEATURES,
 		.flags = VHOST_USER_VERSION,
@@ -277,7 +284,7 @@ vhost_user_set_protocol_features(struct virtio_user_dev *dev, uint64_t features)
 		.payload.u64 = features,
 	};
 
-	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+	ret = vhost_user_write(data->vhostfd, &msg, NULL, 0);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "Failed to set protocol features");
 		return -1;
@@ -296,11 +303,11 @@ vhost_user_get_features(struct virtio_user_dev *dev, uint64_t *features)
 		.flags = VHOST_USER_VERSION,
 	};
 
-	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+	ret = vhost_user_write(data->vhostfd, &msg, NULL, 0);
 	if (ret < 0)
 		goto err;
 
-	ret = vhost_user_read(dev->vhostfd, &msg);
+	ret = vhost_user_read(data->vhostfd, &msg);
 	if (ret < 0)
 		goto err;
 
@@ -344,6 +351,7 @@ static int
 vhost_user_set_features(struct virtio_user_dev *dev, uint64_t features)
 {
 	int ret;
+	struct vhost_user_data *data = dev->backend_data;
 	struct vhost_user_msg msg = {
 		.request = VHOST_USER_SET_FEATURES,
 		.flags = VHOST_USER_VERSION,
@@ -353,7 +361,7 @@ vhost_user_set_features(struct virtio_user_dev *dev, uint64_t features)
 
 	msg.payload.u64 |= dev->device_features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES);
 
-	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+	ret = vhost_user_write(data->vhostfd, &msg, NULL, 0);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "Failed to set features");
 		return -1;
@@ -477,7 +485,7 @@ vhost_user_set_memory_table(struct virtio_user_dev *dev)
 	msg.size += sizeof(msg.payload.memory.padding);
 	msg.size += fd_num * sizeof(struct vhost_memory_region);
 
-	ret = vhost_user_write(dev->vhostfd, &msg, fds, fd_num);
+	ret = vhost_user_write(data->vhostfd, &msg, fds, fd_num);
 	if (ret < 0)
 		goto err;
 
@@ -492,6 +500,7 @@ vhost_user_set_vring(struct virtio_user_dev *dev, enum vhost_user_request req,
 		struct vhost_vring_state *state)
 {
 	int ret;
+	struct vhost_user_data *data = dev->backend_data;
 	struct vhost_user_msg msg = {
 		.request = req,
 		.flags = VHOST_USER_VERSION,
@@ -499,7 +508,7 @@ vhost_user_set_vring(struct virtio_user_dev *dev, enum vhost_user_request req,
 		.payload.state = *state,
 	};
 
-	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+	ret = vhost_user_write(data->vhostfd, &msg, NULL, 0);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "Failed to set vring state (request %d)", req);
 		return -1;
@@ -531,6 +540,7 @@ vhost_user_get_vring_base(struct virtio_user_dev *dev, struct vhost_vring_state
 {
 	int ret;
 	struct vhost_user_msg msg;
+	struct vhost_user_data *data = dev->backend_data;
 	unsigned int index = state->index;
 
 	ret = vhost_user_set_vring(dev, VHOST_USER_GET_VRING_BASE, state);
@@ -539,7 +549,7 @@ vhost_user_get_vring_base(struct virtio_user_dev *dev, struct vhost_vring_state
 		goto err;
 	}
 
-	ret = vhost_user_read(dev->vhostfd, &msg);
+	ret = vhost_user_read(data->vhostfd, &msg);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "Failed to read reply");
 		goto err;
@@ -575,6 +585,7 @@ vhost_user_set_vring_file(struct virtio_user_dev *dev, enum vhost_user_request r
 	int ret;
 	int fd = file->fd;
 	int num_fd = 0;
+	struct vhost_user_data *data = dev->backend_data;
 	struct vhost_user_msg msg = {
 		.request = req,
 		.flags = VHOST_USER_VERSION,
@@ -587,7 +598,7 @@ vhost_user_set_vring_file(struct virtio_user_dev *dev, enum vhost_user_request r
 	else
 		msg.payload.u64 |= VHOST_USER_VRING_NOFD_MASK;
 
-	ret = vhost_user_write(dev->vhostfd, &msg, &fd, num_fd);
+	ret = vhost_user_write(data->vhostfd, &msg, &fd, num_fd);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "Failed to set vring file (request %d)", req);
 		return -1;
@@ -613,6 +624,7 @@ static int
 vhost_user_set_vring_addr(struct virtio_user_dev *dev, struct vhost_vring_addr *addr)
 {
 	int ret;
+	struct vhost_user_data *data = dev->backend_data;
 	struct vhost_user_msg msg = {
 		.request = VHOST_USER_SET_VRING_ADDR,
 		.flags = VHOST_USER_VERSION,
@@ -620,7 +632,7 @@ vhost_user_set_vring_addr(struct virtio_user_dev *dev, struct vhost_vring_addr *
 		.payload.addr = *addr,
 	};
 
-	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+	ret = vhost_user_write(data->vhostfd, &msg, NULL, 0);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "Failed to send vring addresses");
 		return -1;
@@ -653,13 +665,13 @@ vhost_user_get_status(struct virtio_user_dev *dev, uint8_t *status)
 	if (!(data->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_STATUS)))
 		return -ENOTSUP;
 
-	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+	ret = vhost_user_write(data->vhostfd, &msg, NULL, 0);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "Failed to send request");
 		goto err;
 	}
 
-	ret = vhost_user_read(dev->vhostfd, &msg);
+	ret = vhost_user_read(data->vhostfd, &msg);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "Failed to recv request");
 		goto err;
@@ -712,7 +724,7 @@ vhost_user_set_status(struct virtio_user_dev *dev, uint8_t status)
 	if (data->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK))
 		msg.flags |= VHOST_USER_NEED_REPLY_MASK;
 
-	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
+	ret = vhost_user_write(data->vhostfd, &msg, NULL, 0);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "Failed to send get status request");
 		return -1;
@@ -723,11 +735,12 @@ vhost_user_set_status(struct virtio_user_dev *dev, uint8_t status)
 
 #define MAX_VIRTIO_USER_BACKLOG 1
 static int
-virtio_user_start_server(struct virtio_user_dev *dev, struct sockaddr_un *un)
+vhost_user_start_server(struct virtio_user_dev *dev, struct sockaddr_un *un)
 {
 	int ret;
 	int flag;
-	int fd = dev->listenfd;
+	struct vhost_user_data *data = dev->backend_data;
+	int fd = data->listenfd;
 
 	ret = bind(fd, (struct sockaddr *)un, sizeof(*un));
 	if (ret < 0) {
@@ -740,8 +753,8 @@ virtio_user_start_server(struct virtio_user_dev *dev, struct sockaddr_un *un)
 		return -1;
 
 	PMD_DRV_LOG(NOTICE, "(%s) waiting for client connection...", dev->path);
-	dev->vhostfd = accept(fd, NULL, NULL);
-	if (dev->vhostfd < 0) {
+	data->vhostfd = accept(fd, NULL, NULL);
+	if (data->vhostfd < 0) {
 		PMD_DRV_LOG(ERR, "Failed to accept initial client connection (%s)",
 				strerror(errno));
 		return -1;
@@ -756,6 +769,37 @@ virtio_user_start_server(struct virtio_user_dev *dev, struct sockaddr_un *un)
 	return 0;
 }
 
+static int
+vhost_user_server_disconnect(struct virtio_user_dev *dev)
+{
+	struct vhost_user_data *data = dev->backend_data;
+
+	if (data->vhostfd < 0) {
+		PMD_DRV_LOG(ERR, "(%s) Expected valid Vhost FD", dev->path);
+		return -1;
+	}
+
+	close(data->vhostfd);
+	data->vhostfd = -1;
+
+	return 0;
+}
+
+static int
+vhost_user_server_reconnect(struct virtio_user_dev *dev)
+{
+	struct vhost_user_data *data = dev->backend_data;
+	int fd;
+
+	fd = accept(data->listenfd, NULL, NULL);
+	if (fd < 0)
+		return -1;
+
+	data->vhostfd = fd;
+
+	return 0;
+}
+
 /**
  * Set up environment to talk with a vhost user backend.
  *
@@ -781,6 +825,8 @@ vhost_user_setup(struct virtio_user_dev *dev)
 
 	dev->backend_data = data;
 
+	data->vhostfd = -1;
+
 	fd = socket(AF_UNIX, SOCK_STREAM, 0);
 	if (fd < 0) {
 		PMD_DRV_LOG(ERR, "socket() error, %s", strerror(errno));
@@ -796,8 +842,8 @@ vhost_user_setup(struct virtio_user_dev *dev)
 	strlcpy(un.sun_path, dev->path, sizeof(un.sun_path));
 
 	if (dev->is_server) {
-		dev->listenfd = fd;
-		if (virtio_user_start_server(dev, &un) < 0) {
+		data->listenfd = fd;
+		if (vhost_user_start_server(dev, &un) < 0) {
 			PMD_DRV_LOG(ERR, "virtio-user startup fails in server mode");
 			goto err_socket;
 		}
@@ -806,7 +852,7 @@ vhost_user_setup(struct virtio_user_dev *dev)
 			PMD_DRV_LOG(ERR, "connect error, %s", strerror(errno));
 			goto err_socket;
 		}
-		dev->vhostfd = fd;
+		data->vhostfd = fd;
 	}
 
 	return 0;
@@ -823,11 +869,24 @@ vhost_user_setup(struct virtio_user_dev *dev)
 static int
 vhost_user_destroy(struct virtio_user_dev *dev)
 {
-	if (dev->backend_data) {
-		free(dev->backend_data);
-		dev->backend_data = NULL;
+	struct vhost_user_data *data = dev->backend_data;
+
+	if (!data)
+		return 0;
+
+	if (data->vhostfd >= 0) {
+		close(data->vhostfd);
+		data->vhostfd = -1;
 	}
 
+	if (data->listenfd >= 0) {
+		close(data->listenfd);
+		data->listenfd = -1;
+	}
+
+	free(data);
+	dev->backend_data = NULL;
+
 	return 0;
 }
 
@@ -836,8 +895,12 @@ vhost_user_enable_queue_pair(struct virtio_user_dev *dev,
 			     uint16_t pair_idx,
 			     int enable)
 {
+	struct vhost_user_data *data = dev->backend_data;
 	int i;
 
+	if (data->vhostfd < 0)
+		return 0;
+
 	if (dev->qp_enabled[pair_idx] == enable)
 		return 0;
 
@@ -863,6 +926,61 @@ vhost_user_get_backend_features(uint64_t *features)
 	return 0;
 }
 
+static int
+vhost_user_update_link_state(struct virtio_user_dev *dev)
+{
+	struct vhost_user_data *data = dev->backend_data;
+	char buf[128];
+
+	if (data->vhostfd >= 0) {
+		int r;
+		int flags;
+
+		flags = fcntl(data->vhostfd, F_GETFL);
+		if (fcntl(data->vhostfd, F_SETFL, flags | O_NONBLOCK) == -1) {
+			PMD_DRV_LOG(ERR, "error setting O_NONBLOCK flag");
+			return -1;
+		}
+
+		r = recv(data->vhostfd, buf, 128, MSG_PEEK);
+		if (r == 0 || (r < 0 && errno != EAGAIN)) {
+			dev->net_status &= (~VIRTIO_NET_S_LINK_UP);
+			PMD_DRV_LOG(ERR, "virtio-user port %u is down", dev->port_id);
+
+			/* This function could be called in the process
+			 * of interrupt handling, callback cannot be
+			 * unregistered here, set an alarm to do it.
+			 */
+			rte_eal_alarm_set(1, virtio_user_dev_delayed_handler, (void *)dev);
+		} else {
+			dev->net_status |= VIRTIO_NET_S_LINK_UP;
+		}
+
+		if (fcntl(data->vhostfd, F_SETFL,
+					flags & ~O_NONBLOCK) == -1) {
+			PMD_DRV_LOG(ERR, "error clearing O_NONBLOCK flag");
+			return -1;
+		}
+	} else if (dev->is_server) {
+		dev->net_status &= (~VIRTIO_NET_S_LINK_UP);
+		if (virtio_user_dev_server_reconnect(dev) >= 0)
+			dev->net_status |= VIRTIO_NET_S_LINK_UP;
+	}
+
+	return 0;
+}
+
+static int
+vhost_user_get_intr_fd(struct virtio_user_dev *dev)
+{
+	struct vhost_user_data *data = dev->backend_data;
+
+	if (dev->is_server && data->vhostfd == -1)
+		return data->listenfd;
+
+	return data->vhostfd;
+}
+
 struct virtio_user_backend_ops virtio_ops_user = {
 	.setup = vhost_user_setup,
 	.destroy = vhost_user_destroy,
@@ -879,5 +997,9 @@ struct virtio_user_backend_ops virtio_ops_user = {
 	.set_vring_addr = vhost_user_set_vring_addr,
 	.get_status = vhost_user_get_status,
 	.set_status = vhost_user_set_status,
-	.enable_qp = vhost_user_enable_queue_pair
+	.enable_qp = vhost_user_enable_queue_pair,
+	.update_link_state = vhost_user_update_link_state,
+	.server_disconnect = vhost_user_server_disconnect,
+	.server_reconnect = vhost_user_server_reconnect,
+	.get_intr_fd = vhost_user_get_intr_fd,
 };
diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c b/drivers/net/virtio/virtio_user/vhost_vdpa.c
index f5a8943993..5e3778b682 100644
--- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
+++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
@@ -471,6 +471,20 @@ vhost_vdpa_get_backend_features(uint64_t *features)
 	return 0;
 }
 
+static int
+vhost_vdpa_update_link_state(struct virtio_user_dev *dev __rte_unused)
+{
+	/* Nothing to update (for now?) */
+	return 0;
+}
+
+static int
+vhost_vdpa_get_intr_fd(struct virtio_user_dev *dev __rte_unused)
+{
+	/* No link state interrupt with Vhost-vDPA */
+	return -1;
+}
+
 struct virtio_user_backend_ops virtio_ops_vdpa = {
 	.setup = vhost_vdpa_setup,
 	.destroy = vhost_vdpa_destroy,
@@ -490,4 +504,6 @@ struct virtio_user_backend_ops virtio_ops_vdpa = {
 	.enable_qp = vhost_vdpa_enable_queue_pair,
 	.dma_map = vhost_vdpa_dma_map_batch,
 	.dma_unmap = vhost_vdpa_dma_unmap_batch,
+	.update_link_state = vhost_vdpa_update_link_state,
+	.get_intr_fd = vhost_vdpa_get_intr_fd,
 };
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index 215819d46d..7128457e32 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -343,11 +343,7 @@ virtio_user_fill_intr_handle(struct virtio_user_dev *dev)
 	eth_dev->intr_handle->type = RTE_INTR_HANDLE_VDEV;
 	/* For virtio vdev, no need to read counter for clean */
 	eth_dev->intr_handle->efd_counter_size = 0;
-	eth_dev->intr_handle->fd = -1;
-	if (dev->vhostfd >= 0)
-		eth_dev->intr_handle->fd = dev->vhostfd;
-	else if (dev->is_server)
-		eth_dev->intr_handle->fd = dev->listenfd;
+	eth_dev->intr_handle->fd = dev->ops->get_intr_fd(dev);
 
 	return 0;
 }
@@ -404,7 +400,6 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
 {
 	uint32_t q;
 
-	dev->vhostfd = -1;
 	dev->vhostfds = NULL;
 	dev->tapfds = NULL;
 
@@ -598,15 +593,6 @@ virtio_user_dev_uninit(struct virtio_user_dev *dev)
 		close(dev->callfds[i]);
 		close(dev->kickfds[i]);
 	}
-
-	if (dev->vhostfd >= 0)
-		close(dev->vhostfd);
-
-	if (dev->is_server && dev->listenfd >= 0) {
-		close(dev->listenfd);
-		dev->listenfd = -1;
-	}
-
 	if (dev->vhostfds) {
 		for (i = 0; i < dev->max_queue_pairs; ++i) {
 			close(dev->vhostfds[i]);
@@ -637,15 +623,11 @@ virtio_user_handle_mq(struct virtio_user_dev *dev, uint16_t q_pairs)
 		return -1;
 	}
 
-	/* Server mode can't enable queue pairs if vhostfd is invalid,
-	 * always return 0 in this case.
-	 */
-	if (!dev->is_server || dev->vhostfd >= 0) {
-		for (i = 0; i < q_pairs; ++i)
-			ret |= dev->ops->enable_qp(dev, i, 1);
-		for (i = q_pairs; i < dev->max_queue_pairs; ++i)
-			ret |= dev->ops->enable_qp(dev, i, 0);
-	}
+	for (i = 0; i < q_pairs; ++i)
+		ret |= dev->ops->enable_qp(dev, i, 1);
+	for (i = q_pairs; i < dev->max_queue_pairs; ++i)
+		ret |= dev->ops->enable_qp(dev, i, 0);
+
 	dev->queue_pairs = q_pairs;
 
 	return ret;
@@ -860,3 +842,154 @@ virtio_user_dev_update_status(struct virtio_user_dev *dev)
 	pthread_mutex_unlock(&dev->mutex);
 	return ret;
 }
+
+int
+virtio_user_dev_update_link_state(struct virtio_user_dev *dev)
+{
+	if (dev->ops->update_link_state)
+		return dev->ops->update_link_state(dev);
+
+	return 0;
+}
+
+static void
+virtio_user_dev_reset_queues_packed(struct rte_eth_dev *eth_dev)
+{
+	struct virtio_user_dev *dev = eth_dev->data->dev_private;
+	struct virtio_hw *hw = &dev->hw;
+	struct virtnet_rx *rxvq;
+	struct virtnet_tx *txvq;
+	uint16_t i;
+
+	/* Add lock to avoid queue contention. */
+	rte_spinlock_lock(&hw->state_lock);
+	hw->started = 0;
+
+	/*
+	 * Waiting for datapath to complete before resetting queues.
+	 * 1 ms should be enough for the ongoing Tx/Rx function to finish.
+	 */
+	rte_delay_ms(1);
+
+	/* Vring reset for each Tx queue and Rx queue. */
+	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
+		rxvq = eth_dev->data->rx_queues[i];
+		virtqueue_rxvq_reset_packed(rxvq->vq);
+		virtio_dev_rx_queue_setup_finish(eth_dev, i);
+	}
+
+	for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
+		txvq = eth_dev->data->tx_queues[i];
+		virtqueue_txvq_reset_packed(txvq->vq);
+	}
+
+	hw->started = 1;
+	rte_spinlock_unlock(&hw->state_lock);
+}
+
+void
+virtio_user_dev_delayed_handler(void *param)
+{
+	struct virtio_user_dev *dev = param;
+	struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->port_id];
+
+	if (rte_intr_disable(eth_dev->intr_handle) < 0) {
+		PMD_DRV_LOG(ERR, "interrupt disable failed");
+		return;
+	}
+	rte_intr_callback_unregister(eth_dev->intr_handle,
+				     virtio_interrupt_handler, eth_dev);
+	if (dev->is_server) {
+		if (dev->ops->server_disconnect)
+			dev->ops->server_disconnect(dev);
+		eth_dev->intr_handle->fd = dev->ops->get_intr_fd(dev);
+		rte_intr_callback_register(eth_dev->intr_handle,
+					   virtio_interrupt_handler, eth_dev);
+		if (rte_intr_enable(eth_dev->intr_handle) < 0) {
+			PMD_DRV_LOG(ERR, "interrupt enable failed");
+			return;
+		}
+	}
+}
+
+int
+virtio_user_dev_server_reconnect(struct virtio_user_dev *dev)
+{
+	int ret, old_status;
+	struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->port_id];
+	struct virtio_hw *hw = &dev->hw;
+
+	if (!dev->ops->server_reconnect) {
+		PMD_DRV_LOG(ERR, "(%s) Missing server reconnect callback", dev->path);
+		return -1;
+	}
+
+	if (dev->ops->server_reconnect(dev)) {
+		PMD_DRV_LOG(ERR, "(%s) Reconnect callback call failed", dev->path);
+		return -1;
+	}
+
+	old_status = dev->status;
+
+	virtio_reset(hw);
+
+	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_ACK);
+
+	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);
+
+	if (dev->ops->get_features(dev, &dev->device_features) < 0) {
+		PMD_INIT_LOG(ERR, "get_features failed: %s",
+			     strerror(errno));
+		return -1;
+	}
+
+	dev->device_features |= dev->frontend_features;
+
+	/* unmask vhost-user unsupported features */
+	dev->device_features &= ~(dev->unsupported_features);
+
+	dev->features &= dev->device_features;
+
+	/* For packed ring, resetting queues is required in reconnection. */
+	if (virtio_with_packed_queue(hw) &&
+	   (old_status & VIRTIO_CONFIG_STATUS_DRIVER_OK)) {
+		PMD_INIT_LOG(NOTICE, "Packets on the fly will be dropped"
+				" when packed ring reconnecting.");
+		virtio_user_dev_reset_queues_packed(eth_dev);
+	}
+
+	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_FEATURES_OK);
+
+	/* Start the device */
+	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER_OK);
+	if (!dev->started)
+		return -1;
+
+	if (dev->queue_pairs > 1) {
+		ret = virtio_user_handle_mq(dev, dev->queue_pairs);
+		if (ret != 0) {
+			PMD_INIT_LOG(ERR, "Fails to enable multi-queue pairs!");
+			return -1;
+		}
+	}
+	if (eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC) {
+		if (rte_intr_disable(eth_dev->intr_handle) < 0) {
+			PMD_DRV_LOG(ERR, "interrupt disable failed");
+			return -1;
+		}
+		rte_intr_callback_unregister(eth_dev->intr_handle,
+					     virtio_interrupt_handler,
+					     eth_dev);
+
+		eth_dev->intr_handle->fd = dev->ops->get_intr_fd(dev);
+		rte_intr_callback_register(eth_dev->intr_handle,
+					   virtio_interrupt_handler, eth_dev);
+
+		if (rte_intr_enable(eth_dev->intr_handle) < 0) {
+			PMD_DRV_LOG(ERR, "interrupt enable failed");
+			return -1;
+		}
+	}
+	PMD_INIT_LOG(NOTICE, "server mode virtio-user reconnection succeeds!");
+	return 0;
+}
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h b/drivers/net/virtio/virtio_user/virtio_user_dev.h
index 7650097b6d..36d2410546 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
@@ -27,11 +27,11 @@ struct virtio_user_queue {
 struct virtio_user_dev {
 	struct virtio_hw hw;
 	enum virtio_user_backend_type backend_type;
-	/* for vhost_user backend */
-	int		vhostfd;
-	int		listenfd;   /* listening fd */
 	bool		is_server;  /* server or client mode */
 
+	/* for vhost_vdpa backend */
+	int		vhostfd;
+
 	/* for vhost_kernel backend */
 	char		*ifname;
 	int		*vhostfds;
@@ -85,5 +85,8 @@ void virtio_user_handle_cq_packed(struct virtio_user_dev *dev,
 uint8_t virtio_user_handle_mq(struct virtio_user_dev *dev, uint16_t q_pairs);
 int virtio_user_dev_set_status(struct virtio_user_dev *dev, uint8_t status);
 int virtio_user_dev_update_status(struct virtio_user_dev *dev);
+int virtio_user_dev_update_link_state(struct virtio_user_dev *dev);
+void virtio_user_dev_delayed_handler(void *param);
+int virtio_user_dev_server_reconnect(struct virtio_user_dev *dev);
 extern const char * const virtio_user_backend_strings[];
 #endif
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index e2c606a838..063a723872 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -28,146 +28,6 @@
 
 #define virtio_user_get_dev(hwp) container_of(hwp, struct virtio_user_dev, hw)
 
-static void
-virtio_user_reset_queues_packed(struct rte_eth_dev *eth_dev)
-{
-	struct virtio_user_dev *dev = eth_dev->data->dev_private;
-	struct virtio_hw *hw = &dev->hw;
-	struct virtnet_rx *rxvq;
-	struct virtnet_tx *txvq;
-	uint16_t i;
-
-	/* Add lock to avoid queue contention. */
-	rte_spinlock_lock(&hw->state_lock);
-	hw->started = 0;
-
-	/*
-	 * Waitting for datapath to complete before resetting queues.
-	 * 1 ms should be enough for the ongoing Tx/Rx function to finish.
-	 */
-	rte_delay_ms(1);
-
-	/* Vring reset for each Tx queue and Rx queue. */
-	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
-		rxvq = eth_dev->data->rx_queues[i];
-		virtqueue_rxvq_reset_packed(rxvq->vq);
-		virtio_dev_rx_queue_setup_finish(eth_dev, i);
-	}
-
-	for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
-		txvq = eth_dev->data->tx_queues[i];
-		virtqueue_txvq_reset_packed(txvq->vq);
-	}
-
-	hw->started = 1;
-	rte_spinlock_unlock(&hw->state_lock);
-}
-
-
-static int
-virtio_user_server_reconnect(struct virtio_user_dev *dev)
-{
-	int ret, connectfd, old_status;
-	struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->port_id];
-	struct virtio_hw *hw = &dev->hw;
-
-	connectfd = accept(dev->listenfd, NULL, NULL);
-	if (connectfd < 0)
-		return -1;
-
-	dev->vhostfd = connectfd;
-	old_status = dev->status;
-
-	virtio_reset(hw);
-
-	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_ACK);
-
-	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);
-
-	if (dev->ops->get_features(dev, &dev->device_features) < 0) {
-		PMD_INIT_LOG(ERR, "get_features failed: %s",
-			     strerror(errno));
-		return -1;
-	}
-
-	dev->device_features |= dev->frontend_features;
-
-	/* umask vhost-user unsupported features */
-	dev->device_features &= ~(dev->unsupported_features);
-
-	dev->features &= dev->device_features;
-
-	/* For packed ring, resetting queues is required in reconnection. */
-	if (virtio_with_packed_queue(hw) &&
-	   (old_status & VIRTIO_CONFIG_STATUS_DRIVER_OK)) {
-		PMD_INIT_LOG(NOTICE, "Packets on the fly will be dropped"
-				" when packed ring reconnecting.");
-		virtio_user_reset_queues_packed(eth_dev);
-	}
-
-	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_FEATURES_OK);
-
-	/* Start the device */
-	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER_OK);
-	if (!dev->started)
-		return -1;
-
-	if (dev->queue_pairs > 1) {
-		ret = virtio_user_handle_mq(dev, dev->queue_pairs);
-		if (ret != 0) {
-			PMD_INIT_LOG(ERR, "Fails to enable multi-queue pairs!");
-			return -1;
-		}
-	}
-	if (eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC) {
-		if (rte_intr_disable(eth_dev->intr_handle) < 0) {
-			PMD_DRV_LOG(ERR, "interrupt disable failed");
-			return -1;
-		}
-		rte_intr_callback_unregister(eth_dev->intr_handle,
-					     virtio_interrupt_handler,
-					     eth_dev);
-		eth_dev->intr_handle->fd = connectfd;
-		rte_intr_callback_register(eth_dev->intr_handle,
-					   virtio_interrupt_handler, eth_dev);
-
-		if (rte_intr_enable(eth_dev->intr_handle) < 0) {
-			PMD_DRV_LOG(ERR, "interrupt enable failed");
-			return -1;
-		}
-	}
-	PMD_INIT_LOG(NOTICE, "server mode virtio-user reconnection succeeds!");
-	return 0;
-}
-
-static void
-virtio_user_delayed_handler(void *param)
-{
-	struct virtio_hw *hw = (struct virtio_hw *)param;
-	struct rte_eth_dev *eth_dev = &rte_eth_devices[hw->port_id];
-	struct virtio_user_dev *dev = virtio_user_get_dev(hw);
-
-	if (rte_intr_disable(eth_dev->intr_handle) < 0) {
-		PMD_DRV_LOG(ERR, "interrupt disable failed");
-		return;
-	}
-	rte_intr_callback_unregister(eth_dev->intr_handle,
-				     virtio_interrupt_handler, eth_dev);
-	if (dev->is_server) {
-		if (dev->vhostfd >= 0) {
-			close(dev->vhostfd);
-			dev->vhostfd = -1;
-		}
-		eth_dev->intr_handle->fd = dev->listenfd;
-		rte_intr_callback_register(eth_dev->intr_handle,
-					   virtio_interrupt_handler, eth_dev);
-		if (rte_intr_enable(eth_dev->intr_handle) < 0) {
-			PMD_DRV_LOG(ERR, "interrupt enable failed");
-			return;
-		}
-	}
-}
-
 static void
 virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset,
 		     void *dst, int length)
@@ -183,44 +43,7 @@ virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset,
 	}
 
 	if (offset == offsetof(struct virtio_net_config, status)) {
-		char buf[128];
-
-		if (dev->vhostfd >= 0) {
-			int r;
-			int flags;
-
-			flags = fcntl(dev->vhostfd, F_GETFL);
-			if (fcntl(dev->vhostfd, F_SETFL,
-					flags | O_NONBLOCK) == -1) {
-				PMD_DRV_LOG(ERR, "error setting O_NONBLOCK flag");
-				return;
-			}
-			r = recv(dev->vhostfd, buf, 128, MSG_PEEK);
-			if (r == 0 || (r < 0 && errno != EAGAIN)) {
-				dev->net_status &= (~VIRTIO_NET_S_LINK_UP);
-				PMD_DRV_LOG(ERR, "virtio-user port %u is down",
-					    hw->port_id);
-
-				/* This function could be called in the process
-				 * of interrupt handling, callback cannot be
-				 * unregistered here, set an alarm to do it.
-				 */
-				rte_eal_alarm_set(1,
-						  virtio_user_delayed_handler,
-						  (void *)hw);
-			} else {
-				dev->net_status |= VIRTIO_NET_S_LINK_UP;
-			}
-			if (fcntl(dev->vhostfd, F_SETFL,
-					flags & ~O_NONBLOCK) == -1) {
-				PMD_DRV_LOG(ERR, "error clearing O_NONBLOCK flag");
-				return;
-			}
-		} else if (dev->is_server) {
-			dev->net_status &= (~VIRTIO_NET_S_LINK_UP);
-			if (virtio_user_server_reconnect(dev) >= 0)
-				dev->net_status |= VIRTIO_NET_S_LINK_UP;
-		}
+		virtio_user_dev_update_link_state(dev);
 
 		*(uint16_t *)dst = dev->net_status;
 	}
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 41/44] net/virtio: move Vhost-kernel data to its backend
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (39 preceding siblings ...)
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 40/44] net/virtio: move Vhost-user specifics to its backend Maxime Coquelin
@ 2021-01-19 21:25 ` Maxime Coquelin
  2021-01-22  8:55   ` Xia, Chenbo
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 42/44] net/virtio: move Vhost-vDPA " Maxime Coquelin
                   ` (2 subsequent siblings)
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:25 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

As done earlier for Vhost-user, this patch moves the
Vhost-Kernel specific data to its backend file.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_user/vhost_kernel.c | 106 +++++++++++++++---
 .../net/virtio/virtio_user/virtio_user_dev.c  |  43 ++-----
 .../net/virtio/virtio_user/virtio_user_dev.h  |   7 +-
 3 files changed, 98 insertions(+), 58 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c b/drivers/net/virtio/virtio_user/vhost_kernel.c
index aa1f9ece5e..bc4b3461e1 100644
--- a/drivers/net/virtio/virtio_user/vhost_kernel.c
+++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
@@ -14,6 +14,11 @@
 #include "virtio_user_dev.h"
 #include "vhost_kernel_tap.h"
 
+struct vhost_kernel_data {
+	int *vhostfds;
+	int *tapfds;
+};
+
 struct vhost_memory_kernel {
 	uint32_t nregions;
 	uint32_t padding;
@@ -96,7 +101,9 @@ vhost_kernel_ioctl(int fd, uint64_t request, void *arg)
 static int
 vhost_kernel_set_owner(struct virtio_user_dev *dev)
 {
-	return vhost_kernel_ioctl(dev->vhostfds[0], VHOST_SET_OWNER, NULL);
+	struct vhost_kernel_data *data = dev->backend_data;
+
+	return vhost_kernel_ioctl(data->vhostfds[0], VHOST_SET_OWNER, NULL);
 }
 
 static int
@@ -104,8 +111,9 @@ vhost_kernel_get_features(struct virtio_user_dev *dev, uint64_t *features)
 {
 	int ret;
 	unsigned int tap_features;
+	struct vhost_kernel_data *data = dev->backend_data;
 
-	ret = vhost_kernel_ioctl(dev->vhostfds[0], VHOST_GET_FEATURES, features);
+	ret = vhost_kernel_ioctl(data->vhostfds[0], VHOST_GET_FEATURES, features);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "Failed to get features");
 		return -1;
@@ -138,6 +146,8 @@ vhost_kernel_get_features(struct virtio_user_dev *dev, uint64_t *features)
 static int
 vhost_kernel_set_features(struct virtio_user_dev *dev, uint64_t features)
 {
+	struct vhost_kernel_data *data = dev->backend_data;
+
 	/* We don't need memory protection here */
 	features &= ~(1ULL << VIRTIO_F_IOMMU_PLATFORM);
 	/* VHOST kernel does not know about below flags */
@@ -145,7 +155,7 @@ vhost_kernel_set_features(struct virtio_user_dev *dev, uint64_t features)
 	features &= ~VHOST_KERNEL_HOST_OFFLOADS_MASK;
 	features &= ~(1ULL << VIRTIO_NET_F_MQ);
 
-	return vhost_kernel_ioctl(dev->vhostfds[0], VHOST_SET_FEATURES, &features);
+	return vhost_kernel_ioctl(data->vhostfds[0], VHOST_SET_FEATURES, &features);
 }
 
 static int
@@ -185,6 +195,7 @@ add_memseg_list(const struct rte_memseg_list *msl, void *arg)
 static int
 vhost_kernel_set_memory_table(struct virtio_user_dev *dev)
 {
+	struct vhost_kernel_data *data = dev->backend_data;
 	struct vhost_memory_kernel *vm;
 	int ret;
 
@@ -205,7 +216,7 @@ vhost_kernel_set_memory_table(struct virtio_user_dev *dev)
 	if (ret < 0)
 		goto err_free;
 
-	ret = vhost_kernel_ioctl(dev->vhostfds[0], VHOST_SET_MEM_TABLE, vm);
+	ret = vhost_kernel_ioctl(data->vhostfds[0], VHOST_SET_MEM_TABLE, vm);
 	if (ret < 0)
 		goto err_free;
 
@@ -224,9 +235,10 @@ vhost_kernel_set_vring(struct virtio_user_dev *dev, uint64_t req, struct vhost_v
 {
 	int ret, fd;
 	unsigned int index = state->index;
+	struct vhost_kernel_data *data = dev->backend_data;
 
 	/* Convert from queue index to queue-pair & offset */
-	fd = dev->vhostfds[state->index / 2];
+	fd = data->vhostfds[state->index / 2];
 	state->index %= 2;
 
 	ret = vhost_kernel_ioctl(fd, req, state);
@@ -265,9 +277,10 @@ vhost_kernel_set_vring_file(struct virtio_user_dev *dev, uint64_t req,
 {
 	int ret, fd;
 	unsigned int index = file->index;
+	struct vhost_kernel_data *data = dev->backend_data;
 
 	/* Convert from queue index to queue-pair & offset */
-	fd = dev->vhostfds[file->index / 2];
+	fd = data->vhostfds[file->index / 2];
 	file->index %= 2;
 
 	ret = vhost_kernel_ioctl(fd, req, file);
@@ -299,9 +312,10 @@ vhost_kernel_set_vring_addr(struct virtio_user_dev *dev, struct vhost_vring_addr
 {
 	int ret, fd;
 	unsigned int index = addr->index;
+	struct vhost_kernel_data *data = dev->backend_data;
 
 	/* Convert from queue index to queue-pair & offset */
-	fd = dev->vhostfds[addr->index / 2];
+	fd = data->vhostfds[addr->index / 2];
 	addr->index %= 2;
 
 	ret = vhost_kernel_ioctl(fd, VHOST_SET_VRING_ADDR, addr);
@@ -339,27 +353,82 @@ static int
 vhost_kernel_setup(struct virtio_user_dev *dev)
 {
 	int vhostfd;
-	uint32_t i;
+	uint32_t q, i;
+	struct vhost_kernel_data *data;
+
+	data = malloc(sizeof(*data));
+	if (!data) {
+		PMD_INIT_LOG(ERR, "(%s) Failed to allocate Vhost-kernel data", dev->path);
+		return -1;
+	}
+
+	data->vhostfds = malloc(dev->max_queue_pairs * sizeof(int));
+	if (!data->vhostfds) {
+		PMD_INIT_LOG(ERR, "(%s) Failed to allocate Vhost FDs", dev->path);
+		goto err_data;
+	}
+	data->tapfds = malloc(dev->max_queue_pairs * sizeof(int));
+	if (!data->tapfds) {
+		PMD_INIT_LOG(ERR, "(%s) Failed to allocate FDs", dev->path);
+		goto err_vhostfds;
+	}
+
+	for (q = 0; q < dev->max_queue_pairs; ++q) {
+		data->vhostfds[q] = -1;
+		data->tapfds[q] = -1;
+	}
 
 	get_vhost_kernel_max_regions();
 
 	for (i = 0; i < dev->max_queue_pairs; ++i) {
 		vhostfd = open(dev->path, O_RDWR);
 		if (vhostfd < 0) {
-			PMD_DRV_LOG(ERR, "fail to open %s, %s",
-				    dev->path, strerror(errno));
-			return -1;
+			PMD_DRV_LOG(ERR, "fail to open %s, %s", dev->path, strerror(errno));
+			goto err_tapfds;
 		}
 
-		dev->vhostfds[i] = vhostfd;
+		data->vhostfds[i] = vhostfd;
 	}
 
+	dev->backend_data = data;
+
 	return 0;
+
+err_tapfds:
+	for (i = 0; i < dev->max_queue_pairs; i++)
+		if (data->vhostfds[i] >= 0)
+			close(data->vhostfds[i]);
+
+	free(data->tapfds);
+err_vhostfds:
+	free(data->vhostfds);
+err_data:
+	free(data);
+
+	return -1;
 }
 
 static int
-vhost_kernel_destroy(struct virtio_user_dev *dev __rte_unused)
+vhost_kernel_destroy(struct virtio_user_dev *dev)
 {
+	struct vhost_kernel_data *data = dev->backend_data;
+	uint32_t i;
+
+	if (!data)
+		return 0;
+
+	for (i = 0; i < dev->max_queue_pairs; ++i) {
+		if (data->vhostfds[i] >= 0)
+			close(data->vhostfds[i]);
+		if (data->tapfds[i] >= 0)
+			close(data->tapfds[i]);
+	}
+
+	free(data->vhostfds);
+	free(data->tapfds);
+	free(data);
+	dev->backend_data = NULL;
+
 	return 0;
 }
 
@@ -395,14 +464,15 @@ vhost_kernel_enable_queue_pair(struct virtio_user_dev *dev,
 	int vhostfd;
 	int tapfd;
 	int req_mq = (dev->max_queue_pairs > 1);
+	struct vhost_kernel_data *data = dev->backend_data;
 
-	vhostfd = dev->vhostfds[pair_idx];
+	vhostfd = data->vhostfds[pair_idx];
 
 	if (dev->qp_enabled[pair_idx] == enable)
 		return 0;
 
 	if (!enable) {
-		tapfd = dev->tapfds[pair_idx];
+		tapfd = data->tapfds[pair_idx];
 		if (vhost_kernel_set_backend(vhostfd, -1) < 0) {
 			PMD_DRV_LOG(ERR, "fail to set backend for vhost kernel");
 			return -1;
@@ -415,8 +485,8 @@ vhost_kernel_enable_queue_pair(struct virtio_user_dev *dev,
 		return 0;
 	}
 
-	if (dev->tapfds[pair_idx] >= 0) {
-		tapfd = dev->tapfds[pair_idx];
+	if (data->tapfds[pair_idx] >= 0) {
+		tapfd = data->tapfds[pair_idx];
 		if (vhost_kernel_tap_set_offload(tapfd, dev->features) == -1)
 			return -1;
 		if (req_mq && vhost_kernel_tap_set_queue(tapfd, true) < 0) {
@@ -439,7 +509,7 @@ vhost_kernel_enable_queue_pair(struct virtio_user_dev *dev,
 		return -1;
 	}
 
-	dev->tapfds[pair_idx] = tapfd;
+	data->tapfds[pair_idx] = tapfd;
 
 set_backend:
 	if (vhost_kernel_set_backend(vhostfd, tapfd) < 0) {
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index 7128457e32..a1e32158bb 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -398,11 +398,6 @@ virtio_user_mem_event_cb(enum rte_mem_event type __rte_unused,
 static int
 virtio_user_dev_setup(struct virtio_user_dev *dev)
 {
-	uint32_t q;
-
-	dev->vhostfds = NULL;
-	dev->tapfds = NULL;
-
 	if (dev->is_server) {
 		if (dev->backend_type != VIRTIO_USER_BACKEND_VHOST_USER) {
 			PMD_DRV_LOG(ERR, "Server mode only supports vhost-user!");
@@ -410,34 +405,21 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
 		}
 	}
 
-	if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER) {
+	switch (dev->backend_type) {
+	case VIRTIO_USER_BACKEND_VHOST_USER:
 		dev->ops = &virtio_ops_user;
-	} else if (dev->backend_type ==
-			VIRTIO_USER_BACKEND_VHOST_KERNEL) {
+		break;
+	case VIRTIO_USER_BACKEND_VHOST_KERNEL:
 		dev->ops = &virtio_ops_kernel;
-
-		dev->vhostfds = malloc(dev->max_queue_pairs *
-				sizeof(int));
-		dev->tapfds = malloc(dev->max_queue_pairs *
-				sizeof(int));
-		if (!dev->vhostfds || !dev->tapfds) {
-			PMD_INIT_LOG(ERR, "(%s) Failed to allocate FDs", dev->path);
-			return -1;
-		}
-
-		for (q = 0; q < dev->max_queue_pairs; ++q) {
-			dev->vhostfds[q] = -1;
-			dev->tapfds[q] = -1;
-		}
-	} else if (dev->backend_type ==
-			VIRTIO_USER_BACKEND_VHOST_VDPA) {
+		break;
+	case VIRTIO_USER_BACKEND_VHOST_VDPA:
 		dev->ops = &virtio_ops_vdpa;
-	} else {
+		break;
+	default:
 		PMD_DRV_LOG(ERR, "(%s) Unknown backend type", dev->path);
 		return -1;
 	}
 
-
 	if (dev->ops->setup(dev) < 0) {
 		PMD_INIT_LOG(ERR, "(%s) Failed to setup backend\n", dev->path);
 		return -1;
@@ -593,15 +575,6 @@ virtio_user_dev_uninit(struct virtio_user_dev *dev)
 		close(dev->callfds[i]);
 		close(dev->kickfds[i]);
 	}
-	if (dev->vhostfds) {
-		for (i = 0; i < dev->max_queue_pairs; ++i) {
-			close(dev->vhostfds[i]);
-			if (dev->tapfds[i] >= 0)
-				close(dev->tapfds[i]);
-		}
-		free(dev->vhostfds);
-		free(dev->tapfds);
-	}
 
 	free(dev->ifname);
 
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h b/drivers/net/virtio/virtio_user/virtio_user_dev.h
index 36d2410546..36a9cadcad 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
@@ -32,11 +32,6 @@ struct virtio_user_dev {
 	/* for vhost_vdpa backend */
 	int		vhostfd;
 
-	/* for vhost_kernel backend */
-	char		*ifname;
-	int		*vhostfds;
-	int		*tapfds;
-
 	/* for both vhost_user and vhost_kernel */
 	int		callfds[VIRTIO_MAX_VIRTQUEUES];
 	int		kickfds[VIRTIO_MAX_VIRTQUEUES];
@@ -56,6 +51,8 @@ struct virtio_user_dev {
 	uint16_t	port_id;
 	uint8_t		mac_addr[RTE_ETHER_ADDR_LEN];
 	char		path[PATH_MAX];
+	char		*ifname;
+
 	union {
 		struct vring		vrings[VIRTIO_MAX_VIRTQUEUES];
 		struct vring_packed	packed_vrings[VIRTIO_MAX_VIRTQUEUES];
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 42/44] net/virtio: move Vhost-vDPA data to its backend
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (40 preceding siblings ...)
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 41/44] net/virtio: move Vhost-kernel data " Maxime Coquelin
@ 2021-01-19 21:25 ` Maxime Coquelin
  2021-01-22  9:06   ` Xia, Chenbo
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 43/44] net/virtio: improve Vhost-user error logging Maxime Coquelin
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 44/44] net/virtio: handle Virtio-user setup failure properly Maxime Coquelin
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:25 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

As done earlier for Vhost-user and Vhost-kernel, this
patch moves the Vhost-vDPA specific data to its backend
file.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_user/vhost_vdpa.c   | 120 +++++++++++++-----
 .../net/virtio/virtio_user/virtio_user_dev.h  |   4 -
 2 files changed, 89 insertions(+), 35 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c b/drivers/net/virtio/virtio_user/vhost_vdpa.c
index 5e3778b682..e2d6d3504d 100644
--- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
+++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
@@ -13,6 +13,11 @@
 #include "vhost.h"
 #include "virtio_user_dev.h"
 
+struct vhost_vdpa_data {
+	int vhostfd;
+	uint64_t protocol_features;
+};
+
 #define VHOST_VDPA_SUPPORTED_BACKEND_FEATURES		\
 	(1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2	|	\
 	1ULL << VHOST_BACKEND_F_IOTLB_BATCH)
@@ -88,27 +93,34 @@ vhost_vdpa_ioctl(int fd, uint64_t request, void *arg)
 static int
 vhost_vdpa_set_owner(struct virtio_user_dev *dev)
 {
-	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_OWNER, NULL);
+	struct vhost_vdpa_data *data = dev->backend_data;
+
+	return vhost_vdpa_ioctl(data->vhostfd, VHOST_SET_OWNER, NULL);
 }
 
 static int
 vhost_vdpa_get_protocol_features(struct virtio_user_dev *dev, uint64_t *features)
 {
-	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_GET_BACKEND_FEATURES, features);
+	struct vhost_vdpa_data *data = dev->backend_data;
+
+	return vhost_vdpa_ioctl(data->vhostfd, VHOST_GET_BACKEND_FEATURES, features);
 }
 
 static int
 vhost_vdpa_set_protocol_features(struct virtio_user_dev *dev, uint64_t features)
 {
-	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_BACKEND_FEATURES, &features);
+	struct vhost_vdpa_data *data = dev->backend_data;
+
+	return vhost_vdpa_ioctl(data->vhostfd, VHOST_SET_BACKEND_FEATURES, &features);
 }
 
 static int
 vhost_vdpa_get_features(struct virtio_user_dev *dev, uint64_t *features)
 {
+	struct vhost_vdpa_data *data = dev->backend_data;
 	int ret;
 
-	ret = vhost_vdpa_ioctl(dev->vhostfd, VHOST_GET_FEATURES, features);
+	ret = vhost_vdpa_ioctl(data->vhostfd, VHOST_GET_FEATURES, features);
 	if (ret) {
 		PMD_DRV_LOG(ERR, "Failed to get features");
 		return -1;
@@ -118,15 +130,15 @@ vhost_vdpa_get_features(struct virtio_user_dev *dev, uint64_t *features)
 	*features &= ~(1ULL << VIRTIO_NET_F_MQ);
 
 	/* Negotiated vDPA backend features */
-	ret = vhost_vdpa_get_protocol_features(dev, &dev->protocol_features);
+	ret = vhost_vdpa_get_protocol_features(dev, &data->protocol_features);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "Failed to get backend features");
 		return -1;
 	}
 
-	dev->protocol_features &= VHOST_VDPA_SUPPORTED_BACKEND_FEATURES;
+	data->protocol_features &= VHOST_VDPA_SUPPORTED_BACKEND_FEATURES;
 
-	ret = vhost_vdpa_set_protocol_features(dev, dev->protocol_features);
+	ret = vhost_vdpa_set_protocol_features(dev, data->protocol_features);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "Failed to set backend features");
 		return -1;
@@ -138,21 +150,24 @@ vhost_vdpa_get_features(struct virtio_user_dev *dev, uint64_t *features)
 static int
 vhost_vdpa_set_features(struct virtio_user_dev *dev, uint64_t features)
 {
+	struct vhost_vdpa_data *data = dev->backend_data;
+
 	/* WORKAROUND */
 	features |= 1ULL << VIRTIO_F_IOMMU_PLATFORM;
 
-	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_FEATURES, &features);
+	return vhost_vdpa_ioctl(data->vhostfd, VHOST_SET_FEATURES, &features);
 }
 
 static int
 vhost_vdpa_iotlb_batch_begin(struct virtio_user_dev *dev)
 {
+	struct vhost_vdpa_data *data = dev->backend_data;
 	struct vhost_msg msg = {};
 
-	if (!(dev->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_BATCH)))
+	if (!(data->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_BATCH)))
 		return 0;
 
-	if (!(dev->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2))) {
+	if (!(data->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2))) {
 		PMD_DRV_LOG(ERR, "IOTLB_MSG_V2 not supported by the backend.");
 		return -1;
 	}
@@ -160,7 +175,7 @@ vhost_vdpa_iotlb_batch_begin(struct virtio_user_dev *dev)
 	msg.type = VHOST_IOTLB_MSG_V2;
 	msg.iotlb.type = VHOST_IOTLB_BATCH_BEGIN;
 
-	if (write(dev->vhostfd, &msg, sizeof(msg)) != sizeof(msg)) {
+	if (write(data->vhostfd, &msg, sizeof(msg)) != sizeof(msg)) {
 		PMD_DRV_LOG(ERR, "Failed to send IOTLB batch begin (%s)",
 				strerror(errno));
 		return -1;
@@ -172,12 +187,13 @@ vhost_vdpa_iotlb_batch_begin(struct virtio_user_dev *dev)
 static int
 vhost_vdpa_iotlb_batch_end(struct virtio_user_dev *dev)
 {
+	struct vhost_vdpa_data *data = dev->backend_data;
 	struct vhost_msg msg = {};
 
-	if (!(dev->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_BATCH)))
+	if (!(data->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_BATCH)))
 		return 0;
 
-	if (!(dev->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2))) {
+	if (!(data->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2))) {
 		PMD_DRV_LOG(ERR, "IOTLB_MSG_V2 not supported by the backend.");
 		return -1;
 	}
@@ -185,7 +201,7 @@ vhost_vdpa_iotlb_batch_end(struct virtio_user_dev *dev)
 	msg.type = VHOST_IOTLB_MSG_V2;
 	msg.iotlb.type = VHOST_IOTLB_BATCH_END;
 
-	if (write(dev->vhostfd, &msg, sizeof(msg)) != sizeof(msg)) {
+	if (write(data->vhostfd, &msg, sizeof(msg)) != sizeof(msg)) {
 		PMD_DRV_LOG(ERR, "Failed to send IOTLB batch end (%s)",
 				strerror(errno));
 		return -1;
@@ -198,9 +214,10 @@ static int
 vhost_vdpa_dma_map(struct virtio_user_dev *dev, void *addr,
 				  uint64_t iova, size_t len)
 {
+	struct vhost_vdpa_data *data = dev->backend_data;
 	struct vhost_msg msg = {};
 
-	if (!(dev->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2))) {
+	if (!(data->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2))) {
 		PMD_DRV_LOG(ERR, "IOTLB_MSG_V2 not supported by the backend.");
 		return -1;
 	}
@@ -215,7 +232,7 @@ vhost_vdpa_dma_map(struct virtio_user_dev *dev, void *addr,
 	PMD_DRV_LOG(DEBUG, "%s: iova: 0x%" PRIx64 ", addr: %p, len: 0x%zx",
 			__func__, iova, addr, len);
 
-	if (write(dev->vhostfd, &msg, sizeof(msg)) != sizeof(msg)) {
+	if (write(data->vhostfd, &msg, sizeof(msg)) != sizeof(msg)) {
 		PMD_DRV_LOG(ERR, "Failed to send IOTLB update (%s)",
 				strerror(errno));
 		return -1;
@@ -228,9 +245,10 @@ static int
 vhost_vdpa_dma_unmap(struct virtio_user_dev *dev, __rte_unused void *addr,
 				  uint64_t iova, size_t len)
 {
+	struct vhost_vdpa_data *data = dev->backend_data;
 	struct vhost_msg msg = {};
 
-	if (!(dev->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2))) {
+	if (!(data->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2))) {
 		PMD_DRV_LOG(ERR, "IOTLB_MSG_V2 not supported by the backend.");
 		return -1;
 	}
@@ -243,7 +261,7 @@ vhost_vdpa_dma_unmap(struct virtio_user_dev *dev, __rte_unused void *addr,
 	PMD_DRV_LOG(DEBUG, "%s: iova: 0x%" PRIx64 ", len: 0x%zx",
 			__func__, iova, len);
 
-	if (write(dev->vhostfd, &msg, sizeof(msg)) != sizeof(msg)) {
+	if (write(data->vhostfd, &msg, sizeof(msg)) != sizeof(msg)) {
 		PMD_DRV_LOG(ERR, "Failed to send IOTLB invalidate (%s)",
 				strerror(errno));
 		return -1;
@@ -353,55 +371,73 @@ vhost_vdpa_set_memory_table(struct virtio_user_dev *dev)
 static int
 vhost_vdpa_set_vring_enable(struct virtio_user_dev *dev, struct vhost_vring_state *state)
 {
-	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_VDPA_SET_VRING_ENABLE, state);
+	struct vhost_vdpa_data *data = dev->backend_data;
+
+	return vhost_vdpa_ioctl(data->vhostfd, VHOST_VDPA_SET_VRING_ENABLE, state);
 }
 
 static int
 vhost_vdpa_set_vring_num(struct virtio_user_dev *dev, struct vhost_vring_state *state)
 {
-	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_NUM, state);
+	struct vhost_vdpa_data *data = dev->backend_data;
+
+	return vhost_vdpa_ioctl(data->vhostfd, VHOST_SET_VRING_NUM, state);
 }
 
 static int
 vhost_vdpa_set_vring_base(struct virtio_user_dev *dev, struct vhost_vring_state *state)
 {
-	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_BASE, state);
+	struct vhost_vdpa_data *data = dev->backend_data;
+
+	return vhost_vdpa_ioctl(data->vhostfd, VHOST_SET_VRING_BASE, state);
 }
 
 static int
 vhost_vdpa_get_vring_base(struct virtio_user_dev *dev, struct vhost_vring_state *state)
 {
-	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_GET_VRING_BASE, state);
+	struct vhost_vdpa_data *data = dev->backend_data;
+
+	return vhost_vdpa_ioctl(data->vhostfd, VHOST_GET_VRING_BASE, state);
 }
 
 static int
 vhost_vdpa_set_vring_call(struct virtio_user_dev *dev, struct vhost_vring_file *file)
 {
-	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_CALL, file);
+	struct vhost_vdpa_data *data = dev->backend_data;
+
+	return vhost_vdpa_ioctl(data->vhostfd, VHOST_SET_VRING_CALL, file);
 }
 
 static int
 vhost_vdpa_set_vring_kick(struct virtio_user_dev *dev, struct vhost_vring_file *file)
 {
-	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_KICK, file);
+	struct vhost_vdpa_data *data = dev->backend_data;
+
+	return vhost_vdpa_ioctl(data->vhostfd, VHOST_SET_VRING_KICK, file);
 }
 
 static int
 vhost_vdpa_set_vring_addr(struct virtio_user_dev *dev, struct vhost_vring_addr *addr)
 {
-	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_ADDR, addr);
+	struct vhost_vdpa_data *data = dev->backend_data;
+
+	return vhost_vdpa_ioctl(data->vhostfd, VHOST_SET_VRING_ADDR, addr);
 }
 
 static int
 vhost_vdpa_get_status(struct virtio_user_dev *dev, uint8_t *status)
 {
-	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_VDPA_GET_STATUS, status);
+	struct vhost_vdpa_data *data = dev->backend_data;
+
+	return vhost_vdpa_ioctl(data->vhostfd, VHOST_VDPA_GET_STATUS, status);
 }
 
 static int
 vhost_vdpa_set_status(struct virtio_user_dev *dev, uint8_t status)
 {
-	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_VDPA_SET_STATUS, &status);
+	struct vhost_vdpa_data *data = dev->backend_data;
+
+	return vhost_vdpa_ioctl(data->vhostfd, VHOST_VDPA_SET_STATUS, &status);
 }
 
 /**
@@ -414,27 +450,49 @@ vhost_vdpa_set_status(struct virtio_user_dev *dev, uint8_t status)
 static int
 vhost_vdpa_setup(struct virtio_user_dev *dev)
 {
+	struct vhost_vdpa_data *data;
 	uint32_t did = (uint32_t)-1;
 
-	dev->vhostfd = open(dev->path, O_RDWR);
-	if (dev->vhostfd < 0) {
+	data = malloc(sizeof(*data));
+	if (!data) {
+		PMD_DRV_LOG(ERR, "(%s) Faidle to allocate backend data", dev->path);
+		return -1;
+	}
+
+	data->vhostfd = open(dev->path, O_RDWR);
+	if (data->vhostfd < 0) {
 		PMD_DRV_LOG(ERR, "Failed to open %s: %s\n",
 				dev->path, strerror(errno));
+		free(data);
 		return -1;
 	}
 
-	if (ioctl(dev->vhostfd, VHOST_VDPA_GET_DEVICE_ID, &did) < 0 ||
+	if (ioctl(data->vhostfd, VHOST_VDPA_GET_DEVICE_ID, &did) < 0 ||
 			did != VIRTIO_ID_NETWORK) {
 		PMD_DRV_LOG(ERR, "Invalid vdpa device ID: %u\n", did);
+		close(data->vhostfd);
+		free(data);
 		return -1;
 	}
 
+	dev->backend_data = data;
+
 	return 0;
 }
 
 static int
-vhost_vdpa_destroy(struct virtio_user_dev *dev __rte_unused)
+vhost_vdpa_destroy(struct virtio_user_dev *dev)
 {
+	struct vhost_vdpa_data *data = dev->backend_data;
+
+	if (!data)
+		return 0;
+
+	close(data->vhostfd);
+
+	free(data);
+	dev->backend_data = NULL;
+
 	return 0;
 }
 
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h b/drivers/net/virtio/virtio_user/virtio_user_dev.h
index 36a9cadcad..9a6723da24 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
@@ -29,9 +29,6 @@ struct virtio_user_dev {
 	enum virtio_user_backend_type backend_type;
 	bool		is_server;  /* server or client mode */
 
-	/* for vhost_vdpa backend */
-	int		vhostfd;
-
 	/* for both vhost_user and vhost_kernel */
 	int		callfds[VIRTIO_MAX_VIRTQUEUES];
 	int		kickfds[VIRTIO_MAX_VIRTQUEUES];
@@ -45,7 +42,6 @@ struct virtio_user_dev {
 	uint64_t	device_features; /* supported features by device */
 	uint64_t	frontend_features; /* enabled frontend features */
 	uint64_t	unsupported_features; /* unsupported features mask */
-	uint64_t	protocol_features; /* negotiated protocol features */
 	uint8_t		status;
 	uint16_t	net_status;
 	uint16_t	port_id;
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 43/44] net/virtio: improve Vhost-user error logging
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (41 preceding siblings ...)
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 42/44] net/virtio: move Vhost-vDPA " Maxime Coquelin
@ 2021-01-19 21:25 ` Maxime Coquelin
  2021-01-22  9:11   ` Xia, Chenbo
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 44/44] net/virtio: handle Virtio-user setup failure properly Maxime Coquelin
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:25 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch improves error logging in vhost_user_read,
especially printing errno when recv() fails.

Suggested-by: Adrian Moreno <amorenoz@redhat.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_user/vhost_user.c | 29 ++++++++++++---------
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/vhost_user.c b/drivers/net/virtio/virtio_user/vhost_user.c
index f046655af6..be91c99cea 100644
--- a/drivers/net/virtio/virtio_user/vhost_user.c
+++ b/drivers/net/virtio/virtio_user/vhost_user.c
@@ -148,38 +148,43 @@ vhost_user_read(int fd, struct vhost_user_msg *msg)
 	int ret, sz_hdr = VHOST_USER_HDR_SIZE, sz_payload;
 
 	ret = recv(fd, (void *)msg, sz_hdr, 0);
-	if (ret < sz_hdr) {
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to recv msg header: %s", strerror(errno));
+		return -1;
+	} else if (ret < sz_hdr) {
 		PMD_DRV_LOG(ERR, "Failed to recv msg hdr: %d instead of %d.",
 			    ret, sz_hdr);
-		goto fail;
+		return -1;
 	}
 
 	/* validate msg flags */
 	if (msg->flags != (valid_flags)) {
 		PMD_DRV_LOG(ERR, "Failed to recv msg: flags %x instead of %x.",
 			    msg->flags, valid_flags);
-		goto fail;
+		return -1;
 	}
 
 	sz_payload = msg->size;
 
-	if ((size_t)sz_payload > sizeof(msg->payload))
-		goto fail;
+	if ((size_t)sz_payload > sizeof(msg->payload)) {
+		PMD_DRV_LOG(ERR, "Payload size overflow, header says %d but max %zu\n",
+				sz_payload, sizeof(msg->payload));
+		return -1;
+	}
 
 	if (sz_payload) {
 		ret = recv(fd, (void *)((char *)msg + sz_hdr), sz_payload, 0);
-		if (ret < sz_payload) {
-			PMD_DRV_LOG(ERR,
-				"Failed to recv msg payload: %d instead of %d.",
+		if (ret < 0) {
+			PMD_DRV_LOG(ERR, "Failed to recv msg payload: %s", strerror(errno));
+			return -1;
+		} else if (ret < sz_payload) {
+			PMD_DRV_LOG(ERR, "Failed to recv msg payload: %d instead of %u.",
 				ret, msg->size);
-			goto fail;
+			return -1;
 		}
 	}
 
 	return 0;
-
-fail:
-	return -1;
 }
 
 static int
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [dpdk-dev] [PATCH v2 44/44] net/virtio: handle Virtio-user setup failure properly
  2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
                   ` (42 preceding siblings ...)
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 43/44] net/virtio: improve Vhost-user error logging Maxime Coquelin
@ 2021-01-19 21:25 ` Maxime Coquelin
  2021-01-22  9:24   ` Xia, Chenbo
  43 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-19 21:25 UTC (permalink / raw)
  To: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand; +Cc: Maxime Coquelin

This patch fixes virtio_user_dev_setup() error path,
by cleaning all resources it allocates.

Suggested-by: Adrian Moreno <amorenoz@redhat.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 drivers/net/virtio/virtio_user/virtio_user_dev.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index a1e32158bb..2f7dc574b6 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -427,15 +427,22 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
 
 	if (virtio_user_dev_init_notify(dev) < 0) {
 		PMD_INIT_LOG(ERR, "(%s) Failed to init notifiers\n", dev->path);
-		return -1;
+		goto destroy;
 	}
 
 	if (virtio_user_fill_intr_handle(dev) < 0) {
 		PMD_INIT_LOG(ERR, "(%s) Failed to init interrupt handler\n", dev->path);
-		return -1;
+		goto uninit;
 	}
 
 	return 0;
+
+uninit:
+	virtio_user_dev_uninit(dev);
+destroy:
+	dev->ops->destroy(dev);
+
+	return -1;
 }
 
 /* Use below macro to filter features from vhost backend */
-- 
2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 01/44] bus/vdev: add helper to get vdev from eth dev
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 01/44] bus/vdev: add helper to get vdev from eth dev Maxime Coquelin
@ 2021-01-20  0:56   ` Thomas Monjalon
  2021-01-25 10:53     ` Maxime Coquelin
  2021-01-21  8:58   ` Xia, Chenbo
  1 sibling, 1 reply; 86+ messages in thread
From: Thomas Monjalon @ 2021-01-20  0:56 UTC (permalink / raw)
  To: Maxime Coquelin; +Cc: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand

19/01/2021 22:24, Maxime Coquelin:
> This patch adds an helper macro to get the rte_vdev_device
> pointer from a rte_eth_dev pointer.
> 
> This is similar to RTE_ETH_DEV_TO_PCI().
[...]
> --- a/drivers/bus/vdev/rte_bus_vdev.h
> +++ b/drivers/bus/vdev/rte_bus_vdev.h
> @@ -34,6 +34,8 @@ struct rte_vdev_device {
> +#define RTE_ETH_DEV_TO_VDEV(eth_dev)	RTE_DEV_TO_VDEV((eth_dev)->device)

Why these macros (vdev and PCI) are not in ethdev?



^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 02/44] bus/vdev: add driver IOVA VA mode requirement
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 02/44] bus/vdev: add driver IOVA VA mode requirement Maxime Coquelin
@ 2021-01-20 15:32   ` David Marchand
  2021-01-20 17:47     ` Maxime Coquelin
  0 siblings, 1 reply; 86+ messages in thread
From: David Marchand @ 2021-01-20 15:32 UTC (permalink / raw)
  To: Maxime Coquelin, Ray Kinsella
  Cc: dev, Xia, Chenbo, Olivier Matz, Adrian Moreno Zapata, Thomas Monjalon

On Tue, Jan 19, 2021 at 10:25 PM Maxime Coquelin
<maxime.coquelin@redhat.com> wrote:
>
> This patch adds driver flag in vdev bus driver so that
> vdev drivers can require VA IOVA mode to be used, which
> for example the case of Virtio-user PMD.
>
> The patch implements the .get_iommu_class() callback, that
> is called before devices probing to determine the IOVA mode
> to be used.
>
> It also adds a check right before the device is probed to
> ensure compatible IOVa mode has been selected.
>
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/bus/vdev/rte_bus_vdev.h |  4 ++++
>  drivers/bus/vdev/vdev.c         | 31 +++++++++++++++++++++++++++++++
>  2 files changed, 35 insertions(+)
>
> diff --git a/drivers/bus/vdev/rte_bus_vdev.h b/drivers/bus/vdev/rte_bus_vdev.h
> index f99a41f825..c8b41e649c 100644
> --- a/drivers/bus/vdev/rte_bus_vdev.h
> +++ b/drivers/bus/vdev/rte_bus_vdev.h
> @@ -113,8 +113,12 @@ struct rte_vdev_driver {
>         rte_vdev_remove_t *remove;       /**< Virtual device remove function. */
>         rte_vdev_dma_map_t *dma_map;     /**< Virtual device DMA map function. */
>         rte_vdev_dma_unmap_t *dma_unmap; /**< Virtual device DMA unmap function. */
> +       uint32_t drv_flags;                /**< Flags RTE_VDEV_DRV_*. */

This will probably get broken in the future, but for now, can you
indent the comment in the same way as earlier lines?


The ABI check will complain about this change so we need an exception.

rte_vdev_driver is exposed only through driver API.
We could flag the whole structure like we did for ethdev.
But there is also the alternative of just flagging the required
symbols so that we won't miss later the inclusion of this structure in
an API used by final users.
How about:

diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
index 1dc84fa74b..435913d908 100644
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -11,6 +11,8 @@
 ; Explicit ignore for driver-only ABI
 [suppress_type]
         name = eth_dev_ops
+[suppress_function]
+        name_regexp = rte_vdev_(|un)register

 ; Ignore fields inserted in cacheline boundary of rte_cryptodev
 [suppress_type]


>  };
>
> +/** Device driver needs IOVA as VA and cannot work with IOVA as PA */
> +#define RTE_VDEV_DRV_NEED_IOVA_AS_VA 0x0001
> +
>  /**
>   * Register a virtual device driver.
>   *
> diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
> index acfd78828f..56f15e8201 100644
> --- a/drivers/bus/vdev/vdev.c
> +++ b/drivers/bus/vdev/vdev.c
> @@ -189,6 +189,7 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
>  {
>         const char *name;
>         struct rte_vdev_driver *driver;
> +       enum rte_iova_mode iova_mode;
>         int ret;
>
>         if (rte_dev_is_probed(&dev->device))
> @@ -199,6 +200,14 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
>
>         if (vdev_parse(name, &driver))
>                 return -1;
> +
> +       iova_mode = rte_eal_iova_mode();
> +       if ((driver->drv_flags & RTE_VDEV_DRV_NEED_IOVA_AS_VA) && (iova_mode == RTE_IOVA_PA)) {
> +               VDEV_LOG(ERR, "%s requires VA IOVA mode but current mode is PA, not initializing",
> +                               name);
> +               return -1;
> +       }
> +
>         ret = driver->probe(dev);
>         if (ret == 0)
>                 dev->device.driver = &driver->driver;
> @@ -594,6 +603,27 @@ vdev_unplug(struct rte_device *dev)
>         return rte_vdev_uninit(dev->name);
>  }
>
> +static enum rte_iova_mode
> +vdev_get_iommu_class(void)
> +{
> +       const char *name;
> +       struct rte_vdev_device *dev;
> +       struct rte_vdev_driver *driver;
> +
> +       TAILQ_FOREACH(dev, &vdev_device_list, next) {
> +               name = rte_vdev_device_name(dev);
> +               if (!name)
> +                       continue;

Afaics, a device in vdev_device_list always has a name.


> +               if (vdev_parse(name, &driver))
> +                       continue;
> +
> +               if (driver->drv_flags & RTE_VDEV_DRV_NEED_IOVA_AS_VA)
> +                       return RTE_IOVA_VA;
> +       }
> +
> +       return RTE_IOVA_DC;
> +}
> +
>  static struct rte_bus rte_vdev_bus = {
>         .scan = vdev_scan,
>         .probe = vdev_probe,
> @@ -603,6 +633,7 @@ static struct rte_bus rte_vdev_bus = {
>         .parse = vdev_parse,
>         .dma_map = vdev_dma_map,
>         .dma_unmap = vdev_dma_unmap,
> +       .get_iommu_class = vdev_get_iommu_class,
>         .dev_iterate = rte_vdev_dev_iterate,
>  };
>
> --
> 2.29.2
>


-- 
David Marchand


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 02/44] bus/vdev: add driver IOVA VA mode requirement
  2021-01-20 15:32   ` David Marchand
@ 2021-01-20 17:47     ` Maxime Coquelin
  0 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-20 17:47 UTC (permalink / raw)
  To: David Marchand, Ray Kinsella
  Cc: dev, Xia, Chenbo, Olivier Matz, Adrian Moreno Zapata, Thomas Monjalon



On 1/20/21 4:32 PM, David Marchand wrote:
> On Tue, Jan 19, 2021 at 10:25 PM Maxime Coquelin
> <maxime.coquelin@redhat.com> wrote:
>>
>> This patch adds driver flag in vdev bus driver so that
>> vdev drivers can require VA IOVA mode to be used, which
>> for example the case of Virtio-user PMD.
>>
>> The patch implements the .get_iommu_class() callback, that
>> is called before devices probing to determine the IOVA mode
>> to be used.
>>
>> It also adds a check right before the device is probed to
>> ensure compatible IOVa mode has been selected.
>>
>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>> ---
>>  drivers/bus/vdev/rte_bus_vdev.h |  4 ++++
>>  drivers/bus/vdev/vdev.c         | 31 +++++++++++++++++++++++++++++++
>>  2 files changed, 35 insertions(+)
>>
>> diff --git a/drivers/bus/vdev/rte_bus_vdev.h b/drivers/bus/vdev/rte_bus_vdev.h
>> index f99a41f825..c8b41e649c 100644
>> --- a/drivers/bus/vdev/rte_bus_vdev.h
>> +++ b/drivers/bus/vdev/rte_bus_vdev.h
>> @@ -113,8 +113,12 @@ struct rte_vdev_driver {
>>         rte_vdev_remove_t *remove;       /**< Virtual device remove function. */
>>         rte_vdev_dma_map_t *dma_map;     /**< Virtual device DMA map function. */
>>         rte_vdev_dma_unmap_t *dma_unmap; /**< Virtual device DMA unmap function. */
>> +       uint32_t drv_flags;                /**< Flags RTE_VDEV_DRV_*. */
> 
> This will probably get broken in the future, but for now, can you
> indent the comment in the same way as earlier lines?
> 
> 
> The ABI check will complain about this change so we need an exception.
> 
> rte_vdev_driver is exposed only through driver API.
> We could flag the whole structure like we did for ethdev.
> But there is also the alternative of just flagging the required
> symbols so that we won't miss later the inclusion of this structure in
> an API used by final users.
> How about:
> 
> diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
> index 1dc84fa74b..435913d908 100644
> --- a/devtools/libabigail.abignore
> +++ b/devtools/libabigail.abignore
> @@ -11,6 +11,8 @@
>  ; Explicit ignore for driver-only ABI
>  [suppress_type]
>          name = eth_dev_ops
> +[suppress_function]
> +        name_regexp = rte_vdev_(|un)register
> 
>  ; Ignore fields inserted in cacheline boundary of rte_cryptodev
>  [suppress_type]
> 
> 

This is fine by me.

>>  };
>>
>> +/** Device driver needs IOVA as VA and cannot work with IOVA as PA */
>> +#define RTE_VDEV_DRV_NEED_IOVA_AS_VA 0x0001
>> +
>>  /**
>>   * Register a virtual device driver.
>>   *
>> diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
>> index acfd78828f..56f15e8201 100644
>> --- a/drivers/bus/vdev/vdev.c
>> +++ b/drivers/bus/vdev/vdev.c
>> @@ -189,6 +189,7 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
>>  {
>>         const char *name;
>>         struct rte_vdev_driver *driver;
>> +       enum rte_iova_mode iova_mode;
>>         int ret;
>>
>>         if (rte_dev_is_probed(&dev->device))
>> @@ -199,6 +200,14 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
>>
>>         if (vdev_parse(name, &driver))
>>                 return -1;
>> +
>> +       iova_mode = rte_eal_iova_mode();
>> +       if ((driver->drv_flags & RTE_VDEV_DRV_NEED_IOVA_AS_VA) && (iova_mode == RTE_IOVA_PA)) {
>> +               VDEV_LOG(ERR, "%s requires VA IOVA mode but current mode is PA, not initializing",
>> +                               name);
>> +               return -1;
>> +       }
>> +
>>         ret = driver->probe(dev);
>>         if (ret == 0)
>>                 dev->device.driver = &driver->driver;
>> @@ -594,6 +603,27 @@ vdev_unplug(struct rte_device *dev)
>>         return rte_vdev_uninit(dev->name);
>>  }
>>
>> +static enum rte_iova_mode
>> +vdev_get_iommu_class(void)
>> +{
>> +       const char *name;
>> +       struct rte_vdev_device *dev;
>> +       struct rte_vdev_driver *driver;
>> +
>> +       TAILQ_FOREACH(dev, &vdev_device_list, next) {
>> +               name = rte_vdev_device_name(dev);
>> +               if (!name)
>> +                       continue;
> 
> Afaics, a device in vdev_device_list always has a name.

Indeed, I will remove the check in next revision.

Thanks,
Maxime

> 
>> +               if (vdev_parse(name, &driver))
>> +                       continue;
>> +
>> +               if (driver->drv_flags & RTE_VDEV_DRV_NEED_IOVA_AS_VA)
>> +                       return RTE_IOVA_VA;
>> +       }
>> +
>> +       return RTE_IOVA_DC;
>> +}
>> +
>>  static struct rte_bus rte_vdev_bus = {
>>         .scan = vdev_scan,
>>         .probe = vdev_probe,
>> @@ -603,6 +633,7 @@ static struct rte_bus rte_vdev_bus = {
>>         .parse = vdev_parse,
>>         .dma_map = vdev_dma_map,
>>         .dma_unmap = vdev_dma_unmap,
>> +       .get_iommu_class = vdev_get_iommu_class,
>>         .dev_iterate = rte_vdev_dev_iterate,
>>  };
>>
>> --
>> 2.29.2
>>
> 
> 


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 19/44] net/virtio: move features definition to generic header
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 19/44] net/virtio: move features definition to generic header Maxime Coquelin
@ 2021-01-21  6:47   ` Xia, Chenbo
  2021-01-25 12:35     ` Maxime Coquelin
  0 siblings, 1 reply; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-21  6:47 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

Hi Maxime,

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 19/44] net/virtio: move features definition to generic
> header
> 
> This patch moves all the Virtio definition to the generic
> header. It also renames some helpers to no more reference
> PCI.
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/meson.build                |   3 +-
>  drivers/net/virtio/virtio.c                   |  22 ++++
>  drivers/net/virtio/virtio.h                   |  94 +++++++++++++++
>  drivers/net/virtio/virtio_ethdev.c            | 114 +++++++++---------
>  drivers/net/virtio/virtio_pci.c               |  21 +---
>  drivers/net/virtio/virtio_pci.h               |  90 --------------
>  drivers/net/virtio/virtio_ring.h              |   2 +-
>  drivers/net/virtio/virtio_rxtx.c              |  38 +++---
>  drivers/net/virtio/virtio_rxtx_packed.h       |   6 +-
>  .../net/virtio/virtio_user/vhost_kernel_tap.c |   2 +-
>  drivers/net/virtio/virtio_user_ethdev.c       |   6 +-
>  drivers/net/virtio/virtqueue.c                |   4 +-
>  drivers/net/virtio/virtqueue.h                |   8 +-
>  13 files changed, 211 insertions(+), 199 deletions(-)
>  create mode 100644 drivers/net/virtio/virtio.c
> 
> diff --git a/drivers/net/virtio/meson.build b/drivers/net/virtio/meson.build
> index f2873d6180..d595cfdcab 100644
> --- a/drivers/net/virtio/meson.build
> +++ b/drivers/net/virtio/meson.build

<snip>

> 
> -	if (vtpci_with_feature(hw, VIRTIO_F_RING_PACKED)) {
> +	if (virtio_with_feature(hw, VIRTIO_F_RING_PACKED)) {

As discussed before, let's also replace here with virtio_with_packed_queue 😊

Thanks
Chenbo

>  		/*
>  		 * Bit[0:15]: vq queue index
>  		 * Bit[16:30]: avail index
> @@ -618,21 +618,6 @@ vtpci_write_dev_config(struct virtio_hw *hw, size_t
> offset,
>  	VIRTIO_OPS(hw)->write_dev_cfg(hw, offset, src, length);
>  }
> 
> -uint64_t
> -vtpci_negotiate_features(struct virtio_hw *hw, uint64_t host_features)
> -{
> -	uint64_t features;
> -
> -	/*
> -	 * Limit negotiated features to what the driver, virtqueue, and
> -	 * host all support.
> -	 */
> -	features = host_features & hw->guest_features;
> -	VIRTIO_OPS(hw)->set_features(hw, features);
> -
> -	return features;
> -}
> -
>  void
>  vtpci_reset(struct virtio_hw *hw)
>  {
> diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
> index f7f51fba79..3d93e74f36 100644
> --- a/drivers/net/virtio/virtio_pci.h
> +++ b/drivers/net/virtio/virtio_pci.h
> @@ -79,83 +79,6 @@ struct virtnet_ctl;
>   */
>  #define VIRTIO_MAX_INDIRECT ((int) (PAGE_SIZE / 16))
> 
> -/* The feature bitmap for virtio net */
> -#define VIRTIO_NET_F_CSUM	0	/* Host handles pkts w/ partial csum */
> -#define VIRTIO_NET_F_GUEST_CSUM	1	/* Guest handles pkts w/ partial
> csum */
> -#define VIRTIO_NET_F_MTU	3	/* Initial MTU advice. */
> -#define VIRTIO_NET_F_MAC	5	/* Host has given MAC address. */
> -#define VIRTIO_NET_F_GUEST_TSO4	7	/* Guest can handle TSOv4 in. */
> -#define VIRTIO_NET_F_GUEST_TSO6	8	/* Guest can handle TSOv6 in. */
> -#define VIRTIO_NET_F_GUEST_ECN	9	/* Guest can handle TSO[6] w/ ECN in.
> */
> -#define VIRTIO_NET_F_GUEST_UFO	10	/* Guest can handle UFO in. */
> -#define VIRTIO_NET_F_HOST_TSO4	11	/* Host can handle TSOv4 in. */
> -#define VIRTIO_NET_F_HOST_TSO6	12	/* Host can handle TSOv6 in. */
> -#define VIRTIO_NET_F_HOST_ECN	13	/* Host can handle TSO[6] w/ ECN in.
> */
> -#define VIRTIO_NET_F_HOST_UFO	14	/* Host can handle UFO in. */
> -#define VIRTIO_NET_F_MRG_RXBUF	15	/* Host can merge receive buffers.
> */
> -#define VIRTIO_NET_F_STATUS	16	/* virtio_net_config.status available */
> -#define VIRTIO_NET_F_CTRL_VQ	17	/* Control channel available */
> -#define VIRTIO_NET_F_CTRL_RX	18	/* Control channel RX mode support */
> -#define VIRTIO_NET_F_CTRL_VLAN	19	/* Control channel VLAN filtering */
> -#define VIRTIO_NET_F_CTRL_RX_EXTRA 20	/* Extra RX mode control support */
> -#define VIRTIO_NET_F_GUEST_ANNOUNCE 21	/* Guest can announce device on the
> -					 * network */
> -#define VIRTIO_NET_F_MQ		22	/* Device supports Receive Flow
> -					 * Steering */
> -#define VIRTIO_NET_F_CTRL_MAC_ADDR 23	/* Set MAC address */
> -
> -/* Do we get callbacks when the ring is completely used, even if we've
> - * suppressed them? */
> -#define VIRTIO_F_NOTIFY_ON_EMPTY	24
> -
> -/* Can the device handle any descriptor layout? */
> -#define VIRTIO_F_ANY_LAYOUT		27
> -
> -/* We support indirect buffer descriptors */
> -#define VIRTIO_RING_F_INDIRECT_DESC	28
> -
> -#define VIRTIO_F_VERSION_1		32
> -#define VIRTIO_F_IOMMU_PLATFORM	33
> -#define VIRTIO_F_RING_PACKED		34
> -
> -/*
> - * Some VirtIO feature bits (currently bits 28 through 31) are
> - * reserved for the transport being used (eg. virtio_ring), the
> - * rest are per-device feature bits.
> - */
> -#define VIRTIO_TRANSPORT_F_START 28
> -#define VIRTIO_TRANSPORT_F_END   34
> -
> -/*
> - * Inorder feature indicates that all buffers are used by the device
> - * in the same order in which they have been made available.
> - */
> -#define VIRTIO_F_IN_ORDER 35
> -
> -/*
> - * This feature indicates that memory accesses by the driver and the device
> - * are ordered in a way described by the platform.
> - */
> -#define VIRTIO_F_ORDER_PLATFORM 36
> -
> -/*
> - * This feature indicates that the driver passes extra data (besides
> - * identifying the virtqueue) in its device notifications.
> - */
> -#define VIRTIO_F_NOTIFICATION_DATA 38
> -
> -/* Device set linkspeed and duplex */
> -#define VIRTIO_NET_F_SPEED_DUPLEX 63
> -
> -/* The Guest publishes the used index for which it expects an interrupt
> - * at the end of the avail ring. Host should ignore the avail->flags field.
> */
> -/* The Host publishes the avail index for which it expects a kick
> - * at the end of the used ring. Guest should ignore the used->flags field. */
> -#define VIRTIO_RING_F_EVENT_IDX		29
> -
> -#define VIRTIO_NET_S_LINK_UP	1	/* Link is up */
> -#define VIRTIO_NET_S_ANNOUNCE	2	/* Announcement is needed */
> -
>  /*
>   * Maximum number of virtqueues per device.
>   */
> @@ -270,17 +193,6 @@ enum virtio_msix_status {
>  	VIRTIO_MSIX_ENABLED = 2
>  };
> 
> -static inline int
> -vtpci_with_feature(struct virtio_hw *hw, uint64_t bit)
> -{
> -	return (hw->guest_features & (1ULL << bit)) != 0;
> -}
> -
> -static inline int
> -vtpci_packed_queue(struct virtio_hw *hw)
> -{
> -	return vtpci_with_feature(hw, VIRTIO_F_RING_PACKED);
> -}
> 
>  /*
>   * Function declaration from virtio_pci.c
> @@ -293,8 +205,6 @@ void vtpci_reinit_complete(struct virtio_hw *);
>  uint8_t vtpci_get_status(struct virtio_hw *);
>  void vtpci_set_status(struct virtio_hw *, uint8_t);
> 
> -uint64_t vtpci_negotiate_features(struct virtio_hw *, uint64_t);
> -
>  void vtpci_write_dev_config(struct virtio_hw *, size_t, const void *, int);
> 
>  void vtpci_read_dev_config(struct virtio_hw *, size_t, void *, int);
> diff --git a/drivers/net/virtio/virtio_ring.h
> b/drivers/net/virtio/virtio_ring.h
> index 0f6574f684..17a56b0a73 100644
> --- a/drivers/net/virtio/virtio_ring.h
> +++ b/drivers/net/virtio/virtio_ring.h
> @@ -133,7 +133,7 @@ vring_size(struct virtio_hw *hw, unsigned int num,
> unsigned long align)
>  {
>  	size_t size;
> 
> -	if (vtpci_packed_queue(hw)) {
> +	if (virtio_with_packed_queue(hw)) {
>  		size = num * sizeof(struct vring_packed_desc);
>  		size += sizeof(struct vring_packed_desc_event);
>  		size = RTE_ALIGN_CEIL(size, align);
> diff --git a/drivers/net/virtio/virtio_rxtx.c
> b/drivers/net/virtio/virtio_rxtx.c
> index 6875c8fbee..728085e99b 100644
> --- a/drivers/net/virtio/virtio_rxtx.c
> +++ b/drivers/net/virtio/virtio_rxtx.c
> @@ -685,14 +685,14 @@ virtio_dev_rx_queue_setup_finish(struct rte_eth_dev *dev,
> uint16_t queue_idx)
>  	struct rte_mbuf *m;
>  	uint16_t desc_idx;
>  	int error, nbufs, i;
> -	bool in_order = vtpci_with_feature(hw, VIRTIO_F_IN_ORDER);
> +	bool in_order = virtio_with_feature(hw, VIRTIO_F_IN_ORDER);
> 
>  	PMD_INIT_FUNC_TRACE();
> 
>  	/* Allocate blank mbufs for the each rx descriptor */
>  	nbufs = 0;
> 
> -	if (hw->use_vec_rx && !vtpci_packed_queue(hw)) {
> +	if (hw->use_vec_rx && !virtio_with_packed_queue(hw)) {
>  		for (desc_idx = 0; desc_idx < vq->vq_nentries;
>  		     desc_idx++) {
>  			vq->vq_split.ring.avail->ring[desc_idx] = desc_idx;
> @@ -710,12 +710,12 @@ virtio_dev_rx_queue_setup_finish(struct rte_eth_dev *dev,
> uint16_t queue_idx)
>  			&rxvq->fake_mbuf;
>  	}
> 
> -	if (hw->use_vec_rx && !vtpci_packed_queue(hw)) {
> +	if (hw->use_vec_rx && !virtio_with_packed_queue(hw)) {
>  		while (vq->vq_free_cnt >= RTE_VIRTIO_VPMD_RX_REARM_THRESH) {
>  			virtio_rxq_rearm_vec(rxvq);
>  			nbufs += RTE_VIRTIO_VPMD_RX_REARM_THRESH;
>  		}
> -	} else if (!vtpci_packed_queue(vq->hw) && in_order) {
> +	} else if (!virtio_with_packed_queue(vq->hw) && in_order) {
>  		if ((!virtqueue_full(vq))) {
>  			uint16_t free_cnt = vq->vq_free_cnt;
>  			struct rte_mbuf *pkts[free_cnt];
> @@ -741,7 +741,7 @@ virtio_dev_rx_queue_setup_finish(struct rte_eth_dev *dev,
> uint16_t queue_idx)
>  				break;
> 
>  			/* Enqueue allocated buffers */
> -			if (vtpci_packed_queue(vq->hw))
> +			if (virtio_with_packed_queue(vq->hw))
>  				error = virtqueue_enqueue_recv_refill_packed(vq,
>  						&m, 1);
>  			else
> @@ -754,7 +754,7 @@ virtio_dev_rx_queue_setup_finish(struct rte_eth_dev *dev,
> uint16_t queue_idx)
>  			nbufs++;
>  		}
> 
> -		if (!vtpci_packed_queue(vq->hw))
> +		if (!virtio_with_packed_queue(vq->hw))
>  			vq_update_avail_idx(vq);
>  	}
> 
> @@ -829,8 +829,8 @@ virtio_dev_tx_queue_setup_finish(struct rte_eth_dev *dev,
> 
>  	PMD_INIT_FUNC_TRACE();
> 
> -	if (!vtpci_packed_queue(hw)) {
> -		if (vtpci_with_feature(hw, VIRTIO_F_IN_ORDER))
> +	if (!virtio_with_packed_queue(hw)) {
> +		if (virtio_with_feature(hw, VIRTIO_F_IN_ORDER))
>  			vq->vq_split.ring.desc[vq->vq_nentries - 1].next = 0;
>  	}
> 
> @@ -847,7 +847,7 @@ virtio_discard_rxbuf(struct virtqueue *vq, struct rte_mbuf
> *m)
>  	 * Requeue the discarded mbuf. This should always be
>  	 * successful since it was just dequeued.
>  	 */
> -	if (vtpci_packed_queue(vq->hw))
> +	if (virtio_with_packed_queue(vq->hw))
>  		error = virtqueue_enqueue_recv_refill_packed(vq, &m, 1);
>  	else
>  		error = virtqueue_enqueue_recv_refill(vq, &m, 1);
> @@ -1209,7 +1209,7 @@ virtio_recv_pkts_inorder(void *rx_queue,
>  			 ((char *)rxm->buf_addr + RTE_PKTMBUF_HEADROOM
>  			 - hdr_size);
> 
> -		if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
> +		if (virtio_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
>  			seg_num = header->num_buffers;
>  			if (seg_num == 0)
>  				seg_num = 1;
> @@ -1735,7 +1735,7 @@ virtio_xmit_pkts_packed(void *tx_queue, struct rte_mbuf
> **tx_pkts,
>  	struct virtio_hw *hw = vq->hw;
>  	uint16_t hdr_size = hw->vtnet_hdr_size;
>  	uint16_t nb_tx = 0;
> -	bool in_order = vtpci_with_feature(hw, VIRTIO_F_IN_ORDER);
> +	bool in_order = virtio_with_feature(hw, VIRTIO_F_IN_ORDER);
> 
>  	if (unlikely(hw->started == 0 && tx_pkts != hw->inject_pkts))
>  		return nb_tx;
> @@ -1754,8 +1754,8 @@ virtio_xmit_pkts_packed(void *tx_queue, struct rte_mbuf
> **tx_pkts,
>  		int can_push = 0, use_indirect = 0, slots, need;
> 
>  		/* optimize ring usage */
> -		if ((vtpci_with_feature(hw, VIRTIO_F_ANY_LAYOUT) ||
> -		      vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) &&
> +		if ((virtio_with_feature(hw, VIRTIO_F_ANY_LAYOUT) ||
> +		      virtio_with_feature(hw, VIRTIO_F_VERSION_1)) &&
>  		    rte_mbuf_refcnt_read(txm) == 1 &&
>  		    RTE_MBUF_DIRECT(txm) &&
>  		    txm->nb_segs == 1 &&
> @@ -1763,7 +1763,7 @@ virtio_xmit_pkts_packed(void *tx_queue, struct rte_mbuf
> **tx_pkts,
>  		    rte_is_aligned(rte_pktmbuf_mtod(txm, char *),
>  			   __alignof__(struct virtio_net_hdr_mrg_rxbuf)))
>  			can_push = 1;
> -		else if (vtpci_with_feature(hw, VIRTIO_RING_F_INDIRECT_DESC) &&
> +		else if (virtio_with_feature(hw, VIRTIO_RING_F_INDIRECT_DESC) &&
>  			 txm->nb_segs < VIRTIO_MAX_TX_INDIRECT)
>  			use_indirect = 1;
>  		/* How many main ring entries are needed to this Tx?
> @@ -1835,8 +1835,8 @@ virtio_xmit_pkts(void *tx_queue, struct rte_mbuf
> **tx_pkts, uint16_t nb_pkts)
>  		int can_push = 0, use_indirect = 0, slots, need;
> 
>  		/* optimize ring usage */
> -		if ((vtpci_with_feature(hw, VIRTIO_F_ANY_LAYOUT) ||
> -		      vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) &&
> +		if ((virtio_with_feature(hw, VIRTIO_F_ANY_LAYOUT) ||
> +		      virtio_with_feature(hw, VIRTIO_F_VERSION_1)) &&
>  		    rte_mbuf_refcnt_read(txm) == 1 &&
>  		    RTE_MBUF_DIRECT(txm) &&
>  		    txm->nb_segs == 1 &&
> @@ -1844,7 +1844,7 @@ virtio_xmit_pkts(void *tx_queue, struct rte_mbuf
> **tx_pkts, uint16_t nb_pkts)
>  		    rte_is_aligned(rte_pktmbuf_mtod(txm, char *),
>  				   __alignof__(struct virtio_net_hdr_mrg_rxbuf)))
>  			can_push = 1;
> -		else if (vtpci_with_feature(hw, VIRTIO_RING_F_INDIRECT_DESC) &&
> +		else if (virtio_with_feature(hw, VIRTIO_RING_F_INDIRECT_DESC) &&
>  			 txm->nb_segs < VIRTIO_MAX_TX_INDIRECT)
>  			use_indirect = 1;
> 
> @@ -1937,8 +1937,8 @@ virtio_xmit_pkts_inorder(void *tx_queue,
>  		int slots;
> 
>  		/* optimize ring usage */
> -		if ((vtpci_with_feature(hw, VIRTIO_F_ANY_LAYOUT) ||
> -		     vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) &&
> +		if ((virtio_with_feature(hw, VIRTIO_F_ANY_LAYOUT) ||
> +		     virtio_with_feature(hw, VIRTIO_F_VERSION_1)) &&
>  		     rte_mbuf_refcnt_read(txm) == 1 &&
>  		     RTE_MBUF_DIRECT(txm) &&
>  		     txm->nb_segs == 1 &&
> diff --git a/drivers/net/virtio/virtio_rxtx_packed.h
> b/drivers/net/virtio/virtio_rxtx_packed.h
> index c0fad41c3d..8d99caeead 100644
> --- a/drivers/net/virtio/virtio_rxtx_packed.h
> +++ b/drivers/net/virtio/virtio_rxtx_packed.h
> @@ -111,12 +111,12 @@ virtqueue_enqueue_single_packed_vec(struct virtnet_tx
> *txvq,
>  	int16_t need;
> 
>  	/* optimize ring usage */
> -	if ((vtpci_with_feature(hw, VIRTIO_F_ANY_LAYOUT) ||
> -	     vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) &&
> +	if ((virtio_with_feature(hw, VIRTIO_F_ANY_LAYOUT) ||
> +	     virtio_with_feature(hw, VIRTIO_F_VERSION_1)) &&
>  	     rte_mbuf_refcnt_read(txm) == 1 && RTE_MBUF_DIRECT(txm) &&
>  	     txm->nb_segs == 1 && rte_pktmbuf_headroom(txm) >= hdr_size)
>  		can_push = 1;
> -	else if (vtpci_with_feature(hw, VIRTIO_RING_F_INDIRECT_DESC) &&
> +	else if (virtio_with_feature(hw, VIRTIO_RING_F_INDIRECT_DESC) &&
>  		 txm->nb_segs < VIRTIO_MAX_TX_INDIRECT)
>  		use_indirect = 1;
> 
> diff --git a/drivers/net/virtio/virtio_user/vhost_kernel_tap.c
> b/drivers/net/virtio/virtio_user/vhost_kernel_tap.c
> index 79b8446f8e..eade702c5c 100644
> --- a/drivers/net/virtio/virtio_user/vhost_kernel_tap.c
> +++ b/drivers/net/virtio/virtio_user/vhost_kernel_tap.c
> @@ -16,7 +16,7 @@
> 
>  #include "vhost_kernel_tap.h"
>  #include "../virtio_logs.h"
> -#include "../virtio_pci.h"
> +#include "../virtio.h"
> 
>  int
>  vhost_kernel_tap_set_offload(int fd, uint64_t features)
> diff --git a/drivers/net/virtio/virtio_user_ethdev.c
> b/drivers/net/virtio/virtio_user_ethdev.c
> index 6597c16539..8e609333c6 100644
> --- a/drivers/net/virtio/virtio_user_ethdev.c
> +++ b/drivers/net/virtio/virtio_user_ethdev.c
> @@ -122,7 +122,7 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev)
>  	dev->features &= dev->device_features;
> 
>  	/* For packed ring, resetting queues is required in reconnection. */
> -	if (vtpci_packed_queue(hw) &&
> +	if (virtio_with_packed_queue(hw) &&
>  	   (old_status & VIRTIO_CONFIG_STATUS_DRIVER_OK)) {
>  		PMD_INIT_LOG(NOTICE, "Packets on the fly will be dropped"
>  				" when packed ring reconnecting.");
> @@ -423,7 +423,7 @@ virtio_user_setup_queue(struct virtio_hw *hw, struct
> virtqueue *vq)
>  {
>  	struct virtio_user_dev *dev = virtio_user_get_dev(hw);
> 
> -	if (vtpci_packed_queue(hw))
> +	if (virtio_with_packed_queue(hw))
>  		virtio_user_setup_queue_packed(vq, dev);
>  	else
>  		virtio_user_setup_queue_split(vq, dev);
> @@ -456,7 +456,7 @@ virtio_user_notify_queue(struct virtio_hw *hw, struct
> virtqueue *vq)
>  	struct virtio_user_dev *dev = virtio_user_get_dev(hw);
> 
>  	if (hw->cvq && (hw->cvq->vq == vq)) {
> -		if (vtpci_packed_queue(vq->hw))
> +		if (virtio_with_packed_queue(vq->hw))
>  			virtio_user_handle_cq_packed(dev, vq->vq_queue_index);
>  		else
>  			virtio_user_handle_cq(dev, vq->vq_queue_index);
> diff --git a/drivers/net/virtio/virtqueue.c b/drivers/net/virtio/virtqueue.c
> index 2702e120ee..59a2cb6599 100644
> --- a/drivers/net/virtio/virtqueue.c
> +++ b/drivers/net/virtio/virtqueue.c
> @@ -32,7 +32,7 @@ virtqueue_detach_unused(struct virtqueue *vq)
>  	end = (vq->vq_avail_idx + vq->vq_free_cnt) & (vq->vq_nentries - 1);
> 
>  	for (idx = 0; idx < vq->vq_nentries; idx++) {
> -		if (hw->use_vec_rx && !vtpci_packed_queue(hw) &&
> +		if (hw->use_vec_rx && !virtio_with_packed_queue(hw) &&
>  		    type == VTNET_RQ) {
>  			if (start <= end && idx >= start && idx < end)
>  				continue;
> @@ -137,7 +137,7 @@ virtqueue_rxvq_flush(struct virtqueue *vq)
>  {
>  	struct virtio_hw *hw = vq->hw;
> 
> -	if (vtpci_packed_queue(hw))
> +	if (virtio_with_packed_queue(hw))
>  		virtqueue_rxvq_flush_packed(vq);
>  	else
>  		virtqueue_rxvq_flush_split(vq);
> diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
> index 6293cd2604..f419c0aa99 100644
> --- a/drivers/net/virtio/virtqueue.h
> +++ b/drivers/net/virtio/virtqueue.h
> @@ -12,7 +12,7 @@
>  #include <rte_mempool.h>
>  #include <rte_net.h>
> 
> -#include "virtio_pci.h"
> +#include "virtio.h"
>  #include "virtio_ring.h"
>  #include "virtio_logs.h"
>  #include "virtio_rxtx.h"
> @@ -385,7 +385,7 @@ virtqueue_disable_intr_split(struct virtqueue *vq)
>  static inline void
>  virtqueue_disable_intr(struct virtqueue *vq)
>  {
> -	if (vtpci_packed_queue(vq->hw))
> +	if (virtio_with_packed_queue(vq->hw))
>  		virtqueue_disable_intr_packed(vq);
>  	else
>  		virtqueue_disable_intr_split(vq);
> @@ -419,7 +419,7 @@ virtqueue_enable_intr_split(struct virtqueue *vq)
>  static inline void
>  virtqueue_enable_intr(struct virtqueue *vq)
>  {
> -	if (vtpci_packed_queue(vq->hw))
> +	if (virtio_with_packed_queue(vq->hw))
>  		virtqueue_enable_intr_packed(vq);
>  	else
>  		virtqueue_enable_intr_split(vq);
> @@ -572,7 +572,7 @@ virtqueue_notify(struct virtqueue *vq)
>  	used_idx = __atomic_load_n(&(vq)->vq_split.ring.used->idx, \
>  				   __ATOMIC_RELAXED); \
>  	nused = (uint16_t)(used_idx - (vq)->vq_used_cons_idx); \
> -	if (vtpci_packed_queue((vq)->hw)) { \
> +	if (virtio_with_packed_queue((vq)->hw)) { \
>  		PMD_INIT_LOG(DEBUG, \
>  		"VQ: - size=%d; free=%d; used_cons_idx=%d; avail_idx=%d;" \
>  		" cached_flags=0x%x; used_wrap_counter=%d", \
> --
> 2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 09/44] net/virtio: move MSIX detection to PCI ethdev
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 09/44] net/virtio: move MSIX detection to PCI ethdev Maxime Coquelin
@ 2021-01-21  7:12   ` Xia, Chenbo
  2021-01-25 12:41     ` Maxime Coquelin
  0 siblings, 1 reply; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-21  7:12 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

Hi Maxime,

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 09/44] net/virtio: move MSIX detection to PCI ethdev
> 
> This patch introduces a new callback to notify the bus
> driver some interrupt related operation was done.
> 
> This is used by Virtio PCI driver to check msix status.
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_ethdev.c     |  12 +--
>  drivers/net/virtio/virtio_pci.c        | 120 ++++++++++++++-----------
>  drivers/net/virtio/virtio_pci.h        |   6 +-
>  drivers/net/virtio/virtio_pci_ethdev.c |   2 +
>  4 files changed, 82 insertions(+), 58 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_ethdev.c
> b/drivers/net/virtio/virtio_ethdev.c
> index a3e81f336d..13d5a76376 100644
> --- a/drivers/net/virtio/virtio_ethdev.c
> +++ b/drivers/net/virtio/virtio_ethdev.c
> @@ -1287,8 +1287,8 @@ virtio_intr_unmask(struct rte_eth_dev *dev)
>  	if (rte_intr_ack(dev->intr_handle) < 0)
>  		return -1;
> 
> -	if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY || hw->bus_type ==
> VIRTIO_BUS_PCI_MODERN)
> -		hw->use_msix = vtpci_msix_detect(RTE_ETH_DEV_TO_PCI(dev));
> +	if (VTPCI_OPS(hw)->intr_event)

Emmm.. why is callback called intr_event? The callback detects/checks msix and lsc.
IMHO, maybe intr_detect? Or another similar verb you like 😊

> +		VTPCI_OPS(hw)->intr_event(hw);
> 
>  	return 0;

<snip>

> 
> +msix_detect:
> +	hw->use_msix = vtpci_msix_detect(dev);
> +

Just use use the callback introduced? Should also work later when intr_lsc is added.

Thanks,
Chenbo

>  	return 0;
>  }
> 
> -enum virtio_msix_status
> -vtpci_msix_detect(struct rte_pci_device *dev)
> -{
> -	uint8_t pos;
> -	int ret;
> -
> -	ret = rte_pci_read_config(dev, &pos, 1, PCI_CAPABILITY_LIST);
> -	if (ret != 1) {
> -		PMD_INIT_LOG(DEBUG,
> -			     "failed to read pci capability list, ret %d", ret);
> -		return VIRTIO_MSIX_NONE;
> -	}
> -
> -	while (pos) {
> -		uint8_t cap[2];
> -
> -		ret = rte_pci_read_config(dev, cap, sizeof(cap), pos);
> -		if (ret != sizeof(cap)) {
> -			PMD_INIT_LOG(DEBUG,
> -				     "failed to read pci cap at pos: %x ret %d",
> -				     pos, ret);
> -			break;
> -		}
> -
> -		if (cap[0] == PCI_CAP_ID_MSIX) {
> -			uint16_t flags;
> -
> -			ret = rte_pci_read_config(dev, &flags, sizeof(flags),
> -					pos + sizeof(cap));
> -			if (ret != sizeof(flags)) {
> -				PMD_INIT_LOG(DEBUG,
> -					     "failed to read pci cap at pos:"
> -					     " %x ret %d", pos + 2, ret);
> -				break;
> -			}
> -
> -			if (flags & PCI_MSIX_ENABLE)
> -				return VIRTIO_MSIX_ENABLED;
> -			else
> -				return VIRTIO_MSIX_DISABLED;
> -		}
> -
> -		pos = cap[1];
> -	}
> -
> -	return VIRTIO_MSIX_NONE;
> -}
> diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
> index 59f6688218..6f5c53c4b7 100644
> --- a/drivers/net/virtio/virtio_pci.h
> +++ b/drivers/net/virtio/virtio_pci.h
> @@ -239,6 +239,7 @@ struct virtio_pci_ops {
>  	int (*setup_queue)(struct virtio_hw *hw, struct virtqueue *vq);
>  	void (*del_queue)(struct virtio_hw *hw, struct virtqueue *vq);
>  	void (*notify_queue)(struct virtio_hw *hw, struct virtqueue *vq);
> +	void (*intr_event)(struct virtio_hw *hw);
>  };
> 
>  struct virtio_net_config;
> @@ -303,10 +304,13 @@ struct virtio_pci_dev {
>  struct virtio_hw_internal {
>  	const struct virtio_pci_ops *vtpci_ops;
>  	struct rte_pci_ioport io;
> +	struct rte_pci_device *dev;
>  };
> 
>  #define VTPCI_OPS(hw)	(virtio_hw_internal[(hw)->port_id].vtpci_ops)
>  #define VTPCI_IO(hw)	(&virtio_hw_internal[(hw)->port_id].io)
> +#define VTPCI_DEV(hw)	(virtio_hw_internal[(hw)->port_id].dev)
> +
> 
>  extern struct virtio_hw_internal virtio_hw_internal[RTE_MAX_ETHPORTS];
> 
> @@ -383,8 +387,6 @@ void vtpci_read_dev_config(struct virtio_hw *, size_t,
> void *, int);
> 
>  uint8_t vtpci_isr(struct virtio_hw *);
> 
> -enum virtio_msix_status vtpci_msix_detect(struct rte_pci_device *dev);
> -
>  extern const struct virtio_pci_ops legacy_ops;
>  extern const struct virtio_pci_ops modern_ops;
>  extern const struct virtio_pci_ops virtio_user_ops;
> diff --git a/drivers/net/virtio/virtio_pci_ethdev.c
> b/drivers/net/virtio/virtio_pci_ethdev.c
> index 6a0ef6edc3..045b134ef2 100644
> --- a/drivers/net/virtio/virtio_pci_ethdev.c
> +++ b/drivers/net/virtio/virtio_pci_ethdev.c
> @@ -73,6 +73,8 @@ eth_virtio_pci_init(struct rte_eth_dev *eth_dev)
>  	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
>  	int ret;
> 
> +	VTPCI_DEV(hw) = pci_dev;
> +
>  	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
>  		ret = vtpci_init(RTE_ETH_DEV_TO_PCI(eth_dev), hw);
>  		if (ret) {
> --
> 2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 03/44] net/virtio: fix getting old status on reconnect
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 03/44] net/virtio: fix getting old status on reconnect Maxime Coquelin
@ 2021-01-21  7:12   ` Xia, Chenbo
  0 siblings, 0 replies; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-21  7:12 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand; +Cc: stable

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:24 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>; stable@dpdk.org
> Subject: [PATCH v2 03/44] net/virtio: fix getting old status on reconnect
> 
> This patch fixes getting reset status from the restarted
> vhost-user backend in case of reconnection, instead of the
> status at the time of the disconnection.
> 
> This issue was not spotted earlier because Vhost-user
> protocol status feature was disabled in server mode.
> 
> Fixes: 47235f16505f ("net/virtio-user: set status on socket reconnect")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user_ethdev.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/virtio/virtio_user_ethdev.c
> b/drivers/net/virtio/virtio_user_ethdev.c
> index 241808cd8f..7abba1f1ee 100644
> --- a/drivers/net/virtio/virtio_user_ethdev.c
> +++ b/drivers/net/virtio/virtio_user_ethdev.c
> @@ -77,7 +77,7 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev)
>  		return -1;
> 
>  	dev->vhostfd = connectfd;
> -	old_status = vtpci_get_status(hw);
> +	old_status = dev->status;
> 
>  	vtpci_reset(hw);
> 
> --
> 2.29.2

Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 25/44] net/virtio: make Vhost-user req sender consistent
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 25/44] net/virtio: make Vhost-user req sender consistent Maxime Coquelin
@ 2021-01-21  8:50   ` Xia, Chenbo
  0 siblings, 0 replies; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-21  8:50 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 25/44] net/virtio: make Vhost-user req sender consistent
> 
> This patch makes vhost_user_write() consistent with
> vhost_user_read(), by passing a Vhost-user message
> pointer instead of a buffer pointer and its length, which
> is now calculated in the function.
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user/vhost_user.c | 10 ++++------
>  1 file changed, 4 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/vhost_user.c
> b/drivers/net/virtio/virtio_user/vhost_user.c
> index 350eed4182..55c813333a 100644
> --- a/drivers/net/virtio/virtio_user/vhost_user.c
> +++ b/drivers/net/virtio/virtio_user/vhost_user.c
> @@ -51,7 +51,7 @@ struct vhost_user_msg {
>  	(sizeof(struct vhost_user_msg) - VHOST_USER_HDR_SIZE)
> 
>  static int
> -vhost_user_write(int fd, void *buf, int len, int *fds, int fd_num)
> +vhost_user_write(int fd, struct vhost_user_msg *msg, int *fds, int fd_num)
>  {
>  	int r;
>  	struct msghdr msgh;
> @@ -63,8 +63,8 @@ vhost_user_write(int fd, void *buf, int len, int *fds, int
> fd_num)
>  	memset(&msgh, 0, sizeof(msgh));
>  	memset(control, 0, sizeof(control));
> 
> -	iov.iov_base = (uint8_t *)buf;
> -	iov.iov_len = len;
> +	iov.iov_base = (uint8_t *)msg;
> +	iov.iov_len = VHOST_USER_HDR_SIZE + msg->size;
> 
>  	msgh.msg_iov = &iov;
>  	msgh.msg_iovlen = 1;
> @@ -259,7 +259,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
>  	int has_reply_ack = 0;
>  	int fds[VHOST_MEMORY_MAX_NREGIONS];
>  	int fd_num = 0;
> -	int len;
>  	int vhostfd = dev->vhostfd;
> 
>  	RTE_SET_USED(m);
> @@ -364,8 +363,7 @@ vhost_user_sock(struct virtio_user_dev *dev,
>  		return -1;
>  	}
> 
> -	len = VHOST_USER_HDR_SIZE + msg.size;
> -	if (vhost_user_write(vhostfd, &msg, len, fds, fd_num) < 0) {
> +	if (vhost_user_write(vhostfd, &msg, fds, fd_num) < 0) {
>  		PMD_DRV_LOG(ERR, "%s failed: %s",
>  			    vhost_msg_strings[req], strerror(errno));
>  		return -1;
> --
> 2.29.2

Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 36/44] net/virtio: move Vhost-user reqs to Vhost-user backend
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 36/44] net/virtio: move Vhost-user reqs to Vhost-user backend Maxime Coquelin
@ 2021-01-21  8:56   ` Xia, Chenbo
  2021-01-25 14:50     ` Maxime Coquelin
  0 siblings, 1 reply; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-21  8:56 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

Hi Maxime,

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 36/44] net/virtio: move Vhost-user reqs to Vhost-user

Better use full name 'requests' if the title's not too long?

Same thing could be done for 'net/virtio: make Vhost-user req sender consistent'

With this fixed:

Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>

> backend
> 
> Now that we have a proper isolation of the backends,
> we can move Vhost-user requests declaration to the
> Vhost-user backend file.
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user/vhost.h      | 25 ---------------------
>  drivers/net/virtio/virtio_user/vhost_user.c | 25 +++++++++++++++++++++
>  2 files changed, 25 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/vhost.h
> b/drivers/net/virtio/virtio_user/vhost.h
> index 6294b8afee..2aa6b2cb70 100644
> --- a/drivers/net/virtio/virtio_user/vhost.h
> +++ b/drivers/net/virtio/virtio_user/vhost.h
> @@ -63,31 +63,6 @@ struct vhost_vring_addr {
>  #define VHOST_USER_PROTOCOL_F_STATUS 16
>  #endif
> 
> -enum vhost_user_request {
> -	VHOST_USER_NONE = 0,
> -	VHOST_USER_GET_FEATURES = 1,
> -	VHOST_USER_SET_FEATURES = 2,
> -	VHOST_USER_SET_OWNER = 3,
> -	VHOST_USER_RESET_OWNER = 4,
> -	VHOST_USER_SET_MEM_TABLE = 5,
> -	VHOST_USER_SET_LOG_BASE = 6,
> -	VHOST_USER_SET_LOG_FD = 7,
> -	VHOST_USER_SET_VRING_NUM = 8,
> -	VHOST_USER_SET_VRING_ADDR = 9,
> -	VHOST_USER_SET_VRING_BASE = 10,
> -	VHOST_USER_GET_VRING_BASE = 11,
> -	VHOST_USER_SET_VRING_KICK = 12,
> -	VHOST_USER_SET_VRING_CALL = 13,
> -	VHOST_USER_SET_VRING_ERR = 14,
> -	VHOST_USER_GET_PROTOCOL_FEATURES = 15,
> -	VHOST_USER_SET_PROTOCOL_FEATURES = 16,
> -	VHOST_USER_GET_QUEUE_NUM = 17,
> -	VHOST_USER_SET_VRING_ENABLE = 18,
> -	VHOST_USER_SET_STATUS = 39,
> -	VHOST_USER_GET_STATUS = 40,
> -	VHOST_USER_MAX
> -};
> -
>  #ifndef VHOST_BACKEND_F_IOTLB_MSG_V2
>  #define VHOST_BACKEND_F_IOTLB_MSG_V2 1
>  #endif
> diff --git a/drivers/net/virtio/virtio_user/vhost_user.c
> b/drivers/net/virtio/virtio_user/vhost_user.c
> index d46e25b64b..fb6fcc82c9 100644
> --- a/drivers/net/virtio/virtio_user/vhost_user.c
> +++ b/drivers/net/virtio/virtio_user/vhost_user.c
> @@ -27,6 +27,31 @@ struct vhost_memory {
>  	struct vhost_memory_region regions[VHOST_MEMORY_MAX_NREGIONS];
>  };
> 
> +enum vhost_user_request {
> +	VHOST_USER_NONE = 0,
> +	VHOST_USER_GET_FEATURES = 1,
> +	VHOST_USER_SET_FEATURES = 2,
> +	VHOST_USER_SET_OWNER = 3,
> +	VHOST_USER_RESET_OWNER = 4,
> +	VHOST_USER_SET_MEM_TABLE = 5,
> +	VHOST_USER_SET_LOG_BASE = 6,
> +	VHOST_USER_SET_LOG_FD = 7,
> +	VHOST_USER_SET_VRING_NUM = 8,
> +	VHOST_USER_SET_VRING_ADDR = 9,
> +	VHOST_USER_SET_VRING_BASE = 10,
> +	VHOST_USER_GET_VRING_BASE = 11,
> +	VHOST_USER_SET_VRING_KICK = 12,
> +	VHOST_USER_SET_VRING_CALL = 13,
> +	VHOST_USER_SET_VRING_ERR = 14,
> +	VHOST_USER_GET_PROTOCOL_FEATURES = 15,
> +	VHOST_USER_SET_PROTOCOL_FEATURES = 16,
> +	VHOST_USER_GET_QUEUE_NUM = 17,
> +	VHOST_USER_SET_VRING_ENABLE = 18,
> +	VHOST_USER_SET_STATUS = 39,
> +	VHOST_USER_GET_STATUS = 40,
> +	VHOST_USER_MAX
> +};
> +
>  struct vhost_user_msg {
>  	enum vhost_user_request request;
> 
> --
> 2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 01/44] bus/vdev: add helper to get vdev from eth dev
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 01/44] bus/vdev: add helper to get vdev from eth dev Maxime Coquelin
  2021-01-20  0:56   ` Thomas Monjalon
@ 2021-01-21  8:58   ` Xia, Chenbo
  2021-01-25 14:51     ` Maxime Coquelin
  1 sibling, 1 reply; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-21  8:58 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

Hi Maxime,

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:24 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 01/44] bus/vdev: add helper to get vdev from eth dev

Sorry that I missed the title in v1..

Better use 'ethdev' or 'eth device'here?

Thanks,
Chenbo

> 
> This patch adds an helper macro to get the rte_vdev_device
> pointer from a rte_eth_dev pointer.
> 
> This is similar to RTE_ETH_DEV_TO_PCI().
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
> Reviewed-by: David Marchand <david.marchand@redhat.com>
> ---
>  drivers/bus/vdev/rte_bus_vdev.h | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/bus/vdev/rte_bus_vdev.h b/drivers/bus/vdev/rte_bus_vdev.h
> index d14eeb41b0..f99a41f825 100644
> --- a/drivers/bus/vdev/rte_bus_vdev.h
> +++ b/drivers/bus/vdev/rte_bus_vdev.h
> @@ -34,6 +34,8 @@ struct rte_vdev_device {
>  #define RTE_DEV_TO_VDEV_CONST(ptr) \
>  	container_of(ptr, const struct rte_vdev_device, device)
> 
> +#define RTE_ETH_DEV_TO_VDEV(eth_dev)	RTE_DEV_TO_VDEV((eth_dev)->device)
> +
>  static inline const char *
>  rte_vdev_device_name(const struct rte_vdev_device *dev)
>  {
> --
> 2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 26/44] net/virtio: add Virtio-user ops to set owner
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 26/44] net/virtio: add Virtio-user ops to set owner Maxime Coquelin
@ 2021-01-22  3:27   ` Xia, Chenbo
  0 siblings, 0 replies; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-22  3:27 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 26/44] net/virtio: add Virtio-user ops to set owner
> 
> This patch implements a dedicated callback for
> sending owner request. All the requests will be
> converted that way so that backends other than
> Vhost-user don't have to work around being it.
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user/vhost.h        |  1 +
>  drivers/net/virtio/virtio_user/vhost_kernel.c | 28 +++++++++++++++--
>  drivers/net/virtio/virtio_user/vhost_user.c   | 21 +++++++++++--
>  drivers/net/virtio/virtio_user/vhost_vdpa.c   | 30 ++++++++++++++++---
>  .../net/virtio/virtio_user/virtio_user_dev.c  |  3 +-
>  5 files changed, 72 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/vhost.h
> b/drivers/net/virtio/virtio_user/vhost.h
> index 8ec3a6a62c..5413ec6778 100644
> --- a/drivers/net/virtio/virtio_user/vhost.h
> +++ b/drivers/net/virtio/virtio_user/vhost.h
> @@ -109,6 +109,7 @@ struct virtio_user_dev;
> 
>  struct virtio_user_backend_ops {
>  	int (*setup)(struct virtio_user_dev *dev);
> +	int (*set_owner)(struct virtio_user_dev *dev);
>  	int (*send_request)(struct virtio_user_dev *dev,
>  			    enum vhost_user_request req,
>  			    void *arg);
> diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c
> b/drivers/net/virtio/virtio_user/vhost_kernel.c
> index 2c805077af..b79dcad179 100644
> --- a/drivers/net/virtio/virtio_user/vhost_kernel.c
> +++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
> @@ -6,6 +6,7 @@
>  #include <sys/stat.h>
>  #include <fcntl.h>
>  #include <unistd.h>
> +#include <errno.h>
> 
>  #include <rte_memory.h>
> 
> @@ -55,8 +56,28 @@ get_vhost_kernel_max_regions(void)
>  	close(fd);
>  }
> 
> +static int
> +vhost_kernel_ioctl(int fd, uint64_t request, void *arg)
> +{
> +	int ret;
> +
> +	ret = ioctl(fd, request, arg);
> +	if (ret) {
> +		PMD_DRV_LOG(ERR, "Vhost-kernel ioctl %"PRIu64" failed (%s)",
> +				request, strerror(errno));
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +vhost_kernel_set_owner(struct virtio_user_dev *dev)
> +{
> +	return vhost_kernel_ioctl(dev->vhostfds[0], VHOST_SET_OWNER, NULL);
> +}
> +
>  static uint64_t vhost_req_user_to_kernel[] = {
> -	[VHOST_USER_SET_OWNER] = VHOST_SET_OWNER,
>  	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
>  	[VHOST_USER_SET_FEATURES] = VHOST_SET_FEATURES,
>  	[VHOST_USER_GET_FEATURES] = VHOST_GET_FEATURES,
> @@ -175,7 +196,7 @@ tap_support_features(void)
>  }
> 
>  static int
> -vhost_kernel_ioctl(struct virtio_user_dev *dev,
> +vhost_kernel_send_request(struct virtio_user_dev *dev,
>  		   enum vhost_user_request req,
>  		   void *arg)
>  {
> @@ -385,6 +406,7 @@ vhost_kernel_enable_queue_pair(struct virtio_user_dev *dev,
> 
>  struct virtio_user_backend_ops virtio_ops_kernel = {
>  	.setup = vhost_kernel_setup,
> -	.send_request = vhost_kernel_ioctl,
> +	.set_owner = vhost_kernel_set_owner,
> +	.send_request = vhost_kernel_send_request,
>  	.enable_qp = vhost_kernel_enable_queue_pair
>  };
> diff --git a/drivers/net/virtio/virtio_user/vhost_user.c
> b/drivers/net/virtio/virtio_user/vhost_user.c
> index 55c813333a..ea3bd4ca10 100644
> --- a/drivers/net/virtio/virtio_user/vhost_user.c
> +++ b/drivers/net/virtio/virtio_user/vhost_user.c
> @@ -125,6 +125,24 @@ vhost_user_read(int fd, struct vhost_user_msg *msg)
>  	return -1;
>  }
> 
> +static int
> +vhost_user_set_owner(struct virtio_user_dev *dev)
> +{
> +	int ret;
> +	struct vhost_user_msg msg = {
> +		.request = VHOST_USER_SET_OWNER,
> +		.flags = VHOST_USER_VERSION,
> +	};
> +
> +	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Failed to set owner");
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
>  struct walk_arg {
>  	struct vhost_memory *vm;
>  	int *fds;
> @@ -230,7 +248,6 @@ prepare_vhost_memory_user(struct vhost_user_msg *msg, int
> fds[])
>  static struct vhost_user_msg m;
> 
>  const char * const vhost_msg_strings[] = {
> -	[VHOST_USER_SET_OWNER] = "VHOST_SET_OWNER",
>  	[VHOST_USER_RESET_OWNER] = "VHOST_RESET_OWNER",
>  	[VHOST_USER_SET_FEATURES] = "VHOST_SET_FEATURES",
>  	[VHOST_USER_GET_FEATURES] = "VHOST_GET_FEATURES",
> @@ -308,7 +325,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
>  		msg.size = sizeof(m.payload.u64);
>  		break;
> 
> -	case VHOST_USER_SET_OWNER:
>  	case VHOST_USER_RESET_OWNER:
>  		break;
> 
> @@ -519,6 +535,7 @@ vhost_user_enable_queue_pair(struct virtio_user_dev *dev,
> 
>  struct virtio_user_backend_ops virtio_ops_user = {
>  	.setup = vhost_user_setup,
> +	.set_owner = vhost_user_set_owner,
>  	.send_request = vhost_user_sock,
>  	.enable_qp = vhost_user_enable_queue_pair
>  };
> diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> index 004802b9eb..d9bc213e0d 100644
> --- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> +++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> @@ -39,7 +39,6 @@
>  #define VHOST_GET_BACKEND_FEATURES _IOR(VHOST_VIRTIO, 0x26, __u64)
> 
>  static uint64_t vhost_req_user_to_vdpa[] = {
> -	[VHOST_USER_SET_OWNER] = VHOST_SET_OWNER,
>  	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
>  	[VHOST_USER_SET_FEATURES] = VHOST_SET_FEATURES,
>  	[VHOST_USER_GET_FEATURES] = VHOST_GET_FEATURES,
> @@ -86,6 +85,28 @@ struct vhost_msg {
>  	};
>  };
> 
> +
> +static int
> +vhost_vdpa_ioctl(int fd, uint64_t request, void *arg)
> +{
> +	int ret;
> +
> +	ret = ioctl(fd, request, arg);
> +	if (ret) {
> +		PMD_DRV_LOG(ERR, "Vhost-vDPA ioctl %"PRIu64" failed (%s)",
> +				request, strerror(errno));
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +vhost_vdpa_set_owner(struct virtio_user_dev *dev)
> +{
> +	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_OWNER, NULL);
> +}
> +
>  static int
>  vhost_vdpa_iotlb_batch_begin(struct virtio_user_dev *dev)
>  {
> @@ -308,7 +329,7 @@ vhost_vdpa_dma_map_all(struct virtio_user_dev *dev)
>  	 (1ULL << VIRTIO_NET_F_CSUM))
> 
>  static int
> -vhost_vdpa_ioctl(struct virtio_user_dev *dev,
> +vhost_vdpa_send_request(struct virtio_user_dev *dev,
>  		   enum vhost_user_request req,
>  		   void *arg)
>  {
> @@ -396,7 +417,7 @@ vhost_vdpa_enable_queue_pair(struct virtio_user_dev *dev,
>  			.num   = enable,
>  		};
> 
> -		if (vhost_vdpa_ioctl(dev, VHOST_USER_SET_VRING_ENABLE, &state))
> +		if (vhost_vdpa_send_request(dev, VHOST_USER_SET_VRING_ENABLE,
> &state))
>  			return -1;
>  	}
> 
> @@ -407,7 +428,8 @@ vhost_vdpa_enable_queue_pair(struct virtio_user_dev *dev,
> 
>  struct virtio_user_backend_ops virtio_ops_vdpa = {
>  	.setup = vhost_vdpa_setup,
> -	.send_request = vhost_vdpa_ioctl,
> +	.set_owner = vhost_vdpa_set_owner,
> +	.send_request = vhost_vdpa_send_request,
>  	.enable_qp = vhost_vdpa_enable_queue_pair,
>  	.dma_map = vhost_vdpa_dma_map_batch,
>  	.dma_unmap = vhost_vdpa_dma_unmap_batch,
> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> index 202431ca22..f4b97d8489 100644
> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> @@ -490,8 +490,7 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char
> *path, int queues,
>  			(1ULL << VHOST_USER_F_PROTOCOL_FEATURES);
> 
>  	if (!dev->is_server) {
> -		if (dev->ops->send_request(dev, VHOST_USER_SET_OWNER,
> -					   NULL) < 0) {
> +		if (dev->ops->set_owner(dev) < 0) {
>  			PMD_INIT_LOG(ERR, "set_owner fails: %s",
>  				     strerror(errno));
>  			return -1;
> --
> 2.29.2

Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 27/44] net/virtio: add Virtio-user features ops
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 27/44] net/virtio: add Virtio-user features ops Maxime Coquelin
@ 2021-01-22  7:25   ` Xia, Chenbo
  2021-01-25 14:53     ` Maxime Coquelin
  2021-01-22  8:46   ` Xia, Chenbo
  1 sibling, 1 reply; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-22  7:25 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

Hi Maxime,

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 27/44] net/virtio: add Virtio-user features ops
> 
> This patch introduces new callbacks for getting
> and setting Virtio features, and implements them
> for the different backend types.
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user/vhost.h        |   2 +
>  drivers/net/virtio/virtio_user/vhost_kernel.c | 150 +++++++++---------
>  .../net/virtio/virtio_user/vhost_kernel_tap.c |  23 +++
>  .../net/virtio/virtio_user/vhost_kernel_tap.h |   1 +
>  drivers/net/virtio/virtio_user/vhost_user.c   |  64 +++++++-
>  drivers/net/virtio/virtio_user/vhost_vdpa.c   |  38 +++--
>  .../net/virtio/virtio_user/virtio_user_dev.c  |   5 +-
>  drivers/net/virtio/virtio_user_ethdev.c       |   3 +-
>  8 files changed, 190 insertions(+), 96 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/vhost.h
> b/drivers/net/virtio/virtio_user/vhost.h
> index 5413ec6778..13a88c7671 100644
> --- a/drivers/net/virtio/virtio_user/vhost.h
> +++ b/drivers/net/virtio/virtio_user/vhost.h
> @@ -110,6 +110,8 @@ struct virtio_user_dev;

<snip>

> +
> +	ret = tap_support_features(&tap_features);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Failed to get TAP features)");

Delete the ')' before " ?

> +		return -1;
> +	}
> +

<snip>

> 
> +static int
> +vhost_user_get_features(struct virtio_user_dev *dev, uint64_t *features)
> +{
> +	int ret;
> +	struct vhost_user_msg msg = {
> +		.request = VHOST_USER_GET_FEATURES,
> +		.flags = VHOST_USER_VERSION,
> +	};
> +
> +	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
> +	if (ret < 0)
> +		goto err;
> +
> +	ret = vhost_user_read(dev->vhostfd, &msg);
> +	if (ret < 0)
> +		goto err;

Better add error log both after write and read?

Thanks!
Chenbo

> +
> +	if (msg.request != VHOST_USER_GET_FEATURES) {
> +		PMD_DRV_LOG(ERR, "Unexpected request type (%d)", msg.request);
> +		goto err;
> +	}
> +
> +	if (msg.size != sizeof(*features)) {
> +		PMD_DRV_LOG(ERR, "Unexpected payload size (%u)", msg.size);
> +		goto err;
> +	}
> +
> +	*features = msg.payload.u64;
> +
> +	return 0;
> +err:
> +	PMD_DRV_LOG(ERR, "Failed to get backend features");
> +
> +	return -1;
> +}
> +
> +static int
> +vhost_user_set_features(struct virtio_user_dev *dev, uint64_t features)
> +{
> +	int ret;
> +	struct vhost_user_msg msg = {
> +		.request = VHOST_USER_SET_FEATURES,
> +		.flags = VHOST_USER_VERSION,
> +		.size = sizeof(features),
> +		.payload.u64 = features,
> +	};
> +
> +	msg.payload.u64 |= dev->device_features & (1ULL <<
> VHOST_USER_F_PROTOCOL_FEATURES);
> +
> +	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Failed to set features");
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
>  struct walk_arg {
>  	struct vhost_memory *vm;
>  	int *fds;
> @@ -249,8 +307,6 @@ static struct vhost_user_msg m;
> 
>  const char * const vhost_msg_strings[] = {
>  	[VHOST_USER_RESET_OWNER] = "VHOST_RESET_OWNER",
> -	[VHOST_USER_SET_FEATURES] = "VHOST_SET_FEATURES",
> -	[VHOST_USER_GET_FEATURES] = "VHOST_GET_FEATURES",
>  	[VHOST_USER_SET_VRING_CALL] = "VHOST_SET_VRING_CALL",
>  	[VHOST_USER_SET_VRING_NUM] = "VHOST_SET_VRING_NUM",
>  	[VHOST_USER_SET_VRING_BASE] = "VHOST_SET_VRING_BASE",
> @@ -299,7 +355,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
>  				(1ULL << VHOST_USER_PROTOCOL_F_STATUS))))
>  			return -ENOTSUP;
>  		/* Fallthrough */
> -	case VHOST_USER_GET_FEATURES:
>  	case VHOST_USER_GET_PROTOCOL_FEATURES:
>  		need_reply = 1;
>  		break;
> @@ -398,7 +453,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
>  		}
> 
>  		switch (req) {
> -		case VHOST_USER_GET_FEATURES:
>  		case VHOST_USER_GET_STATUS:
>  		case VHOST_USER_GET_PROTOCOL_FEATURES:
>  			if (msg.size != sizeof(m.payload.u64)) {
> @@ -536,6 +590,8 @@ vhost_user_enable_queue_pair(struct virtio_user_dev *dev,
>  struct virtio_user_backend_ops virtio_ops_user = {
>  	.setup = vhost_user_setup,
>  	.set_owner = vhost_user_set_owner,
> +	.get_features = vhost_user_get_features,
> +	.set_features = vhost_user_set_features,
>  	.send_request = vhost_user_sock,
>  	.enable_qp = vhost_user_enable_queue_pair
>  };
> diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> index d9bc213e0d..22a329526a 100644
> --- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> +++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> @@ -40,8 +40,6 @@
> 
>  static uint64_t vhost_req_user_to_vdpa[] = {
>  	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
> -	[VHOST_USER_SET_FEATURES] = VHOST_SET_FEATURES,
> -	[VHOST_USER_GET_FEATURES] = VHOST_GET_FEATURES,
>  	[VHOST_USER_SET_VRING_CALL] = VHOST_SET_VRING_CALL,
>  	[VHOST_USER_SET_VRING_NUM] = VHOST_SET_VRING_NUM,
>  	[VHOST_USER_SET_VRING_BASE] = VHOST_SET_VRING_BASE,
> @@ -107,6 +105,32 @@ vhost_vdpa_set_owner(struct virtio_user_dev *dev)
>  	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_OWNER, NULL);
>  }
> 
> +static int
> +vhost_vdpa_get_features(struct virtio_user_dev *dev, uint64_t *features)
> +{
> +	int ret;
> +
> +	ret = vhost_vdpa_ioctl(dev->vhostfd, VHOST_GET_FEATURES, features);
> +	if (ret) {
> +		PMD_DRV_LOG(ERR, "Failed to get features");
> +		return -1;
> +	}
> +
> +	/* Multiqueue not supported for now */
> +	*features &= ~(1ULL << VIRTIO_NET_F_MQ);
> +
> +	return 0;
> +}
> +
> +static int
> +vhost_vdpa_set_features(struct virtio_user_dev *dev, uint64_t features)
> +{
> +	/* WORKAROUND */
> +	features |= 1ULL << VIRTIO_F_IOMMU_PLATFORM;
> +
> +	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_FEATURES, &features);
> +}
> +
>  static int
>  vhost_vdpa_iotlb_batch_begin(struct virtio_user_dev *dev)
>  {
> @@ -343,14 +367,6 @@ vhost_vdpa_send_request(struct virtio_user_dev *dev,
>  	if (req_vdpa == VHOST_SET_MEM_TABLE)
>  		return vhost_vdpa_dma_map_all(dev);
> 
> -	if (req_vdpa == VHOST_SET_FEATURES) {
> -		/* WORKAROUND */
> -		*(uint64_t *)arg |= 1ULL << VIRTIO_F_IOMMU_PLATFORM;
> -
> -		/* Multiqueue not supported for now */
> -		*(uint64_t *)arg &= ~(1ULL << VIRTIO_NET_F_MQ);
> -	}
> -
>  	switch (req_vdpa) {
>  	case VHOST_SET_VRING_NUM:
>  	case VHOST_SET_VRING_ADDR:
> @@ -429,6 +445,8 @@ vhost_vdpa_enable_queue_pair(struct virtio_user_dev *dev,
>  struct virtio_user_backend_ops virtio_ops_vdpa = {
>  	.setup = vhost_vdpa_setup,
>  	.set_owner = vhost_vdpa_set_owner,
> +	.get_features = vhost_vdpa_get_features,
> +	.set_features = vhost_vdpa_set_features,
>  	.send_request = vhost_vdpa_send_request,
>  	.enable_qp = vhost_vdpa_enable_queue_pair,
>  	.dma_map = vhost_vdpa_dma_map_batch,
> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> index f4b97d8489..1f3bbae663 100644
> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> @@ -141,7 +141,7 @@ virtio_user_dev_set_features(struct virtio_user_dev *dev)
>  	/* Strip VIRTIO_NET_F_CTRL_VQ, as devices do not really need to know */
>  	features &= ~(1ull << VIRTIO_NET_F_CTRL_VQ);
>  	features &= ~(1ull << VIRTIO_NET_F_STATUS);
> -	ret = dev->ops->send_request(dev, VHOST_USER_SET_FEATURES, &features);
> +	ret = dev->ops->set_features(dev, features);
>  	if (ret < 0)
>  		goto error;
>  	PMD_DRV_LOG(INFO, "set features: %" PRIx64, features);
> @@ -496,8 +496,7 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char
> *path, int queues,
>  			return -1;
>  		}
> 
> -		if (dev->ops->send_request(dev, VHOST_USER_GET_FEATURES,
> -					   &dev->device_features) < 0) {
> +		if (dev->ops->get_features(dev, &dev->device_features) < 0) {
>  			PMD_INIT_LOG(ERR, "get_features failed: %s",
>  				     strerror(errno));
>  			return -1;
> diff --git a/drivers/net/virtio/virtio_user_ethdev.c
> b/drivers/net/virtio/virtio_user_ethdev.c
> index 91794b8645..56c379bc15 100644
> --- a/drivers/net/virtio/virtio_user_ethdev.c
> +++ b/drivers/net/virtio/virtio_user_ethdev.c
> @@ -85,8 +85,7 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev)
> 
>  	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);
> 
> -	if (dev->ops->send_request(dev, VHOST_USER_GET_FEATURES,
> -				   &dev->device_features) < 0) {
> +	if (dev->ops->get_features(dev, &dev->device_features) < 0) {
>  		PMD_INIT_LOG(ERR, "get_features failed: %s",
>  			     strerror(errno));
>  		return -1;
> --
> 2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 28/44] net/virtio: add Virtio-user protocol features ops
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 28/44] net/virtio: add Virtio-user protocol " Maxime Coquelin
@ 2021-01-22  7:27   ` Xia, Chenbo
  0 siblings, 0 replies; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-22  7:27 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

Hi Maxime,

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 28/44] net/virtio: add Virtio-user protocol features ops
> 
> This patch introduces new callbacks for getting
> and setting Vhost-user protocol features.
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user/vhost.h        |  2 +
>  drivers/net/virtio/virtio_user/vhost_user.c   | 64 +++++++++++++++++--
>  drivers/net/virtio/virtio_user/vhost_vdpa.c   | 14 ++++
>  .../net/virtio/virtio_user/virtio_user_dev.c  | 14 ++--
>  drivers/net/virtio/virtio_user_ethdev.c       | 14 ++--
>  5 files changed, 82 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/vhost.h
> b/drivers/net/virtio/virtio_user/vhost.h
> index 13a88c7671..d805526130 100644
> --- a/drivers/net/virtio/virtio_user/vhost.h
> +++ b/drivers/net/virtio/virtio_user/vhost.h
> @@ -112,6 +112,8 @@ struct virtio_user_backend_ops {
>  	int (*set_owner)(struct virtio_user_dev *dev);
>  	int (*get_features)(struct virtio_user_dev *dev, uint64_t *features);
>  	int (*set_features)(struct virtio_user_dev *dev, uint64_t features);
> +	int (*get_protocol_features)(struct virtio_user_dev *dev, uint64_t
> *features);
> +	int (*set_protocol_features)(struct virtio_user_dev *dev, uint64_t
> features);
>  	int (*send_request)(struct virtio_user_dev *dev,
>  			    enum vhost_user_request req,
>  			    void *arg);
> diff --git a/drivers/net/virtio/virtio_user/vhost_user.c
> b/drivers/net/virtio/virtio_user/vhost_user.c
> index 8e5bf332d6..4877574f72 100644
> --- a/drivers/net/virtio/virtio_user/vhost_user.c
> +++ b/drivers/net/virtio/virtio_user/vhost_user.c
> @@ -201,6 +201,62 @@ vhost_user_set_features(struct virtio_user_dev *dev,
> uint64_t features)
>  	return 0;
>  }
> 
> +static int
> +vhost_user_get_protocol_features(struct virtio_user_dev *dev, uint64_t
> *features)
> +{
> +	int ret;
> +	struct vhost_user_msg msg = {
> +		.request = VHOST_USER_GET_PROTOCOL_FEATURES,
> +		.flags = VHOST_USER_VERSION,
> +	};
> +
> +	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
> +	if (ret < 0)
> +		goto err;
> +
> +	ret = vhost_user_read(dev->vhostfd, &msg);
> +	if (ret < 0)
> +		goto err;

Better add error log both after write and read?

Thanks
Chenbo

> +
> +	if (msg.request != VHOST_USER_GET_PROTOCOL_FEATURES) {
> +		PMD_DRV_LOG(ERR, "Unexpected request type (%d)", msg.request);
> +		goto err;
> +	}
> +
> +	if (msg.size != sizeof(*features)) {
> +		PMD_DRV_LOG(ERR, "Unexpected payload size (%u)", msg.size);
> +		goto err;
> +	}
> +
> +	*features = msg.payload.u64;
> +
> +	return 0;
> +err:
> +	PMD_DRV_LOG(ERR, "Failed to get backend protocol features");
> +
> +	return -1;
> +}
> +
> +static int
> +vhost_user_set_protocol_features(struct virtio_user_dev *dev, uint64_t
> features)
> +{
> +	int ret;
> +	struct vhost_user_msg msg = {
> +		.request = VHOST_USER_SET_PROTOCOL_FEATURES,
> +		.flags = VHOST_USER_VERSION,
> +		.size = sizeof(features),
> +		.payload.u64 = features,
> +	};
> +
> +	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Failed to set protocol features");
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
>  struct walk_arg {
>  	struct vhost_memory *vm;
>  	int *fds;
> @@ -315,8 +371,6 @@ const char * const vhost_msg_strings[] = {
>  	[VHOST_USER_SET_VRING_KICK] = "VHOST_SET_VRING_KICK",
>  	[VHOST_USER_SET_MEM_TABLE] = "VHOST_SET_MEM_TABLE",
>  	[VHOST_USER_SET_VRING_ENABLE] = "VHOST_SET_VRING_ENABLE",
> -	[VHOST_USER_GET_PROTOCOL_FEATURES] = "VHOST_USER_GET_PROTOCOL_FEATURES",
> -	[VHOST_USER_SET_PROTOCOL_FEATURES] = "VHOST_USER_SET_PROTOCOL_FEATURES",
>  	[VHOST_USER_SET_STATUS] = "VHOST_SET_STATUS",
>  	[VHOST_USER_GET_STATUS] = "VHOST_GET_STATUS",
>  };
> @@ -354,8 +408,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
>  		    (!(dev->protocol_features &
>  				(1ULL << VHOST_USER_PROTOCOL_F_STATUS))))
>  			return -ENOTSUP;
> -		/* Fallthrough */
> -	case VHOST_USER_GET_PROTOCOL_FEATURES:
>  		need_reply = 1;
>  		break;
> 
> @@ -368,7 +420,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
>  		if (has_reply_ack)
>  			msg.flags |= VHOST_USER_NEED_REPLY_MASK;
>  		/* Fallthrough */
> -	case VHOST_USER_SET_PROTOCOL_FEATURES:
>  	case VHOST_USER_SET_LOG_BASE:
>  		msg.payload.u64 = *((__u64 *)arg);
>  		msg.size = sizeof(m.payload.u64);
> @@ -454,7 +505,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
> 
>  		switch (req) {
>  		case VHOST_USER_GET_STATUS:
> -		case VHOST_USER_GET_PROTOCOL_FEATURES:
>  			if (msg.size != sizeof(m.payload.u64)) {
>  				PMD_DRV_LOG(ERR, "Received bad msg size");
>  				return -1;
> @@ -592,6 +642,8 @@ struct virtio_user_backend_ops virtio_ops_user = {
>  	.set_owner = vhost_user_set_owner,
>  	.get_features = vhost_user_get_features,
>  	.set_features = vhost_user_set_features,
> +	.get_protocol_features = vhost_user_get_protocol_features,
> +	.set_protocol_features = vhost_user_set_protocol_features,
>  	.send_request = vhost_user_sock,
>  	.enable_qp = vhost_user_enable_queue_pair
>  };
> diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> index 22a329526a..f627afbcfc 100644
> --- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> +++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> @@ -105,6 +105,18 @@ vhost_vdpa_set_owner(struct virtio_user_dev *dev)
>  	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_OWNER, NULL);
>  }
> 
> +static int
> +vhost_vdpa_get_backend_features(struct virtio_user_dev *dev, uint64_t
> *features)
> +{
> +	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_GET_BACKEND_FEATURES,
> features);
> +}
> +
> +static int
> +vhost_vdpa_set_backend_features(struct virtio_user_dev *dev, uint64_t
> features)
> +{
> +	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_BACKEND_FEATURES,
> &features);
> +}
> +
>  static int
>  vhost_vdpa_get_features(struct virtio_user_dev *dev, uint64_t *features)
>  {
> @@ -447,6 +459,8 @@ struct virtio_user_backend_ops virtio_ops_vdpa = {
>  	.set_owner = vhost_vdpa_set_owner,
>  	.get_features = vhost_vdpa_get_features,
>  	.set_features = vhost_vdpa_set_features,
> +	.get_protocol_features = vhost_vdpa_get_backend_features,
> +	.set_protocol_features = vhost_vdpa_set_backend_features,
>  	.send_request = vhost_vdpa_send_request,
>  	.enable_qp = vhost_vdpa_enable_queue_pair,
>  	.dma_map = vhost_vdpa_dma_map_batch,
> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> index 1f3bbae663..45417bbc5d 100644
> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> @@ -505,22 +505,16 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char
> *path, int queues,
> 
>  		if ((dev->device_features & (1ULL <<
> VHOST_USER_F_PROTOCOL_FEATURES)) ||
>  				(dev->backend_type == VIRTIO_USER_BACKEND_VHOST_VDPA))
> {
> -			if (dev->ops->send_request(dev,
> -					VHOST_USER_GET_PROTOCOL_FEATURES,
> -					&protocol_features))
> +			if (dev->ops->get_protocol_features(dev, &protocol_features))
>  				return -1;
> 
>  			dev->protocol_features &= protocol_features;
> 
> -			if (dev->ops->send_request(dev,
> -					VHOST_USER_SET_PROTOCOL_FEATURES,
> -					&dev->protocol_features))
> +			if (dev->ops->set_protocol_features(dev, dev-
> >protocol_features))
>  				return -1;
> 
> -			if (!(dev->protocol_features &
> -					(1ULL << VHOST_USER_PROTOCOL_F_MQ)))
> -				dev->unsupported_features |=
> -					(1ull << VIRTIO_NET_F_MQ);
> +			if (!(dev->protocol_features & (1ULL <<
> VHOST_USER_PROTOCOL_F_MQ)))
> +				dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
>  		}
>  	} else {
>  		/* We just pretend vhost-user can support all these features.
> diff --git a/drivers/net/virtio/virtio_user_ethdev.c
> b/drivers/net/virtio/virtio_user_ethdev.c
> index 56c379bc15..5e256f4e6d 100644
> --- a/drivers/net/virtio/virtio_user_ethdev.c
> +++ b/drivers/net/virtio/virtio_user_ethdev.c
> @@ -93,23 +93,17 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev)
> 
>  	if (dev->device_features &
>  			(1ULL << VHOST_USER_F_PROTOCOL_FEATURES)) {
> -		if (dev->ops->send_request(dev,
> -					VHOST_USER_GET_PROTOCOL_FEATURES,
> -					&protocol_features))
> +		if (dev->ops->get_protocol_features(dev, &protocol_features))
>  			return -1;
> 
>  		/* Offer VHOST_USER_PROTOCOL_F_STATUS */
> -		dev->protocol_features |=
> -			(1ULL << VHOST_USER_PROTOCOL_F_STATUS);
> +		dev->protocol_features |= (1ULL << VHOST_USER_PROTOCOL_F_STATUS);
>  		dev->protocol_features &= protocol_features;
> 
> -		if (dev->ops->send_request(dev,
> -					VHOST_USER_SET_PROTOCOL_FEATURES,
> -					&dev->protocol_features))
> +		if (dev->ops->set_protocol_features(dev, dev->protocol_features))
>  			return -1;
> 
> -		if (!(dev->protocol_features &
> -				(1ULL << VHOST_USER_PROTOCOL_F_MQ)))
> +		if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
>  			dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
>  	}
> 
> --
> 2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 29/44] net/virtio: add Virtio-user memory tables ops
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 29/44] net/virtio: add Virtio-user memory tables ops Maxime Coquelin
@ 2021-01-22  7:34   ` Xia, Chenbo
  2021-01-25 14:56     ` Maxime Coquelin
  0 siblings, 1 reply; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-22  7:34 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

Hi Maxime,

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 29/44] net/virtio: add Virtio-user memory tables ops
> 
> This patch implements a dedicated callback for
> preparing and sending memory table to the backends.
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user/vhost.h        |  1 +
>  drivers/net/virtio/virtio_user/vhost_kernel.c | 60 ++++++-------
>  drivers/net/virtio/virtio_user/vhost_user.c   | 86 ++++++++++++++-----
>  drivers/net/virtio/virtio_user/vhost_vdpa.c   |  8 +-
>  .../net/virtio/virtio_user/virtio_user_dev.c  |  4 +-
>  5 files changed, 101 insertions(+), 58 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/vhost.h
> b/drivers/net/virtio/virtio_user/vhost.h
> index d805526130..463801f563 100644
> --- a/drivers/net/virtio/virtio_user/vhost.h
> +++ b/drivers/net/virtio/virtio_user/vhost.h
> @@ -114,6 +114,7 @@ struct virtio_user_backend_ops {
>  	int (*set_features)(struct virtio_user_dev *dev, uint64_t features);
>  	int (*get_protocol_features)(struct virtio_user_dev *dev, uint64_t
> *features);
>  	int (*set_protocol_features)(struct virtio_user_dev *dev, uint64_t
> features);
> +	int (*set_memory_table)(struct virtio_user_dev *dev);
>  	int (*send_request)(struct virtio_user_dev *dev,
>  			    enum vhost_user_request req,
>  			    void *arg);
> diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c
> b/drivers/net/virtio/virtio_user/vhost_kernel.c
> index f44df8ef1f..2d30f572b6 100644
> --- a/drivers/net/virtio/virtio_user/vhost_kernel.c
> +++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
> @@ -148,17 +148,6 @@ vhost_kernel_set_features(struct virtio_user_dev *dev,
> uint64_t features)
>  	return vhost_kernel_ioctl(dev->vhostfds[0], VHOST_SET_FEATURES,
> &features);
>  }
> 
> -static uint64_t vhost_req_user_to_kernel[] = {
> -	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
> -	[VHOST_USER_SET_VRING_CALL] = VHOST_SET_VRING_CALL,
> -	[VHOST_USER_SET_VRING_NUM] = VHOST_SET_VRING_NUM,
> -	[VHOST_USER_SET_VRING_BASE] = VHOST_SET_VRING_BASE,
> -	[VHOST_USER_GET_VRING_BASE] = VHOST_GET_VRING_BASE,
> -	[VHOST_USER_SET_VRING_ADDR] = VHOST_SET_VRING_ADDR,
> -	[VHOST_USER_SET_VRING_KICK] = VHOST_SET_VRING_KICK,
> -	[VHOST_USER_SET_MEM_TABLE] = VHOST_SET_MEM_TABLE,
> -};
> -
>  static int
>  add_memseg_list(const struct rte_memseg_list *msl, void *arg)
>  {
> @@ -193,16 +182,17 @@ add_memseg_list(const struct rte_memseg_list *msl, void
> *arg)
>   * have much more memory regions. Below function will treat each
>   * contiguous memory space reserved by DPDK as one region.
>   */
> -static struct vhost_memory_kernel *
> -prepare_vhost_memory_kernel(void)
> +static int
> +vhost_kernel_set_memory_table(struct virtio_user_dev *dev)
>  {
>  	struct vhost_memory_kernel *vm;
> +	int ret;
> 
>  	vm = malloc(sizeof(struct vhost_memory_kernel) +
>  			max_regions *
>  			sizeof(struct vhost_memory_region));
>  	if (!vm)
> -		return NULL;
> +		goto err;
> 
>  	vm->nregions = 0;
>  	vm->padding = 0;
> @@ -211,14 +201,34 @@ prepare_vhost_memory_kernel(void)
>  	 * The memory lock has already been taken by memory subsystem
>  	 * or virtio_user_start_device().
>  	 */
> -	if (rte_memseg_list_walk_thread_unsafe(add_memseg_list, vm) < 0) {
> -		free(vm);
> -		return NULL;
> -	}
> +	ret = rte_memseg_list_walk_thread_unsafe(add_memseg_list, vm);
> +	if (ret < 0)
> +		goto err_free;
> +
> +	ret = vhost_kernel_ioctl(dev->vhostfds[0], VHOST_SET_MEM_TABLE, vm);
> +	if (ret < 0)
> +		goto err_free;
> 
> -	return vm;
> +	free(vm);
> +
> +	return 0;
> +err_free:
> +	free(vm);
> +err:
> +	PMD_DRV_LOG(ERR, "Failed to set memory table");
> +	return -1;
>  }
> 
> +static uint64_t vhost_req_user_to_kernel[] = {
> +	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
> +	[VHOST_USER_SET_VRING_CALL] = VHOST_SET_VRING_CALL,
> +	[VHOST_USER_SET_VRING_NUM] = VHOST_SET_VRING_NUM,
> +	[VHOST_USER_SET_VRING_BASE] = VHOST_SET_VRING_BASE,
> +	[VHOST_USER_GET_VRING_BASE] = VHOST_GET_VRING_BASE,
> +	[VHOST_USER_SET_VRING_ADDR] = VHOST_SET_VRING_ADDR,
> +	[VHOST_USER_SET_VRING_KICK] = VHOST_SET_VRING_KICK,
> +};
> +
>  static int
>  vhost_kernel_send_request(struct virtio_user_dev *dev,
>  		   enum vhost_user_request req,
> @@ -227,7 +237,6 @@ vhost_kernel_send_request(struct virtio_user_dev *dev,
>  	int ret = -1;
>  	unsigned int i;
>  	uint64_t req_kernel;
> -	struct vhost_memory_kernel *vm = NULL;
>  	int vhostfd;
>  	unsigned int queue_sel;
> 
> @@ -235,13 +244,6 @@ vhost_kernel_send_request(struct virtio_user_dev *dev,
> 
>  	req_kernel = vhost_req_user_to_kernel[req];
> 
> -	if (req_kernel == VHOST_SET_MEM_TABLE) {
> -		vm = prepare_vhost_memory_kernel();
> -		if (!vm)
> -			return -1;
> -		arg = (void *)vm;
> -	}
> -
>  	switch (req_kernel) {
>  	case VHOST_SET_VRING_NUM:
>  	case VHOST_SET_VRING_ADDR:
> @@ -271,9 +273,6 @@ vhost_kernel_send_request(struct virtio_user_dev *dev,
>  		ret = ioctl(vhostfd, req_kernel, arg);
>  	}
> 
> -	if (vm)
> -		free(vm);
> -
>  	if (ret < 0)
>  		PMD_DRV_LOG(ERR, "%s failed: %s",
>  			    vhost_msg_strings[req], strerror(errno));
> @@ -403,6 +402,7 @@ struct virtio_user_backend_ops virtio_ops_kernel = {
>  	.set_owner = vhost_kernel_set_owner,
>  	.get_features = vhost_kernel_get_features,
>  	.set_features = vhost_kernel_set_features,
> +	.set_memory_table = vhost_kernel_set_memory_table,
>  	.send_request = vhost_kernel_send_request,
>  	.enable_qp = vhost_kernel_enable_queue_pair
>  };
> diff --git a/drivers/net/virtio/virtio_user/vhost_user.c
> b/drivers/net/virtio/virtio_user/vhost_user.c
> index 4877574f72..94533e31ce 100644
> --- a/drivers/net/virtio/virtio_user/vhost_user.c
> +++ b/drivers/net/virtio/virtio_user/vhost_user.c
> @@ -81,6 +81,9 @@ vhost_user_write(int fd, struct vhost_user_msg *msg, int
> *fds, int fd_num)
>  		r = sendmsg(fd, &msgh, 0);
>  	} while (r < 0 && errno == EINTR);
> 
> +	if (r < 0)
> +		PMD_DRV_LOG(ERR, "Failed to send msg: %s", strerror(errno));
> +
>  	return r;
>  }
> 
> @@ -125,6 +128,39 @@ vhost_user_read(int fd, struct vhost_user_msg *msg)
>  	return -1;
>  }
> 
> +static int
> +vhost_user_check_reply_ack(struct virtio_user_dev *dev, struct vhost_user_msg
> *msg)
> +{
> +	enum vhost_user_request req = msg->request;
> +	int ret;
> +
> +	if (!(msg->flags & VHOST_USER_NEED_REPLY_MASK))
> +		return 0;
> +
> +	ret = vhost_user_read(dev->vhostfd, msg);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Failed to read reply-ack");
> +		return -1;
> +	}
> +
> +	if (req != msg->request) {
> +		PMD_DRV_LOG(ERR, "Unexpected reply-ack request type (%d)", msg-
> >request);
> +		return -1;
> +	}
> +
> +	if (msg->size != sizeof(msg->payload.u64)) {
> +		PMD_DRV_LOG(ERR, "Unexpected reply-ack payload size (%d)", msg-
> >size);

Better to use '%u'?

> +		return -1;
> +	}
> +
> +	if (msg->payload.u64) {
> +		PMD_DRV_LOG(ERR, "Slave replied NACK to request type %d", msg-
> >request);

Replace '%d' with '(%d)' to align with the above style? :P

Thanks,
Chenbo

> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
>  static int
>  vhost_user_set_owner(struct virtio_user_dev *dev)
>  {
> @@ -338,25 +374,47 @@ update_memory_region(const struct rte_memseg_list *msl
> __rte_unused,
>  }
> 
>  static int
> -prepare_vhost_memory_user(struct vhost_user_msg *msg, int fds[])
> +vhost_user_set_memory_table(struct virtio_user_dev *dev)
>  {
>  	struct walk_arg wa;
> +	int fds[VHOST_MEMORY_MAX_NREGIONS];
> +	int ret, fd_num;
> +	struct vhost_user_msg msg = {
> +		.request = VHOST_USER_SET_MEM_TABLE,
> +		.flags = VHOST_USER_VERSION,
> +	};
> +
> +	if (dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK))
> +		msg.flags |= VHOST_USER_NEED_REPLY_MASK;
> 
>  	wa.region_nr = 0;
> -	wa.vm = &msg->payload.memory;
> +	wa.vm = &msg.payload.memory;
>  	wa.fds = fds;
> 
>  	/*
>  	 * The memory lock has already been taken by memory subsystem
>  	 * or virtio_user_start_device().
>  	 */
> -	if (rte_memseg_walk_thread_unsafe(update_memory_region, &wa) < 0)
> -		return -1;
> +	ret = rte_memseg_walk_thread_unsafe(update_memory_region, &wa);
> +	if (ret < 0)
> +		goto err;
> 
> -	msg->payload.memory.nregions = wa.region_nr;
> -	msg->payload.memory.padding = 0;
> +	fd_num = wa.region_nr;
> +	msg.payload.memory.nregions = wa.region_nr;
> +	msg.payload.memory.padding = 0;
> 
> -	return 0;
> +	msg.size = sizeof(msg.payload.memory.nregions);
> +	msg.size += sizeof(msg.payload.memory.padding);
> +	msg.size += fd_num * sizeof(struct vhost_memory_region);
> +
> +	ret = vhost_user_write(dev->vhostfd, &msg, fds, fd_num);
> +	if (ret < 0)
> +		goto err;
> +
> +	return vhost_user_check_reply_ack(dev, &msg);
> +err:
> +	PMD_DRV_LOG(ERR, "Failed to set memory table");
> +	return -1;
>  }
> 
>  static struct vhost_user_msg m;
> @@ -369,7 +427,6 @@ const char * const vhost_msg_strings[] = {
>  	[VHOST_USER_GET_VRING_BASE] = "VHOST_GET_VRING_BASE",
>  	[VHOST_USER_SET_VRING_ADDR] = "VHOST_SET_VRING_ADDR",
>  	[VHOST_USER_SET_VRING_KICK] = "VHOST_SET_VRING_KICK",
> -	[VHOST_USER_SET_MEM_TABLE] = "VHOST_SET_MEM_TABLE",
>  	[VHOST_USER_SET_VRING_ENABLE] = "VHOST_SET_VRING_ENABLE",
>  	[VHOST_USER_SET_STATUS] = "VHOST_SET_STATUS",
>  	[VHOST_USER_GET_STATUS] = "VHOST_GET_STATUS",
> @@ -434,18 +491,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
>  	case VHOST_USER_RESET_OWNER:
>  		break;
> 
> -	case VHOST_USER_SET_MEM_TABLE:
> -		if (prepare_vhost_memory_user(&msg, fds) < 0)
> -			return -1;
> -		fd_num = msg.payload.memory.nregions;
> -		msg.size = sizeof(m.payload.memory.nregions);
> -		msg.size += sizeof(m.payload.memory.padding);
> -		msg.size += fd_num * sizeof(struct vhost_memory_region);
> -
> -		if (has_reply_ack)
> -			msg.flags |= VHOST_USER_NEED_REPLY_MASK;
> -		break;
> -
>  	case VHOST_USER_SET_LOG_FD:
>  		fds[fd_num++] = *((int *)arg);
>  		break;
> @@ -644,6 +689,7 @@ struct virtio_user_backend_ops virtio_ops_user = {
>  	.set_features = vhost_user_set_features,
>  	.get_protocol_features = vhost_user_get_protocol_features,
>  	.set_protocol_features = vhost_user_set_protocol_features,
> +	.set_memory_table = vhost_user_set_memory_table,
>  	.send_request = vhost_user_sock,
>  	.enable_qp = vhost_user_enable_queue_pair
>  };
> diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> index f627afbcfc..bd7daebf0c 100644
> --- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> +++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> @@ -19,7 +19,6 @@
>  #define VHOST_SET_FEATURES _IOW(VHOST_VIRTIO, 0x00, __u64)
>  #define VHOST_SET_OWNER _IO(VHOST_VIRTIO, 0x01)
>  #define VHOST_RESET_OWNER _IO(VHOST_VIRTIO, 0x02)
> -#define VHOST_SET_MEM_TABLE _IOW(VHOST_VIRTIO, 0x03, void *)
>  #define VHOST_SET_LOG_BASE _IOW(VHOST_VIRTIO, 0x04, __u64)
>  #define VHOST_SET_LOG_FD _IOW(VHOST_VIRTIO, 0x07, int)
>  #define VHOST_SET_VRING_NUM _IOW(VHOST_VIRTIO, 0x10, struct vhost_vring_state)
> @@ -46,7 +45,6 @@ static uint64_t vhost_req_user_to_vdpa[] = {
>  	[VHOST_USER_GET_VRING_BASE] = VHOST_GET_VRING_BASE,
>  	[VHOST_USER_SET_VRING_ADDR] = VHOST_SET_VRING_ADDR,
>  	[VHOST_USER_SET_VRING_KICK] = VHOST_SET_VRING_KICK,
> -	[VHOST_USER_SET_MEM_TABLE] = VHOST_SET_MEM_TABLE,
>  	[VHOST_USER_SET_STATUS] = VHOST_VDPA_SET_STATUS,
>  	[VHOST_USER_GET_STATUS] = VHOST_VDPA_GET_STATUS,
>  	[VHOST_USER_SET_VRING_ENABLE] = VHOST_VDPA_SET_VRING_ENABLE,
> @@ -319,7 +317,7 @@ vhost_vdpa_map(const struct rte_memseg_list *msl, const
> struct rte_memseg *ms,
>  }
> 
>  static int
> -vhost_vdpa_dma_map_all(struct virtio_user_dev *dev)
> +vhost_vdpa_set_memory_table(struct virtio_user_dev *dev)
>  {
>  	int ret;
> 
> @@ -376,9 +374,6 @@ vhost_vdpa_send_request(struct virtio_user_dev *dev,
> 
>  	req_vdpa = vhost_req_user_to_vdpa[req];
> 
> -	if (req_vdpa == VHOST_SET_MEM_TABLE)
> -		return vhost_vdpa_dma_map_all(dev);
> -
>  	switch (req_vdpa) {
>  	case VHOST_SET_VRING_NUM:
>  	case VHOST_SET_VRING_ADDR:
> @@ -461,6 +456,7 @@ struct virtio_user_backend_ops virtio_ops_vdpa = {
>  	.set_features = vhost_vdpa_set_features,
>  	.get_protocol_features = vhost_vdpa_get_backend_features,
>  	.set_protocol_features = vhost_vdpa_set_backend_features,
> +	.set_memory_table = vhost_vdpa_set_memory_table,
>  	.send_request = vhost_vdpa_send_request,
>  	.enable_qp = vhost_vdpa_enable_queue_pair,
>  	.dma_map = vhost_vdpa_dma_map_batch,
> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> index 45417bbc5d..cb8f8a872c 100644
> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> @@ -177,7 +177,7 @@ virtio_user_start_device(struct virtio_user_dev *dev)
>  		goto error;
> 
>  	/* Step 2: share memory regions */
> -	ret = dev->ops->send_request(dev, VHOST_USER_SET_MEM_TABLE, NULL);
> +	ret = dev->ops->set_memory_table(dev);
>  	if (ret < 0)
>  		goto error;
> 
> @@ -352,7 +352,7 @@ virtio_user_mem_event_cb(enum rte_mem_event type
> __rte_unused,
>  		dev->ops->enable_qp(dev, i, 0);
> 
>  	/* Step 2: update memory regions */
> -	dev->ops->send_request(dev, VHOST_USER_SET_MEM_TABLE, NULL);
> +	dev->ops->set_memory_table(dev);
> 
>  	/* Step 3: resume the active queues */
>  	for (i = 0; i < dev->queue_pairs; i++)
> --
> 2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 30/44] net/virtio: add Virtio-user vring setting ops
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 30/44] net/virtio: add Virtio-user vring setting ops Maxime Coquelin
@ 2021-01-22  7:49   ` Xia, Chenbo
  0 siblings, 0 replies; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-22  7:49 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 30/44] net/virtio: add Virtio-user vring setting ops
> 
> This patch introduces new callbacks for setting
> and getting vring state.
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user/vhost.h        |   3 +
>  drivers/net/virtio/virtio_user/vhost_kernel.c |  49 +++++++-
>  drivers/net/virtio/virtio_user/vhost_user.c   | 113 +++++++++++++-----
>  drivers/net/virtio/virtio_user/vhost_vdpa.c   |  41 +++++--
>  .../net/virtio/virtio_user/virtio_user_dev.c  |   9 +-
>  5 files changed, 165 insertions(+), 50 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/vhost.h
> b/drivers/net/virtio/virtio_user/vhost.h
> index 463801f563..2d433d5966 100644
> --- a/drivers/net/virtio/virtio_user/vhost.h
> +++ b/drivers/net/virtio/virtio_user/vhost.h
> @@ -115,6 +115,9 @@ struct virtio_user_backend_ops {
>  	int (*get_protocol_features)(struct virtio_user_dev *dev, uint64_t
> *features);
>  	int (*set_protocol_features)(struct virtio_user_dev *dev, uint64_t
> features);
>  	int (*set_memory_table)(struct virtio_user_dev *dev);
> +	int (*set_vring_num)(struct virtio_user_dev *dev, struct
> vhost_vring_state *state);
> +	int (*set_vring_base)(struct virtio_user_dev *dev, struct
> vhost_vring_state *state);
> +	int (*get_vring_base)(struct virtio_user_dev *dev, struct
> vhost_vring_state *state);
>  	int (*send_request)(struct virtio_user_dev *dev,
>  			    enum vhost_user_request req,
>  			    void *arg);
> diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c
> b/drivers/net/virtio/virtio_user/vhost_kernel.c
> index 2d30f572b6..e12fe74f46 100644
> --- a/drivers/net/virtio/virtio_user/vhost_kernel.c
> +++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
> @@ -219,12 +219,49 @@ vhost_kernel_set_memory_table(struct virtio_user_dev
> *dev)
>  	return -1;
>  }
> 
> +static int
> +vhost_kernel_set_vring(struct virtio_user_dev *dev, uint64_t req, struct
> vhost_vring_state *state)
> +{
> +	int ret, fd;
> +	unsigned int index = state->index;
> +
> +	/* Convert from queue index to queue-pair & offset */
> +	fd = dev->vhostfds[state->index / 2];
> +	state->index %= 2;
> +
> +	ret = vhost_kernel_ioctl(fd, req, state);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Failed to set vring (request %" PRIu64 ")", req);
> +		return -1;
> +	}
> +
> +	/* restore index back to queue index */
> +	state->index = index;
> +
> +	return 0;
> +}
> +
> +static int
> +vhost_kernel_set_vring_num(struct virtio_user_dev *dev, struct
> vhost_vring_state *state)
> +{
> +	return vhost_kernel_set_vring(dev, VHOST_SET_VRING_NUM, state);
> +}
> +
> +static int
> +vhost_kernel_set_vring_base(struct virtio_user_dev *dev, struct
> vhost_vring_state *state)
> +{
> +	return vhost_kernel_set_vring(dev, VHOST_SET_VRING_BASE, state);
> +}
> +
> +static int
> +vhost_kernel_get_vring_base(struct virtio_user_dev *dev, struct
> vhost_vring_state *state)
> +{
> +	return vhost_kernel_set_vring(dev, VHOST_GET_VRING_BASE, state);
> +}
> +
>  static uint64_t vhost_req_user_to_kernel[] = {
>  	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
>  	[VHOST_USER_SET_VRING_CALL] = VHOST_SET_VRING_CALL,
> -	[VHOST_USER_SET_VRING_NUM] = VHOST_SET_VRING_NUM,
> -	[VHOST_USER_SET_VRING_BASE] = VHOST_SET_VRING_BASE,
> -	[VHOST_USER_GET_VRING_BASE] = VHOST_GET_VRING_BASE,
>  	[VHOST_USER_SET_VRING_ADDR] = VHOST_SET_VRING_ADDR,
>  	[VHOST_USER_SET_VRING_KICK] = VHOST_SET_VRING_KICK,
>  };
> @@ -245,10 +282,7 @@ vhost_kernel_send_request(struct virtio_user_dev *dev,
>  	req_kernel = vhost_req_user_to_kernel[req];
> 
>  	switch (req_kernel) {
> -	case VHOST_SET_VRING_NUM:
>  	case VHOST_SET_VRING_ADDR:
> -	case VHOST_SET_VRING_BASE:
> -	case VHOST_GET_VRING_BASE:
>  	case VHOST_SET_VRING_KICK:
>  	case VHOST_SET_VRING_CALL:
>  		queue_sel = *(unsigned int *)arg;
> @@ -403,6 +437,9 @@ struct virtio_user_backend_ops virtio_ops_kernel = {
>  	.get_features = vhost_kernel_get_features,
>  	.set_features = vhost_kernel_set_features,
>  	.set_memory_table = vhost_kernel_set_memory_table,
> +	.set_vring_num = vhost_kernel_set_vring_num,
> +	.set_vring_base = vhost_kernel_set_vring_base,
> +	.get_vring_base = vhost_kernel_get_vring_base,
>  	.send_request = vhost_kernel_send_request,
>  	.enable_qp = vhost_kernel_enable_queue_pair
>  };
> diff --git a/drivers/net/virtio/virtio_user/vhost_user.c
> b/drivers/net/virtio/virtio_user/vhost_user.c
> index 94533e31ce..c39be24ce4 100644
> --- a/drivers/net/virtio/virtio_user/vhost_user.c
> +++ b/drivers/net/virtio/virtio_user/vhost_user.c
> @@ -417,17 +417,94 @@ vhost_user_set_memory_table(struct virtio_user_dev *dev)
>  	return -1;
>  }
> 
> +static int
> +vhost_user_set_vring(struct virtio_user_dev *dev, enum vhost_user_request req,
> +		struct vhost_vring_state *state)
> +{
> +	int ret;
> +	struct vhost_user_msg msg = {
> +		.request = req,
> +		.flags = VHOST_USER_VERSION,
> +		.size = sizeof(*state),
> +		.payload.state = *state,
> +	};
> +
> +	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Failed to set vring state (request %d)", req);
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +vhost_user_set_vring_enable(struct virtio_user_dev *dev, struct
> vhost_vring_state *state)
> +{
> +	return vhost_user_set_vring(dev, VHOST_USER_SET_VRING_ENABLE, state);
> +}
> +
> +static int
> +vhost_user_set_vring_num(struct virtio_user_dev *dev, struct
> vhost_vring_state *state)
> +{
> +	return vhost_user_set_vring(dev, VHOST_USER_SET_VRING_NUM, state);
> +}
> +
> +static int
> +vhost_user_set_vring_base(struct virtio_user_dev *dev, struct
> vhost_vring_state *state)
> +{
> +	return vhost_user_set_vring(dev, VHOST_USER_SET_VRING_BASE, state);
> +}
> +
> +static int
> +vhost_user_get_vring_base(struct virtio_user_dev *dev, struct
> vhost_vring_state *state)
> +{
> +	int ret;
> +	struct vhost_user_msg msg;
> +	unsigned int index = state->index;
> +
> +	ret = vhost_user_set_vring(dev, VHOST_USER_GET_VRING_BASE, state);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Failed to send request");
> +		goto err;
> +	}
> +
> +	ret = vhost_user_read(dev->vhostfd, &msg);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Failed to read reply");
> +		goto err;
> +	}
> +
> +	if (msg.request != VHOST_USER_GET_VRING_BASE) {
> +		PMD_DRV_LOG(ERR, "Unexpected request type (%d)", msg.request);
> +		goto err;
> +	}
> +
> +	if (msg.size != sizeof(*state)) {
> +		PMD_DRV_LOG(ERR, "Unexpected payload size (%u)", msg.size);
> +		goto err;
> +	}
> +
> +	if (msg.payload.state.index != index) {
> +		PMD_DRV_LOG(ERR, "Unexpected ring index (%u)", state->index);
> +		goto err;
> +	}
> +
> +	*state = msg.payload.state;
> +
> +	return 0;
> +err:
> +	PMD_DRV_LOG(ERR, "Failed to get vring base");
> +	return -1;
> +}
> +
>  static struct vhost_user_msg m;
> 
>  const char * const vhost_msg_strings[] = {
>  	[VHOST_USER_RESET_OWNER] = "VHOST_RESET_OWNER",
>  	[VHOST_USER_SET_VRING_CALL] = "VHOST_SET_VRING_CALL",
> -	[VHOST_USER_SET_VRING_NUM] = "VHOST_SET_VRING_NUM",
> -	[VHOST_USER_SET_VRING_BASE] = "VHOST_SET_VRING_BASE",
> -	[VHOST_USER_GET_VRING_BASE] = "VHOST_GET_VRING_BASE",
>  	[VHOST_USER_SET_VRING_ADDR] = "VHOST_SET_VRING_ADDR",
>  	[VHOST_USER_SET_VRING_KICK] = "VHOST_SET_VRING_KICK",
> -	[VHOST_USER_SET_VRING_ENABLE] = "VHOST_SET_VRING_ENABLE",
>  	[VHOST_USER_SET_STATUS] = "VHOST_SET_STATUS",
>  	[VHOST_USER_GET_STATUS] = "VHOST_GET_STATUS",
>  };
> @@ -495,19 +572,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
>  		fds[fd_num++] = *((int *)arg);
>  		break;
> 
> -	case VHOST_USER_SET_VRING_NUM:
> -	case VHOST_USER_SET_VRING_BASE:
> -	case VHOST_USER_SET_VRING_ENABLE:
> -		memcpy(&msg.payload.state, arg, sizeof(msg.payload.state));
> -		msg.size = sizeof(m.payload.state);
> -		break;
> -
> -	case VHOST_USER_GET_VRING_BASE:
> -		memcpy(&msg.payload.state, arg, sizeof(msg.payload.state));
> -		msg.size = sizeof(m.payload.state);
> -		need_reply = 1;
> -		break;
> -
>  	case VHOST_USER_SET_VRING_ADDR:
>  		memcpy(&msg.payload.addr, arg, sizeof(msg.payload.addr));
>  		msg.size = sizeof(m.payload.addr);
> @@ -556,14 +620,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
>  			}
>  			*((__u64 *)arg) = msg.payload.u64;
>  			break;
> -		case VHOST_USER_GET_VRING_BASE:
> -			if (msg.size != sizeof(m.payload.state)) {
> -				PMD_DRV_LOG(ERR, "Received bad msg size");
> -				return -1;
> -			}
> -			memcpy(arg, &msg.payload.state,
> -			       sizeof(struct vhost_vring_state));
> -			break;
>  		default:
>  			/* Reply-ack handling */
>  			if (msg.size != sizeof(m.payload.u64)) {
> @@ -671,10 +727,10 @@ vhost_user_enable_queue_pair(struct virtio_user_dev *dev,
>  	for (i = 0; i < 2; ++i) {
>  		struct vhost_vring_state state = {
>  			.index = pair_idx * 2 + i,
> -			.num   = enable,
> +			.num = enable,
>  		};
> 
> -		if (vhost_user_sock(dev, VHOST_USER_SET_VRING_ENABLE, &state))
> +		if (vhost_user_set_vring_enable(dev, &state))
>  			return -1;
>  	}
> 
> @@ -690,6 +746,9 @@ struct virtio_user_backend_ops virtio_ops_user = {
>  	.get_protocol_features = vhost_user_get_protocol_features,
>  	.set_protocol_features = vhost_user_set_protocol_features,
>  	.set_memory_table = vhost_user_set_memory_table,
> +	.set_vring_num = vhost_user_set_vring_num,
> +	.set_vring_base = vhost_user_set_vring_base,
> +	.get_vring_base = vhost_user_get_vring_base,
>  	.send_request = vhost_user_sock,
>  	.enable_qp = vhost_user_enable_queue_pair
>  };
> diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> index bd7daebf0c..323751093a 100644
> --- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> +++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> @@ -32,24 +32,17 @@
>  #define VHOST_VDPA_GET_DEVICE_ID _IOR(VHOST_VIRTIO, 0x70, __u32)
>  #define VHOST_VDPA_GET_STATUS _IOR(VHOST_VIRTIO, 0x71, __u8)
>  #define VHOST_VDPA_SET_STATUS _IOW(VHOST_VIRTIO, 0x72, __u8)
> -#define VHOST_VDPA_SET_VRING_ENABLE	_IOW(VHOST_VIRTIO, 0x75, \
> -					     struct vhost_vring_state)
> +#define VHOST_VDPA_SET_VRING_ENABLE _IOW(VHOST_VIRTIO, 0x75, struct
> vhost_vring_state)
>  #define VHOST_SET_BACKEND_FEATURES _IOW(VHOST_VIRTIO, 0x25, __u64)
>  #define VHOST_GET_BACKEND_FEATURES _IOR(VHOST_VIRTIO, 0x26, __u64)
> 
>  static uint64_t vhost_req_user_to_vdpa[] = {
>  	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
>  	[VHOST_USER_SET_VRING_CALL] = VHOST_SET_VRING_CALL,
> -	[VHOST_USER_SET_VRING_NUM] = VHOST_SET_VRING_NUM,
> -	[VHOST_USER_SET_VRING_BASE] = VHOST_SET_VRING_BASE,
> -	[VHOST_USER_GET_VRING_BASE] = VHOST_GET_VRING_BASE,
>  	[VHOST_USER_SET_VRING_ADDR] = VHOST_SET_VRING_ADDR,
>  	[VHOST_USER_SET_VRING_KICK] = VHOST_SET_VRING_KICK,
>  	[VHOST_USER_SET_STATUS] = VHOST_VDPA_SET_STATUS,
>  	[VHOST_USER_GET_STATUS] = VHOST_VDPA_GET_STATUS,
> -	[VHOST_USER_SET_VRING_ENABLE] = VHOST_VDPA_SET_VRING_ENABLE,
> -	[VHOST_USER_GET_PROTOCOL_FEATURES] = VHOST_GET_BACKEND_FEATURES,
> -	[VHOST_USER_SET_PROTOCOL_FEATURES] = VHOST_SET_BACKEND_FEATURES,
>  };
> 
>  /* no alignment requirement */
> @@ -347,6 +340,30 @@ vhost_vdpa_set_memory_table(struct virtio_user_dev *dev)
>  	return ret;
>  }
> 
> +static int
> +vhost_vdpa_set_vring_enable(struct virtio_user_dev *dev, struct
> vhost_vring_state *state)
> +{
> +	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_VDPA_SET_VRING_ENABLE,
> state);
> +}
> +
> +static int
> +vhost_vdpa_set_vring_num(struct virtio_user_dev *dev, struct
> vhost_vring_state *state)
> +{
> +	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_NUM, state);
> +}
> +
> +static int
> +vhost_vdpa_set_vring_base(struct virtio_user_dev *dev, struct
> vhost_vring_state *state)
> +{
> +	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_BASE, state);
> +}
> +
> +static int
> +vhost_vdpa_get_vring_base(struct virtio_user_dev *dev, struct
> vhost_vring_state *state)
> +{
> +	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_GET_VRING_BASE, state);
> +}
> +
>  /* with below features, vhost vdpa does not need to do the checksum and TSO,
>   * these info will be passed to virtio_user through virtio net header.
>   */
> @@ -375,10 +392,7 @@ vhost_vdpa_send_request(struct virtio_user_dev *dev,
>  	req_vdpa = vhost_req_user_to_vdpa[req];
> 
>  	switch (req_vdpa) {
> -	case VHOST_SET_VRING_NUM:
>  	case VHOST_SET_VRING_ADDR:
> -	case VHOST_SET_VRING_BASE:
> -	case VHOST_GET_VRING_BASE:
>  	case VHOST_SET_VRING_KICK:
>  	case VHOST_SET_VRING_CALL:
>  		PMD_DRV_LOG(DEBUG, "vhostfd=%d, index=%u",
> @@ -440,7 +454,7 @@ vhost_vdpa_enable_queue_pair(struct virtio_user_dev *dev,
>  			.num   = enable,
>  		};
> 
> -		if (vhost_vdpa_send_request(dev, VHOST_USER_SET_VRING_ENABLE,
> &state))
> +		if (vhost_vdpa_set_vring_enable(dev, &state))
>  			return -1;
>  	}
> 
> @@ -457,6 +471,9 @@ struct virtio_user_backend_ops virtio_ops_vdpa = {
>  	.get_protocol_features = vhost_vdpa_get_backend_features,
>  	.set_protocol_features = vhost_vdpa_set_backend_features,
>  	.set_memory_table = vhost_vdpa_set_memory_table,
> +	.set_vring_num = vhost_vdpa_set_vring_num,
> +	.set_vring_base = vhost_vdpa_set_vring_base,
> +	.get_vring_base = vhost_vdpa_get_vring_base,
>  	.send_request = vhost_vdpa_send_request,
>  	.enable_qp = vhost_vdpa_enable_queue_pair,
>  	.dma_map = vhost_vdpa_dma_map_batch,
> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> index cb8f8a872c..0b30c10016 100644
> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> @@ -73,13 +73,13 @@ virtio_user_kick_queue(struct virtio_user_dev *dev,
> uint32_t queue_sel)
> 
>  	state.index = queue_sel;
>  	state.num = vring->num;
> -	dev->ops->send_request(dev, VHOST_USER_SET_VRING_NUM, &state);
> +	dev->ops->set_vring_num(dev, &state);
> 
>  	state.index = queue_sel;
>  	state.num = 0; /* no reservation */
>  	if (dev->features & (1ULL << VIRTIO_F_RING_PACKED))
>  		state.num |= (1 << 15);
> -	dev->ops->send_request(dev, VHOST_USER_SET_VRING_BASE, &state);
> +	dev->ops->set_vring_base(dev, &state);
> 
>  	dev->ops->send_request(dev, VHOST_USER_SET_VRING_ADDR, &addr);
> 
> @@ -218,9 +218,8 @@ int virtio_user_stop_device(struct virtio_user_dev *dev)
>  	/* Stop the backend. */
>  	for (i = 0; i < dev->max_queue_pairs * 2; ++i) {
>  		state.index = i;
> -		if (dev->ops->send_request(dev, VHOST_USER_GET_VRING_BASE,
> -					   &state) < 0) {
> -			PMD_DRV_LOG(ERR, "get_vring_base failed, index=%u\n",
> +		if (dev->ops->get_vring_base(dev, &state) < 0) {
> +			PMD_DRV_LOG(ERR, "get_vring_base failed, index=%u",
>  				    i);
>  			error = -1;
>  			goto out;
> --
> 2.29.2

Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 31/44] net/virtio: add Virtio-user vring file ops
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 31/44] net/virtio: add Virtio-user vring file ops Maxime Coquelin
@ 2021-01-22  8:01   ` Xia, Chenbo
  0 siblings, 0 replies; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-22  8:01 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 31/44] net/virtio: add Virtio-user vring file ops
> 
> This patch introduces new callbacks for setting
> vring files (kick and call).
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user/vhost.h        |  2 +
>  drivers/net/virtio/virtio_user/vhost_kernel.c | 41 +++++++++++++++--
>  drivers/net/virtio/virtio_user/vhost_user.c   | 46 +++++++++++++++++--
>  drivers/net/virtio/virtio_user/vhost_vdpa.c   | 18 ++++++--
>  .../net/virtio/virtio_user/virtio_user_dev.c  |  4 +-
>  5 files changed, 97 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/vhost.h
> b/drivers/net/virtio/virtio_user/vhost.h
> index 2d433d5966..94c524547e 100644
> --- a/drivers/net/virtio/virtio_user/vhost.h
> +++ b/drivers/net/virtio/virtio_user/vhost.h
> @@ -118,6 +118,8 @@ struct virtio_user_backend_ops {
>  	int (*set_vring_num)(struct virtio_user_dev *dev, struct
> vhost_vring_state *state);
>  	int (*set_vring_base)(struct virtio_user_dev *dev, struct
> vhost_vring_state *state);
>  	int (*get_vring_base)(struct virtio_user_dev *dev, struct
> vhost_vring_state *state);
> +	int (*set_vring_call)(struct virtio_user_dev *dev, struct
> vhost_vring_file *file);
> +	int (*set_vring_kick)(struct virtio_user_dev *dev, struct
> vhost_vring_file *file);
>  	int (*send_request)(struct virtio_user_dev *dev,
>  			    enum vhost_user_request req,
>  			    void *arg);
> diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c
> b/drivers/net/virtio/virtio_user/vhost_kernel.c
> index e12fe74f46..dc5358bc15 100644
> --- a/drivers/net/virtio/virtio_user/vhost_kernel.c
> +++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
> @@ -259,11 +259,44 @@ vhost_kernel_get_vring_base(struct virtio_user_dev *dev,
> struct vhost_vring_stat
>  	return vhost_kernel_set_vring(dev, VHOST_GET_VRING_BASE, state);
>  }
> 
> +static int
> +vhost_kernel_set_vring_file(struct virtio_user_dev *dev, uint64_t req,
> +		struct vhost_vring_file *file)
> +{
> +	int ret, fd;
> +	unsigned int index = file->index;
> +
> +	/* Convert from queue index to queue-pair & offset */
> +	fd = dev->vhostfds[file->index / 2];
> +	file->index %= 2;
> +
> +	ret = vhost_kernel_ioctl(fd, req, file);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Failed to set vring file (request %" PRIu64 ")",
> req);
> +		return -1;
> +	}
> +
> +	/* restore index back to queue index */
> +	file->index = index;
> +
> +	return 0;
> +}
> +
> +static int
> +vhost_kernel_set_vring_kick(struct virtio_user_dev *dev, struct
> vhost_vring_file *file)
> +{
> +	return vhost_kernel_set_vring_file(dev, VHOST_SET_VRING_KICK, file);
> +}
> +
> +static int
> +vhost_kernel_set_vring_call(struct virtio_user_dev *dev, struct
> vhost_vring_file *file)
> +{
> +	return vhost_kernel_set_vring_file(dev, VHOST_SET_VRING_CALL, file);
> +}
> +
>  static uint64_t vhost_req_user_to_kernel[] = {
>  	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
> -	[VHOST_USER_SET_VRING_CALL] = VHOST_SET_VRING_CALL,
>  	[VHOST_USER_SET_VRING_ADDR] = VHOST_SET_VRING_ADDR,
> -	[VHOST_USER_SET_VRING_KICK] = VHOST_SET_VRING_KICK,
>  };
> 
>  static int
> @@ -283,8 +316,6 @@ vhost_kernel_send_request(struct virtio_user_dev *dev,
> 
>  	switch (req_kernel) {
>  	case VHOST_SET_VRING_ADDR:
> -	case VHOST_SET_VRING_KICK:
> -	case VHOST_SET_VRING_CALL:
>  		queue_sel = *(unsigned int *)arg;
>  		vhostfd = dev->vhostfds[queue_sel / 2];
>  		*(unsigned int *)arg = queue_sel % 2;
> @@ -440,6 +471,8 @@ struct virtio_user_backend_ops virtio_ops_kernel = {
>  	.set_vring_num = vhost_kernel_set_vring_num,
>  	.set_vring_base = vhost_kernel_set_vring_base,
>  	.get_vring_base = vhost_kernel_get_vring_base,
> +	.set_vring_call = vhost_kernel_set_vring_call,
> +	.set_vring_kick = vhost_kernel_set_vring_kick,
>  	.send_request = vhost_kernel_send_request,
>  	.enable_qp = vhost_kernel_enable_queue_pair
>  };
> diff --git a/drivers/net/virtio/virtio_user/vhost_user.c
> b/drivers/net/virtio/virtio_user/vhost_user.c
> index c39be24ce4..06d17cadcb 100644
> --- a/drivers/net/virtio/virtio_user/vhost_user.c
> +++ b/drivers/net/virtio/virtio_user/vhost_user.c
> @@ -498,13 +498,51 @@ vhost_user_get_vring_base(struct virtio_user_dev *dev,
> struct vhost_vring_state
>  	return -1;
>  }
> 
> +static int
> +vhost_user_set_vring_file(struct virtio_user_dev *dev, enum
> vhost_user_request req,
> +		struct vhost_vring_file *file)
> +{
> +	int ret;
> +	int fd = file->fd;
> +	int num_fd = 0;
> +	struct vhost_user_msg msg = {
> +		.request = req,
> +		.flags = VHOST_USER_VERSION,
> +		.size = sizeof(msg.payload.u64),
> +		.payload.u64 = file->index & VHOST_USER_VRING_IDX_MASK,
> +	};
> +
> +	if (fd >= 0)
> +		num_fd++;
> +	else
> +		msg.payload.u64 |= VHOST_USER_VRING_NOFD_MASK;
> +
> +	ret = vhost_user_write(dev->vhostfd, &msg, &fd, num_fd);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Failed to set vring file (request %d)", req);
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +vhost_user_set_vring_call(struct virtio_user_dev *dev, struct
> vhost_vring_file *file)
> +{
> +	return vhost_user_set_vring_file(dev, VHOST_USER_SET_VRING_CALL, file);
> +}
> +
> +static int
> +vhost_user_set_vring_kick(struct virtio_user_dev *dev, struct
> vhost_vring_file *file)
> +{
> +	return vhost_user_set_vring_file(dev, VHOST_USER_SET_VRING_KICK, file);
> +}
> +
>  static struct vhost_user_msg m;
> 
>  const char * const vhost_msg_strings[] = {
>  	[VHOST_USER_RESET_OWNER] = "VHOST_RESET_OWNER",
> -	[VHOST_USER_SET_VRING_CALL] = "VHOST_SET_VRING_CALL",
>  	[VHOST_USER_SET_VRING_ADDR] = "VHOST_SET_VRING_ADDR",
> -	[VHOST_USER_SET_VRING_KICK] = "VHOST_SET_VRING_KICK",
>  	[VHOST_USER_SET_STATUS] = "VHOST_SET_STATUS",
>  	[VHOST_USER_GET_STATUS] = "VHOST_GET_STATUS",
>  };
> @@ -577,8 +615,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
>  		msg.size = sizeof(m.payload.addr);
>  		break;
> 
> -	case VHOST_USER_SET_VRING_KICK:
> -	case VHOST_USER_SET_VRING_CALL:
>  	case VHOST_USER_SET_VRING_ERR:
>  		file = arg;
>  		msg.payload.u64 = file->index & VHOST_USER_VRING_IDX_MASK;
> @@ -749,6 +785,8 @@ struct virtio_user_backend_ops virtio_ops_user = {
>  	.set_vring_num = vhost_user_set_vring_num,
>  	.set_vring_base = vhost_user_set_vring_base,
>  	.get_vring_base = vhost_user_get_vring_base,
> +	.set_vring_call = vhost_user_set_vring_call,
> +	.set_vring_kick = vhost_user_set_vring_kick,
>  	.send_request = vhost_user_sock,
>  	.enable_qp = vhost_user_enable_queue_pair
>  };
> diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> index 323751093a..304a808b55 100644
> --- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> +++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> @@ -38,9 +38,7 @@
> 
>  static uint64_t vhost_req_user_to_vdpa[] = {
>  	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
> -	[VHOST_USER_SET_VRING_CALL] = VHOST_SET_VRING_CALL,
>  	[VHOST_USER_SET_VRING_ADDR] = VHOST_SET_VRING_ADDR,
> -	[VHOST_USER_SET_VRING_KICK] = VHOST_SET_VRING_KICK,
>  	[VHOST_USER_SET_STATUS] = VHOST_VDPA_SET_STATUS,
>  	[VHOST_USER_GET_STATUS] = VHOST_VDPA_GET_STATUS,
>  };
> @@ -364,6 +362,18 @@ vhost_vdpa_get_vring_base(struct virtio_user_dev *dev,
> struct vhost_vring_state
>  	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_GET_VRING_BASE, state);
>  }
> 
> +static int
> +vhost_vdpa_set_vring_call(struct virtio_user_dev *dev, struct
> vhost_vring_file *file)
> +{
> +	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_CALL, file);
> +}
> +
> +static int
> +vhost_vdpa_set_vring_kick(struct virtio_user_dev *dev, struct
> vhost_vring_file *file)
> +{
> +	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_KICK, file);
> +}
> +
>  /* with below features, vhost vdpa does not need to do the checksum and TSO,
>   * these info will be passed to virtio_user through virtio net header.
>   */
> @@ -393,8 +403,6 @@ vhost_vdpa_send_request(struct virtio_user_dev *dev,
> 
>  	switch (req_vdpa) {
>  	case VHOST_SET_VRING_ADDR:
> -	case VHOST_SET_VRING_KICK:
> -	case VHOST_SET_VRING_CALL:
>  		PMD_DRV_LOG(DEBUG, "vhostfd=%d, index=%u",
>  			    dev->vhostfd, *(unsigned int *)arg);
>  		break;
> @@ -474,6 +482,8 @@ struct virtio_user_backend_ops virtio_ops_vdpa = {
>  	.set_vring_num = vhost_vdpa_set_vring_num,
>  	.set_vring_base = vhost_vdpa_set_vring_base,
>  	.get_vring_base = vhost_vdpa_get_vring_base,
> +	.set_vring_call = vhost_vdpa_set_vring_call,
> +	.set_vring_kick = vhost_vdpa_set_vring_kick,
>  	.send_request = vhost_vdpa_send_request,
>  	.enable_qp = vhost_vdpa_enable_queue_pair,
>  	.dma_map = vhost_vdpa_dma_map_batch,
> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> index 0b30c10016..4383e403da 100644
> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> @@ -40,7 +40,7 @@ virtio_user_create_queue(struct virtio_user_dev *dev,
> uint32_t queue_sel)
> 
>  	file.index = queue_sel;
>  	file.fd = dev->callfds[queue_sel];
> -	dev->ops->send_request(dev, VHOST_USER_SET_VRING_CALL, &file);
> +	dev->ops->set_vring_call(dev, &file);
> 
>  	return 0;
>  }
> @@ -89,7 +89,7 @@ virtio_user_kick_queue(struct virtio_user_dev *dev, uint32_t
> queue_sel)
>  	 */
>  	file.index = queue_sel;
>  	file.fd = dev->kickfds[queue_sel];
> -	dev->ops->send_request(dev, VHOST_USER_SET_VRING_KICK, &file);
> +	dev->ops->set_vring_kick(dev, &file);
> 
>  	return 0;
>  }
> --
> 2.29.2

Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 32/44] net/virtio: add Virtio-user vring address ops
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 32/44] net/virtio: add Virtio-user vring address ops Maxime Coquelin
@ 2021-01-22  8:02   ` Xia, Chenbo
  0 siblings, 0 replies; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-22  8:02 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 32/44] net/virtio: add Virtio-user vring address ops
> 
> This patch introduces a new callback for setting
> vrings addresses.
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user/vhost.h        |  1 +
>  drivers/net/virtio/virtio_user/vhost_kernel.c | 32 +++++++++++++------
>  drivers/net/virtio/virtio_user/vhost_user.c   | 29 +++++++++++++----
>  drivers/net/virtio/virtio_user/vhost_vdpa.c   |  8 ++++-
>  .../net/virtio/virtio_user/virtio_user_dev.c  |  2 +-
>  5 files changed, 55 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/vhost.h
> b/drivers/net/virtio/virtio_user/vhost.h
> index 94c524547e..19040dfdc2 100644
> --- a/drivers/net/virtio/virtio_user/vhost.h
> +++ b/drivers/net/virtio/virtio_user/vhost.h
> @@ -120,6 +120,7 @@ struct virtio_user_backend_ops {
>  	int (*get_vring_base)(struct virtio_user_dev *dev, struct
> vhost_vring_state *state);
>  	int (*set_vring_call)(struct virtio_user_dev *dev, struct
> vhost_vring_file *file);
>  	int (*set_vring_kick)(struct virtio_user_dev *dev, struct
> vhost_vring_file *file);
> +	int (*set_vring_addr)(struct virtio_user_dev *dev, struct
> vhost_vring_addr *addr);
>  	int (*send_request)(struct virtio_user_dev *dev,
>  			    enum vhost_user_request req,
>  			    void *arg);
> diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c
> b/drivers/net/virtio/virtio_user/vhost_kernel.c
> index dc5358bc15..566f42f0cb 100644
> --- a/drivers/net/virtio/virtio_user/vhost_kernel.c
> +++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
> @@ -294,9 +294,30 @@ vhost_kernel_set_vring_call(struct virtio_user_dev *dev,
> struct vhost_vring_file
>  	return vhost_kernel_set_vring_file(dev, VHOST_SET_VRING_CALL, file);
>  }
> 
> +static int
> +vhost_kernel_set_vring_addr(struct virtio_user_dev *dev, struct
> vhost_vring_addr *addr)
> +{
> +	int ret, fd;
> +	unsigned int index = addr->index;
> +
> +	/* Convert from queue index to queue-pair & offset */
> +	fd = dev->vhostfds[addr->index / 2];
> +	addr->index %= 2;
> +
> +	ret = vhost_kernel_ioctl(fd, VHOST_SET_VRING_ADDR, addr);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Failed to set vring address");
> +		return -1;
> +	}
> +
> +	/* restore index back to queue index */
> +	addr->index = index;
> +
> +	return 0;
> +}
> +
>  static uint64_t vhost_req_user_to_kernel[] = {
>  	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
> -	[VHOST_USER_SET_VRING_ADDR] = VHOST_SET_VRING_ADDR,
>  };
> 
>  static int
> @@ -308,20 +329,12 @@ vhost_kernel_send_request(struct virtio_user_dev *dev,
>  	unsigned int i;
>  	uint64_t req_kernel;
>  	int vhostfd;
> -	unsigned int queue_sel;
> 
>  	PMD_DRV_LOG(INFO, "%s", vhost_msg_strings[req]);
> 
>  	req_kernel = vhost_req_user_to_kernel[req];
> 
>  	switch (req_kernel) {
> -	case VHOST_SET_VRING_ADDR:
> -		queue_sel = *(unsigned int *)arg;
> -		vhostfd = dev->vhostfds[queue_sel / 2];
> -		*(unsigned int *)arg = queue_sel % 2;
> -		PMD_DRV_LOG(DEBUG, "vhostfd=%d, index=%u",
> -			    vhostfd, *(unsigned int *)arg);
> -		break;
>  	default:
>  		vhostfd = -1;
>  	}
> @@ -473,6 +486,7 @@ struct virtio_user_backend_ops virtio_ops_kernel = {
>  	.get_vring_base = vhost_kernel_get_vring_base,
>  	.set_vring_call = vhost_kernel_set_vring_call,
>  	.set_vring_kick = vhost_kernel_set_vring_kick,
> +	.set_vring_addr = vhost_kernel_set_vring_addr,
>  	.send_request = vhost_kernel_send_request,
>  	.enable_qp = vhost_kernel_enable_queue_pair
>  };
> diff --git a/drivers/net/virtio/virtio_user/vhost_user.c
> b/drivers/net/virtio/virtio_user/vhost_user.c
> index 06d17cadcb..ca70a8a4e7 100644
> --- a/drivers/net/virtio/virtio_user/vhost_user.c
> +++ b/drivers/net/virtio/virtio_user/vhost_user.c
> @@ -538,11 +538,32 @@ vhost_user_set_vring_kick(struct virtio_user_dev *dev,
> struct vhost_vring_file *
>  	return vhost_user_set_vring_file(dev, VHOST_USER_SET_VRING_KICK, file);
>  }
> 
> +
> +static int
> +vhost_user_set_vring_addr(struct virtio_user_dev *dev, struct
> vhost_vring_addr *addr)
> +{
> +	int ret;
> +	struct vhost_user_msg msg = {
> +		.request = VHOST_USER_SET_VRING_ADDR,
> +		.flags = VHOST_USER_VERSION,
> +		.size = sizeof(*addr),
> +		.payload.addr = *addr,
> +	};
> +
> +	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Failed to send vring addresses");
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +
>  static struct vhost_user_msg m;
> 
>  const char * const vhost_msg_strings[] = {
>  	[VHOST_USER_RESET_OWNER] = "VHOST_RESET_OWNER",
> -	[VHOST_USER_SET_VRING_ADDR] = "VHOST_SET_VRING_ADDR",
>  	[VHOST_USER_SET_STATUS] = "VHOST_SET_STATUS",
>  	[VHOST_USER_GET_STATUS] = "VHOST_GET_STATUS",
>  };
> @@ -610,11 +631,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
>  		fds[fd_num++] = *((int *)arg);
>  		break;
> 
> -	case VHOST_USER_SET_VRING_ADDR:
> -		memcpy(&msg.payload.addr, arg, sizeof(msg.payload.addr));
> -		msg.size = sizeof(m.payload.addr);
> -		break;
> -
>  	case VHOST_USER_SET_VRING_ERR:
>  		file = arg;
>  		msg.payload.u64 = file->index & VHOST_USER_VRING_IDX_MASK;
> @@ -787,6 +803,7 @@ struct virtio_user_backend_ops virtio_ops_user = {
>  	.get_vring_base = vhost_user_get_vring_base,
>  	.set_vring_call = vhost_user_set_vring_call,
>  	.set_vring_kick = vhost_user_set_vring_kick,
> +	.set_vring_addr = vhost_user_set_vring_addr,
>  	.send_request = vhost_user_sock,
>  	.enable_qp = vhost_user_enable_queue_pair
>  };
> diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> index 304a808b55..1ec6bb26f2 100644
> --- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> +++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> @@ -38,7 +38,6 @@
> 
>  static uint64_t vhost_req_user_to_vdpa[] = {
>  	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
> -	[VHOST_USER_SET_VRING_ADDR] = VHOST_SET_VRING_ADDR,
>  	[VHOST_USER_SET_STATUS] = VHOST_VDPA_SET_STATUS,
>  	[VHOST_USER_GET_STATUS] = VHOST_VDPA_GET_STATUS,
>  };
> @@ -374,6 +373,12 @@ vhost_vdpa_set_vring_kick(struct virtio_user_dev *dev,
> struct vhost_vring_file *
>  	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_KICK, file);
>  }
> 
> +static int
> +vhost_vdpa_set_vring_addr(struct virtio_user_dev *dev, struct
> vhost_vring_addr *addr)
> +{
> +	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_ADDR, addr);
> +}
> +
>  /* with below features, vhost vdpa does not need to do the checksum and TSO,
>   * these info will be passed to virtio_user through virtio net header.
>   */
> @@ -484,6 +489,7 @@ struct virtio_user_backend_ops virtio_ops_vdpa = {
>  	.get_vring_base = vhost_vdpa_get_vring_base,
>  	.set_vring_call = vhost_vdpa_set_vring_call,
>  	.set_vring_kick = vhost_vdpa_set_vring_kick,
> +	.set_vring_addr = vhost_vdpa_set_vring_addr,
>  	.send_request = vhost_vdpa_send_request,
>  	.enable_qp = vhost_vdpa_enable_queue_pair,
>  	.dma_map = vhost_vdpa_dma_map_batch,
> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> index 4383e403da..7e365d0570 100644
> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> @@ -81,7 +81,7 @@ virtio_user_kick_queue(struct virtio_user_dev *dev, uint32_t
> queue_sel)
>  		state.num |= (1 << 15);
>  	dev->ops->set_vring_base(dev, &state);
> 
> -	dev->ops->send_request(dev, VHOST_USER_SET_VRING_ADDR, &addr);
> +	dev->ops->set_vring_addr(dev, &addr);
> 
>  	/* Of all per virtqueue MSGs, make sure VHOST_USER_SET_VRING_KICK comes
>  	 * lastly because vhost depends on this msg to judge if
> --
> 2.29.2

Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 33/44] net/virtio: add Virtio-user status ops
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 33/44] net/virtio: add Virtio-user status ops Maxime Coquelin
@ 2021-01-22  8:02   ` Xia, Chenbo
  0 siblings, 0 replies; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-22  8:02 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 33/44] net/virtio: add Virtio-user status ops
> 
> This patch introduces new callbacks to
> get and set the device status.
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user/vhost.h        |   2 +
>  drivers/net/virtio/virtio_user/vhost_kernel.c |  14 ++
>  drivers/net/virtio/virtio_user/vhost_user.c   | 121 +++++++++++++-----
>  drivers/net/virtio/virtio_user/vhost_vdpa.c   |  16 ++-
>  .../net/virtio/virtio_user/virtio_user_dev.c  |  42 ++----
>  5 files changed, 129 insertions(+), 66 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/vhost.h
> b/drivers/net/virtio/virtio_user/vhost.h
> index 19040dfdc2..c896f0836d 100644
> --- a/drivers/net/virtio/virtio_user/vhost.h
> +++ b/drivers/net/virtio/virtio_user/vhost.h
> @@ -121,6 +121,8 @@ struct virtio_user_backend_ops {
>  	int (*set_vring_call)(struct virtio_user_dev *dev, struct
> vhost_vring_file *file);
>  	int (*set_vring_kick)(struct virtio_user_dev *dev, struct
> vhost_vring_file *file);
>  	int (*set_vring_addr)(struct virtio_user_dev *dev, struct
> vhost_vring_addr *addr);
> +	int (*get_status)(struct virtio_user_dev *dev, uint8_t *status);
> +	int (*set_status)(struct virtio_user_dev *dev, uint8_t status);
>  	int (*send_request)(struct virtio_user_dev *dev,
>  			    enum vhost_user_request req,
>  			    void *arg);
> diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c
> b/drivers/net/virtio/virtio_user/vhost_kernel.c
> index 566f42f0cb..d85358fc34 100644
> --- a/drivers/net/virtio/virtio_user/vhost_kernel.c
> +++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
> @@ -316,6 +316,18 @@ vhost_kernel_set_vring_addr(struct virtio_user_dev *dev,
> struct vhost_vring_addr
>  	return 0;
>  }
> 
> +static int
> +vhost_kernel_get_status(struct virtio_user_dev *dev __rte_unused, uint8_t
> *status __rte_unused)
> +{
> +	return -ENOTSUP;
> +}
> +
> +static int
> +vhost_kernel_set_status(struct virtio_user_dev *dev __rte_unused, uint8_t
> status __rte_unused)
> +{
> +	return -ENOTSUP;
> +}
> +
>  static uint64_t vhost_req_user_to_kernel[] = {
>  	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
>  };
> @@ -487,6 +499,8 @@ struct virtio_user_backend_ops virtio_ops_kernel = {
>  	.set_vring_call = vhost_kernel_set_vring_call,
>  	.set_vring_kick = vhost_kernel_set_vring_kick,
>  	.set_vring_addr = vhost_kernel_set_vring_addr,
> +	.get_status = vhost_kernel_get_status,
> +	.set_status = vhost_kernel_set_status,
>  	.send_request = vhost_kernel_send_request,
>  	.enable_qp = vhost_kernel_enable_queue_pair
>  };
> diff --git a/drivers/net/virtio/virtio_user/vhost_user.c
> b/drivers/net/virtio/virtio_user/vhost_user.c
> index ca70a8a4e7..cb0cd1cea8 100644
> --- a/drivers/net/virtio/virtio_user/vhost_user.c
> +++ b/drivers/net/virtio/virtio_user/vhost_user.c
> @@ -559,13 +559,100 @@ vhost_user_set_vring_addr(struct virtio_user_dev *dev,
> struct vhost_vring_addr *
>  	return 0;
>  }
> 
> +static int
> +vhost_user_get_status(struct virtio_user_dev *dev, uint8_t *status)
> +{
> +	int ret;
> +	struct vhost_user_msg msg = {
> +		.request = VHOST_USER_GET_STATUS,
> +		.flags = VHOST_USER_VERSION,
> +	};
> +
> +	/*
> +	 * If features have not been negotiated, we don't know if the backend
> +	 * supports protocol features
> +	 */
> +	if (!(dev->status & VIRTIO_CONFIG_STATUS_FEATURES_OK))
> +		return -ENOTSUP;
> +
> +	/* Status protocol feature requires protocol features support */
> +	if (!(dev->device_features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)))
> +		return -ENOTSUP;
> +
> +	if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_STATUS)))
> +		return -ENOTSUP;
> +
> +	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Failed to send request");
> +		goto err;
> +	}
> +
> +	ret = vhost_user_read(dev->vhostfd, &msg);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Failed to recv request");
> +		goto err;
> +	}
> +
> +	if (msg.request != VHOST_USER_GET_STATUS) {
> +		PMD_DRV_LOG(ERR, "Unexpected request type (%d)", msg.request);
> +		goto err;
> +	}
> +
> +	if (msg.size != sizeof(msg.payload.u64)) {
> +		PMD_DRV_LOG(ERR, "Unexpected payload size (%u)", msg.size);
> +		goto err;
> +	}
> +
> +	*status = (uint8_t)msg.payload.u64;
> +
> +	return 0;
> +err:
> +	PMD_DRV_LOG(ERR, "Failed to get device status");
> +	return -1;
> +}
> +
> +static int
> +vhost_user_set_status(struct virtio_user_dev *dev, uint8_t status)
> +{
> +	int ret;
> +	struct vhost_user_msg msg = {
> +		.request = VHOST_USER_SET_STATUS,
> +		.flags = VHOST_USER_VERSION,
> +		.size = sizeof(msg.payload.u64),
> +		.payload.u64 = status,
> +	};
> +
> +	/*
> +	 * If features have not been negotiated, we don't know if the backend
> +	 * supports protocol features
> +	 */
> +	if (!(dev->status & VIRTIO_CONFIG_STATUS_FEATURES_OK))
> +		return -ENOTSUP;
> +
> +	/* Status protocol feature requires protocol features support */
> +	if (!(dev->device_features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)))
> +		return -ENOTSUP;
> +
> +	if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_STATUS)))
> +		return -ENOTSUP;
> +
> +	if (dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK))
> +		msg.flags |= VHOST_USER_NEED_REPLY_MASK;
> +
> +	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Failed to send get status request");
> +		return -1;
> +	}
> +
> +	return vhost_user_check_reply_ack(dev, &msg);
> +}
> 
>  static struct vhost_user_msg m;
> 
>  const char * const vhost_msg_strings[] = {
>  	[VHOST_USER_RESET_OWNER] = "VHOST_RESET_OWNER",
> -	[VHOST_USER_SET_STATUS] = "VHOST_SET_STATUS",
> -	[VHOST_USER_GET_STATUS] = "VHOST_GET_STATUS",
>  };
> 
>  static int
> @@ -576,7 +663,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
>  	struct vhost_user_msg msg;
>  	struct vhost_vring_file *file = 0;
>  	int need_reply = 0;
> -	int has_reply_ack = 0;
>  	int fds[VHOST_MEMORY_MAX_NREGIONS];
>  	int fd_num = 0;
>  	int vhostfd = dev->vhostfd;
> @@ -588,31 +674,11 @@ vhost_user_sock(struct virtio_user_dev *dev,
>  	if (dev->is_server && vhostfd < 0)
>  		return -1;
> 
> -	if (dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK))
> -		has_reply_ack = 1;
> -
>  	msg.request = req;
>  	msg.flags = VHOST_USER_VERSION;
>  	msg.size = 0;
> 
>  	switch (req) {
> -	case VHOST_USER_GET_STATUS:
> -		if (!(dev->status & VIRTIO_CONFIG_STATUS_FEATURES_OK) ||
> -		    (!(dev->protocol_features &
> -				(1ULL << VHOST_USER_PROTOCOL_F_STATUS))))
> -			return -ENOTSUP;
> -		need_reply = 1;
> -		break;
> -
> -	case VHOST_USER_SET_STATUS:
> -		if (!(dev->status & VIRTIO_CONFIG_STATUS_FEATURES_OK) ||
> -		    (!(dev->protocol_features &
> -				(1ULL << VHOST_USER_PROTOCOL_F_STATUS))))
> -			return -ENOTSUP;
> -
> -		if (has_reply_ack)
> -			msg.flags |= VHOST_USER_NEED_REPLY_MASK;
> -		/* Fallthrough */
>  	case VHOST_USER_SET_LOG_BASE:
>  		msg.payload.u64 = *((__u64 *)arg);
>  		msg.size = sizeof(m.payload.u64);
> @@ -665,13 +731,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
>  		}
> 
>  		switch (req) {
> -		case VHOST_USER_GET_STATUS:
> -			if (msg.size != sizeof(m.payload.u64)) {
> -				PMD_DRV_LOG(ERR, "Received bad msg size");
> -				return -1;
> -			}
> -			*((__u64 *)arg) = msg.payload.u64;
> -			break;
>  		default:
>  			/* Reply-ack handling */
>  			if (msg.size != sizeof(m.payload.u64)) {
> @@ -804,6 +863,8 @@ struct virtio_user_backend_ops virtio_ops_user = {
>  	.set_vring_call = vhost_user_set_vring_call,
>  	.set_vring_kick = vhost_user_set_vring_kick,
>  	.set_vring_addr = vhost_user_set_vring_addr,
> +	.get_status = vhost_user_get_status,
> +	.set_status = vhost_user_set_status,
>  	.send_request = vhost_user_sock,
>  	.enable_qp = vhost_user_enable_queue_pair
>  };
> diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> index 1ec6bb26f2..8ebc679f1b 100644
> --- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> +++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> @@ -38,8 +38,6 @@
> 
>  static uint64_t vhost_req_user_to_vdpa[] = {
>  	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
> -	[VHOST_USER_SET_STATUS] = VHOST_VDPA_SET_STATUS,
> -	[VHOST_USER_GET_STATUS] = VHOST_VDPA_GET_STATUS,
>  };
> 
>  /* no alignment requirement */
> @@ -379,6 +377,18 @@ vhost_vdpa_set_vring_addr(struct virtio_user_dev *dev,
> struct vhost_vring_addr *
>  	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_ADDR, addr);
>  }
> 
> +static int
> +vhost_vdpa_get_status(struct virtio_user_dev *dev, uint8_t *status)
> +{
> +	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_VDPA_GET_STATUS, status);
> +}
> +
> +static int
> +vhost_vdpa_set_status(struct virtio_user_dev *dev, uint8_t status)
> +{
> +	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_VDPA_SET_STATUS, &status);
> +}
> +
>  /* with below features, vhost vdpa does not need to do the checksum and TSO,
>   * these info will be passed to virtio_user through virtio net header.
>   */
> @@ -490,6 +500,8 @@ struct virtio_user_backend_ops virtio_ops_vdpa = {
>  	.set_vring_call = vhost_vdpa_set_vring_call,
>  	.set_vring_kick = vhost_vdpa_set_vring_kick,
>  	.set_vring_addr = vhost_vdpa_set_vring_addr,
> +	.get_status = vhost_vdpa_get_status,
> +	.set_status = vhost_vdpa_set_status,
>  	.send_request = vhost_vdpa_send_request,
>  	.enable_qp = vhost_vdpa_enable_queue_pair,
>  	.dma_map = vhost_vdpa_dma_map_batch,
> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> index 7e365d0570..33a25f4684 100644
> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> @@ -814,21 +814,12 @@ int
>  virtio_user_dev_set_status(struct virtio_user_dev *dev, uint8_t status)
>  {
>  	int ret;
> -	uint64_t arg = status;
> 
>  	pthread_mutex_lock(&dev->mutex);
>  	dev->status = status;
> -	if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER)
> -		ret = dev->ops->send_request(dev,
> -				VHOST_USER_SET_STATUS, &arg);
> -	else if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_VDPA)
> -		ret = dev->ops->send_request(dev,
> -				VHOST_USER_SET_STATUS, &status);
> -	else
> -		ret = -ENOTSUP;
> -
> +	ret = dev->ops->set_status(dev, status);
>  	if (ret && ret != -ENOTSUP) {
> -		PMD_INIT_LOG(ERR, "VHOST_USER_SET_STATUS failed (%d): %s", ret,
> +		PMD_INIT_LOG(ERR, "Virtio-user set status failed (%d): %s", ret,
>  			     strerror(errno));
>  	}
> 
> @@ -839,29 +830,13 @@ virtio_user_dev_set_status(struct virtio_user_dev *dev,
> uint8_t status)
>  int
>  virtio_user_dev_update_status(struct virtio_user_dev *dev)
>  {
> -	uint64_t ret;
> +	int ret;
>  	uint8_t status;
> -	int err;
> 
>  	pthread_mutex_lock(&dev->mutex);
> -	if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER) {
> -		err = dev->ops->send_request(dev, VHOST_USER_GET_STATUS, &ret);
> -		if (!err && ret > UINT8_MAX) {
> -			PMD_INIT_LOG(ERR, "Invalid VHOST_USER_GET_STATUS "
> -					"response 0x%" PRIx64 "\n", ret);
> -			err = -1;
> -			goto error;
> -		}
> 
> -		status = ret;
> -	} else if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_VDPA) {
> -		err = dev->ops->send_request(dev, VHOST_USER_GET_STATUS,
> -				&status);
> -	} else {
> -		err = -ENOTSUP;
> -	}
> -
> -	if (!err) {
> +	ret = dev->ops->get_status(dev, &status);
> +	if (!ret) {
>  		dev->status = status;
>  		PMD_INIT_LOG(DEBUG, "Updated Device Status(0x%08x):\n"
>  			"\t-RESET: %u\n"
> @@ -879,12 +854,11 @@ virtio_user_dev_update_status(struct virtio_user_dev
> *dev)
>  			!!(dev->status & VIRTIO_CONFIG_STATUS_FEATURES_OK),
>  			!!(dev->status & VIRTIO_CONFIG_STATUS_DEV_NEED_RESET),
>  			!!(dev->status & VIRTIO_CONFIG_STATUS_FAILED));
> -	} else if (err != -ENOTSUP) {
> -		PMD_INIT_LOG(ERR, "VHOST_USER_GET_STATUS failed (%d): %s", err,
> +	} else if (ret != -ENOTSUP) {
> +		PMD_INIT_LOG(ERR, "Virtio-user get status failed (%d): %s", ret,
>  			     strerror(errno));
>  	}
> 
> -error:
>  	pthread_mutex_unlock(&dev->mutex);
> -	return err;
> +	return ret;
>  }
> --
> 2.29.2

Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 34/44] net/virtio: remove useless request ops
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 34/44] net/virtio: remove useless request ops Maxime Coquelin
@ 2021-01-22  8:10   ` Xia, Chenbo
  0 siblings, 0 replies; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-22  8:10 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 34/44] net/virtio: remove useless request ops
> 
> Now that all the ops have been implemented, we
> can remove the send_request ops for all backends.
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user/vhost.h        |  15 +--
>  drivers/net/virtio/virtio_user/vhost_kernel.c |  43 --------
>  drivers/net/virtio/virtio_user/vhost_user.c   | 102 ------------------
>  drivers/net/virtio/virtio_user/vhost_vdpa.c   |  49 ---------
>  4 files changed, 3 insertions(+), 206 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/vhost.h
> b/drivers/net/virtio/virtio_user/vhost.h
> index c896f0836d..6294b8afee 100644
> --- a/drivers/net/virtio/virtio_user/vhost.h
> +++ b/drivers/net/virtio/virtio_user/vhost.h
> @@ -96,8 +96,6 @@ enum vhost_user_request {
>  #define VHOST_BACKEND_F_IOTLB_BATCH 2
>  #endif
> 
> -extern const char * const vhost_msg_strings[VHOST_USER_MAX];
> -
>  struct vhost_memory_region {
>  	uint64_t guest_phys_addr;
>  	uint64_t memory_size; /* bytes */
> @@ -123,16 +121,9 @@ struct virtio_user_backend_ops {
>  	int (*set_vring_addr)(struct virtio_user_dev *dev, struct
> vhost_vring_addr *addr);
>  	int (*get_status)(struct virtio_user_dev *dev, uint8_t *status);
>  	int (*set_status)(struct virtio_user_dev *dev, uint8_t status);
> -	int (*send_request)(struct virtio_user_dev *dev,
> -			    enum vhost_user_request req,
> -			    void *arg);
> -	int (*enable_qp)(struct virtio_user_dev *dev,
> -			 uint16_t pair_idx,
> -			 int enable);
> -	int (*dma_map)(struct virtio_user_dev *dev, void *addr,
> -				  uint64_t iova, size_t len);
> -	int (*dma_unmap)(struct virtio_user_dev *dev, void *addr,
> -				  uint64_t iova, size_t len);
> +	int (*enable_qp)(struct virtio_user_dev *dev, uint16_t pair_idx, int
> enable);
> +	int (*dma_map)(struct virtio_user_dev *dev, void *addr, uint64_t iova,
> size_t len);
> +	int (*dma_unmap)(struct virtio_user_dev *dev, void *addr, uint64_t iova,
> size_t len);
>  };
> 
>  extern struct virtio_user_backend_ops virtio_ops_user;
> diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c
> b/drivers/net/virtio/virtio_user/vhost_kernel.c
> index d85358fc34..68f0c0b83d 100644
> --- a/drivers/net/virtio/virtio_user/vhost_kernel.c
> +++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
> @@ -328,48 +328,6 @@ vhost_kernel_set_status(struct virtio_user_dev *dev
> __rte_unused, uint8_t status
>  	return -ENOTSUP;
>  }
> 
> -static uint64_t vhost_req_user_to_kernel[] = {
> -	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
> -};
> -
> -static int
> -vhost_kernel_send_request(struct virtio_user_dev *dev,
> -		   enum vhost_user_request req,
> -		   void *arg)
> -{
> -	int ret = -1;
> -	unsigned int i;
> -	uint64_t req_kernel;
> -	int vhostfd;
> -
> -	PMD_DRV_LOG(INFO, "%s", vhost_msg_strings[req]);
> -
> -	req_kernel = vhost_req_user_to_kernel[req];
> -
> -	switch (req_kernel) {
> -	default:
> -		vhostfd = -1;
> -	}
> -	if (vhostfd == -1) {
> -		for (i = 0; i < dev->max_queue_pairs; ++i) {
> -			if (dev->vhostfds[i] < 0)
> -				continue;
> -
> -			ret = ioctl(dev->vhostfds[i], req_kernel, arg);
> -			if (ret < 0)
> -				break;
> -		}
> -	} else {
> -		ret = ioctl(vhostfd, req_kernel, arg);
> -	}
> -
> -	if (ret < 0)
> -		PMD_DRV_LOG(ERR, "%s failed: %s",
> -			    vhost_msg_strings[req], strerror(errno));
> -
> -	return ret;
> -}
> -
>  /**
>   * Set up environment to talk with a vhost kernel backend.
>   *
> @@ -501,6 +459,5 @@ struct virtio_user_backend_ops virtio_ops_kernel = {
>  	.set_vring_addr = vhost_kernel_set_vring_addr,
>  	.get_status = vhost_kernel_get_status,
>  	.set_status = vhost_kernel_set_status,
> -	.send_request = vhost_kernel_send_request,
>  	.enable_qp = vhost_kernel_enable_queue_pair
>  };
> diff --git a/drivers/net/virtio/virtio_user/vhost_user.c
> b/drivers/net/virtio/virtio_user/vhost_user.c
> index cb0cd1cea8..d46e25b64b 100644
> --- a/drivers/net/virtio/virtio_user/vhost_user.c
> +++ b/drivers/net/virtio/virtio_user/vhost_user.c
> @@ -649,107 +649,6 @@ vhost_user_set_status(struct virtio_user_dev *dev,
> uint8_t status)
>  	return vhost_user_check_reply_ack(dev, &msg);
>  }
> 
> -static struct vhost_user_msg m;
> -
> -const char * const vhost_msg_strings[] = {
> -	[VHOST_USER_RESET_OWNER] = "VHOST_RESET_OWNER",
> -};
> -
> -static int
> -vhost_user_sock(struct virtio_user_dev *dev,
> -		enum vhost_user_request req,
> -		void *arg)
> -{
> -	struct vhost_user_msg msg;
> -	struct vhost_vring_file *file = 0;
> -	int need_reply = 0;
> -	int fds[VHOST_MEMORY_MAX_NREGIONS];
> -	int fd_num = 0;
> -	int vhostfd = dev->vhostfd;
> -
> -	RTE_SET_USED(m);
> -
> -	PMD_DRV_LOG(INFO, "%s", vhost_msg_strings[req]);
> -
> -	if (dev->is_server && vhostfd < 0)
> -		return -1;
> -
> -	msg.request = req;
> -	msg.flags = VHOST_USER_VERSION;
> -	msg.size = 0;
> -
> -	switch (req) {
> -	case VHOST_USER_SET_LOG_BASE:
> -		msg.payload.u64 = *((__u64 *)arg);
> -		msg.size = sizeof(m.payload.u64);
> -		break;
> -
> -	case VHOST_USER_SET_FEATURES:
> -		msg.payload.u64 = *((__u64 *)arg) | (dev->device_features &
> -			(1ULL << VHOST_USER_F_PROTOCOL_FEATURES));
> -		msg.size = sizeof(m.payload.u64);
> -		break;
> -
> -	case VHOST_USER_RESET_OWNER:
> -		break;
> -
> -	case VHOST_USER_SET_LOG_FD:
> -		fds[fd_num++] = *((int *)arg);
> -		break;
> -
> -	case VHOST_USER_SET_VRING_ERR:
> -		file = arg;
> -		msg.payload.u64 = file->index & VHOST_USER_VRING_IDX_MASK;
> -		msg.size = sizeof(m.payload.u64);
> -		if (file->fd > 0)
> -			fds[fd_num++] = file->fd;
> -		else
> -			msg.payload.u64 |= VHOST_USER_VRING_NOFD_MASK;
> -		break;
> -
> -	default:
> -		PMD_DRV_LOG(ERR, "trying to send unhandled msg type");
> -		return -1;
> -	}
> -
> -	if (vhost_user_write(vhostfd, &msg, fds, fd_num) < 0) {
> -		PMD_DRV_LOG(ERR, "%s failed: %s",
> -			    vhost_msg_strings[req], strerror(errno));
> -		return -1;
> -	}
> -
> -	if (need_reply || msg.flags & VHOST_USER_NEED_REPLY_MASK) {
> -		if (vhost_user_read(vhostfd, &msg) < 0) {
> -			PMD_DRV_LOG(ERR, "Received msg failed: %s",
> -				    strerror(errno));
> -			return -1;
> -		}
> -
> -		if (req != msg.request) {
> -			PMD_DRV_LOG(ERR, "Received unexpected msg type");
> -			return -1;
> -		}
> -
> -		switch (req) {
> -		default:
> -			/* Reply-ack handling */
> -			if (msg.size != sizeof(m.payload.u64)) {
> -				PMD_DRV_LOG(ERR, "Received bad msg size");
> -				return -1;
> -			}
> -
> -			if (msg.payload.u64 != 0) {
> -				PMD_DRV_LOG(ERR, "Slave replied NACK");
> -				return -1;
> -			}
> -
> -			break;
> -		}
> -	}
> -
> -	return 0;
> -}
> -
>  #define MAX_VIRTIO_USER_BACKLOG 1
>  static int
>  virtio_user_start_server(struct virtio_user_dev *dev, struct sockaddr_un *un)
> @@ -865,6 +764,5 @@ struct virtio_user_backend_ops virtio_ops_user = {
>  	.set_vring_addr = vhost_user_set_vring_addr,
>  	.get_status = vhost_user_get_status,
>  	.set_status = vhost_user_set_status,
> -	.send_request = vhost_user_sock,
>  	.enable_qp = vhost_user_enable_queue_pair
>  };
> diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> index 8ebc679f1b..7fb1249569 100644
> --- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> +++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> @@ -36,10 +36,6 @@
>  #define VHOST_SET_BACKEND_FEATURES _IOW(VHOST_VIRTIO, 0x25, __u64)
>  #define VHOST_GET_BACKEND_FEATURES _IOR(VHOST_VIRTIO, 0x26, __u64)
> 
> -static uint64_t vhost_req_user_to_vdpa[] = {
> -	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
> -};
> -
>  /* no alignment requirement */
>  struct vhost_iotlb_msg {
>  	uint64_t iova;
> @@ -389,50 +385,6 @@ vhost_vdpa_set_status(struct virtio_user_dev *dev,
> uint8_t status)
>  	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_VDPA_SET_STATUS, &status);
>  }
> 
> -/* with below features, vhost vdpa does not need to do the checksum and TSO,
> - * these info will be passed to virtio_user through virtio net header.
> - */
> -#define VHOST_VDPA_GUEST_OFFLOADS_MASK	\
> -	((1ULL << VIRTIO_NET_F_GUEST_CSUM) |	\
> -	 (1ULL << VIRTIO_NET_F_GUEST_TSO4) |	\
> -	 (1ULL << VIRTIO_NET_F_GUEST_TSO6) |	\
> -	 (1ULL << VIRTIO_NET_F_GUEST_ECN)  |	\
> -	 (1ULL << VIRTIO_NET_F_GUEST_UFO))
> -
> -#define VHOST_VDPA_HOST_OFFLOADS_MASK		\
> -	((1ULL << VIRTIO_NET_F_HOST_TSO4) |	\
> -	 (1ULL << VIRTIO_NET_F_HOST_TSO6) |	\
> -	 (1ULL << VIRTIO_NET_F_CSUM))
> -
> -static int
> -vhost_vdpa_send_request(struct virtio_user_dev *dev,
> -		   enum vhost_user_request req,
> -		   void *arg)
> -{
> -	int ret = -1;
> -	uint64_t req_vdpa;
> -
> -	PMD_DRV_LOG(INFO, "%s", vhost_msg_strings[req]);
> -
> -	req_vdpa = vhost_req_user_to_vdpa[req];
> -
> -	switch (req_vdpa) {
> -	case VHOST_SET_VRING_ADDR:
> -		PMD_DRV_LOG(DEBUG, "vhostfd=%d, index=%u",
> -			    dev->vhostfd, *(unsigned int *)arg);
> -		break;
> -	default:
> -		break;
> -	}
> -
> -	ret = ioctl(dev->vhostfd, req_vdpa, arg);
> -	if (ret < 0)
> -		PMD_DRV_LOG(ERR, "%s failed: %s",
> -			    vhost_msg_strings[req], strerror(errno));
> -
> -	return ret;
> -}
> -
>  /**
>   * Set up environment to talk with a vhost vdpa backend.
>   *
> @@ -502,7 +454,6 @@ struct virtio_user_backend_ops virtio_ops_vdpa = {
>  	.set_vring_addr = vhost_vdpa_set_vring_addr,
>  	.get_status = vhost_vdpa_get_status,
>  	.set_status = vhost_vdpa_set_status,
> -	.send_request = vhost_vdpa_send_request,
>  	.enable_qp = vhost_vdpa_enable_queue_pair,
>  	.dma_map = vhost_vdpa_dma_map_batch,
>  	.dma_unmap = vhost_vdpa_dma_unmap_batch,
> --
> 2.29.2

Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 35/44] net/virtio: improve Virtio-user errors handling
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 35/44] net/virtio: improve Virtio-user errors handling Maxime Coquelin
@ 2021-01-22  8:10   ` Xia, Chenbo
  0 siblings, 0 replies; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-22  8:10 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 35/44] net/virtio: improve Virtio-user errors handling
> 
> This patch adds error logs and propagates errors reported
> by the backend. It also adds the device path in error logs
> to make it easier to distinguish which device is facing the
> issue.
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  .../net/virtio/virtio_user/virtio_user_dev.c  | 154 ++++++++++++------
>  1 file changed, 104 insertions(+), 50 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> index 33a25f4684..95204ea955 100644
> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> @@ -37,10 +37,15 @@ virtio_user_create_queue(struct virtio_user_dev *dev,
> uint32_t queue_sel)
>  	 * pair.
>  	 */
>  	struct vhost_vring_file file;
> +	int ret;
> 
>  	file.index = queue_sel;
>  	file.fd = dev->callfds[queue_sel];
> -	dev->ops->set_vring_call(dev, &file);
> +	ret = dev->ops->set_vring_call(dev, &file);
> +	if (ret < 0) {
> +		PMD_INIT_LOG(ERR, "(%s) Failed to create queue %u\n", dev->path,
> queue_sel);
> +		return -1;
> +	}
> 
>  	return 0;
>  }
> @@ -48,6 +53,7 @@ virtio_user_create_queue(struct virtio_user_dev *dev,
> uint32_t queue_sel)
>  static int
>  virtio_user_kick_queue(struct virtio_user_dev *dev, uint32_t queue_sel)
>  {
> +	int ret;
>  	struct vhost_vring_file file;
>  	struct vhost_vring_state state;
>  	struct vring *vring = &dev->vrings[queue_sel];
> @@ -73,15 +79,21 @@ virtio_user_kick_queue(struct virtio_user_dev *dev,
> uint32_t queue_sel)
> 
>  	state.index = queue_sel;
>  	state.num = vring->num;
> -	dev->ops->set_vring_num(dev, &state);
> +	ret = dev->ops->set_vring_num(dev, &state);
> +	if (ret < 0)
> +		goto err;
> 
>  	state.index = queue_sel;
>  	state.num = 0; /* no reservation */
>  	if (dev->features & (1ULL << VIRTIO_F_RING_PACKED))
>  		state.num |= (1 << 15);
> -	dev->ops->set_vring_base(dev, &state);
> +	ret = dev->ops->set_vring_base(dev, &state);
> +	if (ret < 0)
> +		goto err;
> 
> -	dev->ops->set_vring_addr(dev, &addr);
> +	ret = dev->ops->set_vring_addr(dev, &addr);
> +	if (ret < 0)
> +		goto err;
> 
>  	/* Of all per virtqueue MSGs, make sure VHOST_USER_SET_VRING_KICK comes
>  	 * lastly because vhost depends on this msg to judge if
> @@ -89,9 +101,15 @@ virtio_user_kick_queue(struct virtio_user_dev *dev,
> uint32_t queue_sel)
>  	 */
>  	file.index = queue_sel;
>  	file.fd = dev->kickfds[queue_sel];
> -	dev->ops->set_vring_kick(dev, &file);
> +	ret = dev->ops->set_vring_kick(dev, &file);
> +	if (ret < 0)
> +		goto err;
> 
>  	return 0;
> +err:
> +	PMD_INIT_LOG(ERR, "(%s) Failed to kick queue %u\n", dev->path,
> queue_sel);
> +
> +	return -1;
>  }
> 
>  static int
> @@ -103,14 +121,14 @@ virtio_user_queue_setup(struct virtio_user_dev *dev,
>  	for (i = 0; i < dev->max_queue_pairs; ++i) {
>  		queue_sel = 2 * i + VTNET_SQ_RQ_QUEUE_IDX;
>  		if (fn(dev, queue_sel) < 0) {
> -			PMD_DRV_LOG(INFO, "setup rx vq fails: %u", i);
> +			PMD_DRV_LOG(ERR, "(%s) setup rx vq %u failed", dev->path, i);
>  			return -1;
>  		}
>  	}
>  	for (i = 0; i < dev->max_queue_pairs; ++i) {
>  		queue_sel = 2 * i + VTNET_SQ_TQ_QUEUE_IDX;
>  		if (fn(dev, queue_sel) < 0) {
> -			PMD_DRV_LOG(INFO, "setup tx vq fails: %u", i);
> +			PMD_DRV_LOG(INFO, "(%s) setup tx vq %u failed", dev->path,
> i);
>  			return -1;
>  		}
>  	}
> @@ -144,7 +162,7 @@ virtio_user_dev_set_features(struct virtio_user_dev *dev)
>  	ret = dev->ops->set_features(dev, features);
>  	if (ret < 0)
>  		goto error;
> -	PMD_DRV_LOG(INFO, "set features: %" PRIx64, features);
> +	PMD_DRV_LOG(INFO, "(%s) set features: 0x%" PRIx64, dev->path, features);
>  error:
>  	pthread_mutex_unlock(&dev->mutex);
> 
> @@ -172,9 +190,10 @@ virtio_user_start_device(struct virtio_user_dev *dev)
>  	rte_mcfg_mem_read_lock();
>  	pthread_mutex_lock(&dev->mutex);
> 
> +	/* Vhost-user client not connected yet, will start later */
>  	if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER &&
>  			dev->vhostfd < 0)
> -		goto error;
> +		goto out;
> 
>  	/* Step 2: share memory regions */
>  	ret = dev->ops->set_memory_table(dev);
> @@ -182,15 +201,19 @@ virtio_user_start_device(struct virtio_user_dev *dev)
>  		goto error;
> 
>  	/* Step 3: kick queues */
> -	if (virtio_user_queue_setup(dev, virtio_user_kick_queue) < 0)
> +	ret = virtio_user_queue_setup(dev, virtio_user_kick_queue);
> +	if (ret < 0)
>  		goto error;
> 
>  	/* Step 4: enable queues
>  	 * we enable the 1st queue pair by default.
>  	 */
> -	dev->ops->enable_qp(dev, 0, 1);
> +	ret = dev->ops->enable_qp(dev, 0, 1);
> +	if (ret < 0)
> +		goto error;
> 
>  	dev->started = true;
> +out:
>  	pthread_mutex_unlock(&dev->mutex);
>  	rte_mcfg_mem_read_unlock();
> 
> @@ -198,6 +221,9 @@ virtio_user_start_device(struct virtio_user_dev *dev)
>  error:
>  	pthread_mutex_unlock(&dev->mutex);
>  	rte_mcfg_mem_read_unlock();
> +
> +	PMD_INIT_LOG(ERR, "(%s) Failed to start device\n", dev->path);
> +
>  	/* TODO: free resource here or caller to check */
>  	return -1;
>  }
> @@ -206,31 +232,40 @@ int virtio_user_stop_device(struct virtio_user_dev *dev)
>  {
>  	struct vhost_vring_state state;
>  	uint32_t i;
> -	int error = 0;
> +	int ret;
> 
>  	pthread_mutex_lock(&dev->mutex);
>  	if (!dev->started)
>  		goto out;
> 
> -	for (i = 0; i < dev->max_queue_pairs; ++i)
> -		dev->ops->enable_qp(dev, i, 0);
> +	for (i = 0; i < dev->max_queue_pairs; ++i) {
> +		ret = dev->ops->enable_qp(dev, i, 0);
> +		if (ret < 0)
> +			goto err;
> +	}
> 
>  	/* Stop the backend. */
>  	for (i = 0; i < dev->max_queue_pairs * 2; ++i) {
>  		state.index = i;
> -		if (dev->ops->get_vring_base(dev, &state) < 0) {
> -			PMD_DRV_LOG(ERR, "get_vring_base failed, index=%u",
> -				    i);
> -			error = -1;
> -			goto out;
> +		ret = dev->ops->get_vring_base(dev, &state);
> +		if (ret < 0) {
> +			PMD_DRV_LOG(ERR, "(%s) get_vring_base failed, index=%u",
> dev->path, i);
> +			goto err;
>  		}
>  	}
> 
>  	dev->started = false;
> +
>  out:
>  	pthread_mutex_unlock(&dev->mutex);
> 
> -	return error;
> +	return 0;
> +err:
> +	pthread_mutex_unlock(&dev->mutex);
> +
> +	PMD_INIT_LOG(ERR, "(%s) Failed to stop device\n", dev->path);
> +
> +	return -1;
>  }
> 
>  static inline void
> @@ -270,13 +305,13 @@ virtio_user_dev_init_notify(struct virtio_user_dev *dev)
>  		 */
>  		callfd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
>  		if (callfd < 0) {
> -			PMD_DRV_LOG(ERR, "callfd error, %s", strerror(errno));
> +			PMD_DRV_LOG(ERR, "(%s) callfd error, %s", dev->path,
> strerror(errno));
>  			break;
>  		}
>  		kickfd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
>  		if (kickfd < 0) {
>  			close(callfd);
> -			PMD_DRV_LOG(ERR, "kickfd error, %s", strerror(errno));
> +			PMD_DRV_LOG(ERR, "(%s) kickfd error, %s", dev->path,
> strerror(errno));
>  			break;
>  		}
>  		dev->callfds[i] = callfd;
> @@ -304,7 +339,7 @@ virtio_user_fill_intr_handle(struct virtio_user_dev *dev)
>  	if (!eth_dev->intr_handle) {
>  		eth_dev->intr_handle = malloc(sizeof(*eth_dev->intr_handle));
>  		if (!eth_dev->intr_handle) {
> -			PMD_DRV_LOG(ERR, "fail to allocate intr_handle");
> +			PMD_DRV_LOG(ERR, "(%s) failed to allocate intr_handle", dev-
> >path);
>  			return -1;
>  		}
>  		memset(eth_dev->intr_handle, 0, sizeof(*eth_dev->intr_handle));
> @@ -335,6 +370,7 @@ virtio_user_mem_event_cb(enum rte_mem_event type
> __rte_unused,
>  	struct virtio_user_dev *dev = arg;
>  	struct rte_memseg_list *msl;
>  	uint16_t i;
> +	int ret = 0;
> 
>  	/* ignore externally allocated memory */
>  	msl = rte_mem_virt2memseg_list(addr);
> @@ -347,18 +383,29 @@ virtio_user_mem_event_cb(enum rte_mem_event type
> __rte_unused,
>  		goto exit;
> 
>  	/* Step 1: pause the active queues */
> -	for (i = 0; i < dev->queue_pairs; i++)
> -		dev->ops->enable_qp(dev, i, 0);
> +	for (i = 0; i < dev->queue_pairs; i++) {
> +		ret = dev->ops->enable_qp(dev, i, 0);
> +		if (ret < 0)
> +			goto exit;
> +	}
> 
>  	/* Step 2: update memory regions */
> -	dev->ops->set_memory_table(dev);
> +	ret = dev->ops->set_memory_table(dev);
> +	if (ret < 0)
> +		goto exit;
> 
>  	/* Step 3: resume the active queues */
> -	for (i = 0; i < dev->queue_pairs; i++)
> -		dev->ops->enable_qp(dev, i, 1);
> +	for (i = 0; i < dev->queue_pairs; i++) {
> +		ret = dev->ops->enable_qp(dev, i, 1);
> +		if (ret < 0)
> +			goto exit;
> +	}
> 
>  exit:
>  	pthread_mutex_unlock(&dev->mutex);
> +
> +	if (ret < 0)
> +		PMD_DRV_LOG(ERR, "(%s) Failed to update memory table\n", dev-
> >path);
>  }
> 
>  static int
> @@ -388,7 +435,7 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
>  			dev->tapfds = malloc(dev->max_queue_pairs *
>  					     sizeof(int));
>  			if (!dev->vhostfds || !dev->tapfds) {
> -				PMD_INIT_LOG(ERR, "Failed to malloc");
> +				PMD_INIT_LOG(ERR, "(%s) Failed to allocate FDs", dev-
> >path);
>  				return -1;
>  			}
> 
> @@ -400,19 +447,25 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
>  				VIRTIO_USER_BACKEND_VHOST_VDPA) {
>  			dev->ops = &virtio_ops_vdpa;
>  		} else {
> -			PMD_DRV_LOG(ERR, "Unknown backend type");
> +			PMD_DRV_LOG(ERR, "(%s) Unknown backend type", dev->path);
>  			return -1;
>  		}
>  	}
> 
> -	if (dev->ops->setup(dev) < 0)
> +	if (dev->ops->setup(dev) < 0) {
> +		PMD_INIT_LOG(ERR, "(%s) Failed to setup backend\n", dev->path);
>  		return -1;
> +	}
> 
> -	if (virtio_user_dev_init_notify(dev) < 0)
> +	if (virtio_user_dev_init_notify(dev) < 0) {
> +		PMD_INIT_LOG(ERR, "(%s) Failed to init notifiers\n", dev->path);
>  		return -1;
> +	}
> 
> -	if (virtio_user_fill_intr_handle(dev) < 0)
> +	if (virtio_user_fill_intr_handle(dev) < 0) {
> +		PMD_INIT_LOG(ERR, "(%s) Failed to init interrupt handler\n", dev-
> >path);
>  		return -1;
> +	}
> 
>  	return 0;
>  }
> @@ -480,7 +533,7 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char
> *path, int queues,
>  	}
> 
>  	if (virtio_user_dev_setup(dev) < 0) {
> -		PMD_INIT_LOG(ERR, "backend set up fails");
> +		PMD_INIT_LOG(ERR, "(%s) backend set up fails", dev->path);
>  		return -1;
>  	}
> 
> @@ -490,27 +543,31 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char
> *path, int queues,
> 
>  	if (!dev->is_server) {
>  		if (dev->ops->set_owner(dev) < 0) {
> -			PMD_INIT_LOG(ERR, "set_owner fails: %s",
> -				     strerror(errno));
> +			PMD_INIT_LOG(ERR, "(%s) Failed to set backend owner", dev-
> >path);
>  			return -1;
>  		}
> 
>  		if (dev->ops->get_features(dev, &dev->device_features) < 0) {
> -			PMD_INIT_LOG(ERR, "get_features failed: %s",
> -				     strerror(errno));
> +			PMD_INIT_LOG(ERR, "(%s) Failed to get backend features",
> dev->path);
>  			return -1;
>  		}
> 
> 
>  		if ((dev->device_features & (1ULL <<
> VHOST_USER_F_PROTOCOL_FEATURES)) ||
>  				(dev->backend_type == VIRTIO_USER_BACKEND_VHOST_VDPA))
> {
> -			if (dev->ops->get_protocol_features(dev, &protocol_features))
> +			if (dev->ops->get_protocol_features(dev, &protocol_features))
> {
> +				PMD_INIT_LOG(ERR, "(%s) Failed to get backend protocol
> features",
> +						dev->path);
>  				return -1;
> +			}
> 
>  			dev->protocol_features &= protocol_features;
> 
> -			if (dev->ops->set_protocol_features(dev, dev-
> >protocol_features))
> +			if (dev->ops->set_protocol_features(dev, dev-
> >protocol_features)) {
> +				PMD_INIT_LOG(ERR, "(%s) Failed to set backend protocol
> features",
> +						dev->path);
>  				return -1;
> +			}
> 
>  			if (!(dev->protocol_features & (1ULL <<
> VHOST_USER_PROTOCOL_F_MQ)))
>  				dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
> @@ -577,8 +634,8 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char
> *path, int queues,
>  	if (rte_mem_event_callback_register(VIRTIO_USER_MEM_EVENT_CLB_NAME,
>  				virtio_user_mem_event_cb, dev)) {
>  		if (rte_errno != ENOTSUP) {
> -			PMD_INIT_LOG(ERR, "Failed to register mem event"
> -					" callback\n");
> +			PMD_INIT_LOG(ERR, "(%s) Failed to register mem event
> callback\n",
> +					dev->path);
>  			return -1;
>  		}
>  	}
> @@ -631,8 +688,8 @@ virtio_user_handle_mq(struct virtio_user_dev *dev,
> uint16_t q_pairs)
>  	uint8_t ret = 0;
> 
>  	if (q_pairs > dev->max_queue_pairs) {
> -		PMD_INIT_LOG(ERR, "multi-q config %u, but only %u supported",
> -			     q_pairs, dev->max_queue_pairs);
> +		PMD_INIT_LOG(ERR, "(%s) multi-q config %u, but only %u supported",
> +			     dev->path, q_pairs, dev->max_queue_pairs);
>  		return -1;
>  	}
> 
> @@ -818,10 +875,8 @@ virtio_user_dev_set_status(struct virtio_user_dev *dev,
> uint8_t status)
>  	pthread_mutex_lock(&dev->mutex);
>  	dev->status = status;
>  	ret = dev->ops->set_status(dev, status);
> -	if (ret && ret != -ENOTSUP) {
> -		PMD_INIT_LOG(ERR, "Virtio-user set status failed (%d): %s", ret,
> -			     strerror(errno));
> -	}
> +	if (ret && ret != -ENOTSUP)
> +		PMD_INIT_LOG(ERR, "(%s) Failed to set backend status\n", dev-
> >path);
> 
>  	pthread_mutex_unlock(&dev->mutex);
>  	return ret;
> @@ -855,8 +910,7 @@ virtio_user_dev_update_status(struct virtio_user_dev *dev)
>  			!!(dev->status & VIRTIO_CONFIG_STATUS_DEV_NEED_RESET),
>  			!!(dev->status & VIRTIO_CONFIG_STATUS_FAILED));
>  	} else if (ret != -ENOTSUP) {
> -		PMD_INIT_LOG(ERR, "Virtio-user get status failed (%d): %s", ret,
> -			     strerror(errno));
> +		PMD_INIT_LOG(ERR, "(%s) Failed to get backend status\n", dev-
> >path);
>  	}
> 
>  	pthread_mutex_unlock(&dev->mutex);
> --
> 2.29.2

Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 37/44] net/virtio: make server mode blocking
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 37/44] net/virtio: make server mode blocking Maxime Coquelin
@ 2021-01-22  8:19   ` Xia, Chenbo
  0 siblings, 0 replies; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-22  8:19 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 37/44] net/virtio: make server mode blocking
> 
> This patch makes the Vhost-user backend server mode
> blocking at init, waiting for the client connection.
> 
> The goal is to make the driver more reliable, as without
> waiting for client connection, the Virtio driver has to
> assume the Vhost-user backend will support all the
> features it has advertized, which could lead to undefined
> behaviour.
> 
> For example, without this patch, if the user enables packed
> ring Virtio feature but the backend does not support it,
> the ring initialized by the driver will not be compatible
> with the backend.
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user/vhost_user.c   |   9 +-
>  .../net/virtio/virtio_user/virtio_user_dev.c  | 121 +++++++-----------
>  drivers/net/virtio/virtio_user_ethdev.c       |   5 -
>  3 files changed, 55 insertions(+), 80 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/vhost_user.c
> b/drivers/net/virtio/virtio_user/vhost_user.c
> index fb6fcc82c9..a48fadd8c9 100644
> --- a/drivers/net/virtio/virtio_user/vhost_user.c
> +++ b/drivers/net/virtio/virtio_user/vhost_user.c
> @@ -692,6 +692,14 @@ virtio_user_start_server(struct virtio_user_dev *dev,
> struct sockaddr_un *un)
>  	if (ret < 0)
>  		return -1;
> 
> +	PMD_DRV_LOG(NOTICE, "(%s) waiting for client connection...", dev->path);
> +	dev->vhostfd = accept(fd, NULL, NULL);
> +	if (dev->vhostfd < 0) {
> +		PMD_DRV_LOG(ERR, "Failed to accept initial client connection (%s)",
> +				strerror(errno));
> +		return -1;
> +	}
> +
>  	flag = fcntl(fd, F_GETFL);
>  	if (fcntl(fd, F_SETFL, flag | O_NONBLOCK) < 0) {
>  		PMD_DRV_LOG(ERR, "fcntl failed, %s", strerror(errno));
> @@ -736,7 +744,6 @@ vhost_user_setup(struct virtio_user_dev *dev)
>  			close(fd);
>  			return -1;
>  		}
> -		dev->vhostfd = -1;
>  	} else {
>  		if (connect(fd, (struct sockaddr *)&un, sizeof(un)) < 0) {
>  			PMD_DRV_LOG(ERR, "connect error, %s", strerror(errno));
> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> index 95204ea955..c2a41fe3a0 100644
> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> @@ -144,10 +144,6 @@ virtio_user_dev_set_features(struct virtio_user_dev *dev)
> 
>  	pthread_mutex_lock(&dev->mutex);
> 
> -	if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER &&
> -			dev->vhostfd < 0)
> -		goto error;
> -
>  	/* Step 0: tell vhost to create queues */
>  	if (virtio_user_queue_setup(dev, virtio_user_create_queue) < 0)
>  		goto error;
> @@ -190,11 +186,6 @@ virtio_user_start_device(struct virtio_user_dev *dev)
>  	rte_mcfg_mem_read_lock();
>  	pthread_mutex_lock(&dev->mutex);
> 
> -	/* Vhost-user client not connected yet, will start later */
> -	if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER &&
> -			dev->vhostfd < 0)
> -		goto out;
> -
>  	/* Step 2: share memory regions */
>  	ret = dev->ops->set_memory_table(dev);
>  	if (ret < 0)
> @@ -213,7 +204,7 @@ virtio_user_start_device(struct virtio_user_dev *dev)
>  		goto error;
> 
>  	dev->started = true;
> -out:
> +
>  	pthread_mutex_unlock(&dev->mutex);
>  	rte_mcfg_mem_read_unlock();
> 
> @@ -422,36 +413,36 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
>  			PMD_DRV_LOG(ERR, "Server mode only supports vhost-user!");
>  			return -1;
>  		}
> +	}
> +
> +	if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER) {
>  		dev->ops = &virtio_ops_user;
> -	} else {
> -		if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER) {
> -			dev->ops = &virtio_ops_user;
> -		} else if (dev->backend_type ==
> -					VIRTIO_USER_BACKEND_VHOST_KERNEL) {
> -			dev->ops = &virtio_ops_kernel;
> -
> -			dev->vhostfds = malloc(dev->max_queue_pairs *
> -					       sizeof(int));
> -			dev->tapfds = malloc(dev->max_queue_pairs *
> -					     sizeof(int));
> -			if (!dev->vhostfds || !dev->tapfds) {
> -				PMD_INIT_LOG(ERR, "(%s) Failed to allocate FDs", dev-
> >path);
> -				return -1;
> -			}
> -
> -			for (q = 0; q < dev->max_queue_pairs; ++q) {
> -				dev->vhostfds[q] = -1;
> -				dev->tapfds[q] = -1;
> -			}
> -		} else if (dev->backend_type ==
> -				VIRTIO_USER_BACKEND_VHOST_VDPA) {
> -			dev->ops = &virtio_ops_vdpa;
> -		} else {
> -			PMD_DRV_LOG(ERR, "(%s) Unknown backend type", dev->path);
> +	} else if (dev->backend_type ==
> +			VIRTIO_USER_BACKEND_VHOST_KERNEL) {
> +		dev->ops = &virtio_ops_kernel;
> +
> +		dev->vhostfds = malloc(dev->max_queue_pairs *
> +				sizeof(int));
> +		dev->tapfds = malloc(dev->max_queue_pairs *
> +				sizeof(int));
> +		if (!dev->vhostfds || !dev->tapfds) {
> +			PMD_INIT_LOG(ERR, "(%s) Failed to allocate FDs", dev->path);
>  			return -1;
>  		}
> +
> +		for (q = 0; q < dev->max_queue_pairs; ++q) {
> +			dev->vhostfds[q] = -1;
> +			dev->tapfds[q] = -1;
> +		}
> +	} else if (dev->backend_type ==
> +			VIRTIO_USER_BACKEND_VHOST_VDPA) {
> +		dev->ops = &virtio_ops_vdpa;
> +	} else {
> +		PMD_DRV_LOG(ERR, "(%s) Unknown backend type", dev->path);
> +		return -1;
>  	}
> 
> +
>  	if (dev->ops->setup(dev) < 0) {
>  		PMD_INIT_LOG(ERR, "(%s) Failed to setup backend\n", dev->path);
>  		return -1;
> @@ -541,54 +532,36 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char
> *path, int queues,
>  		dev->unsupported_features |=
>  			(1ULL << VHOST_USER_F_PROTOCOL_FEATURES);
> 
> -	if (!dev->is_server) {
> -		if (dev->ops->set_owner(dev) < 0) {
> -			PMD_INIT_LOG(ERR, "(%s) Failed to set backend owner", dev-
> >path);
> -			return -1;
> -		}
> +	if (dev->ops->set_owner(dev) < 0) {
> +		PMD_INIT_LOG(ERR, "(%s) Failed to set backend owner", dev->path);
> +		return -1;
> +	}
> +
> +	if (dev->ops->get_features(dev, &dev->device_features) < 0) {
> +		PMD_INIT_LOG(ERR, "(%s) Failed to get backend features", dev-
> >path);
> +		return -1;
> +	}
> 
> -		if (dev->ops->get_features(dev, &dev->device_features) < 0) {
> -			PMD_INIT_LOG(ERR, "(%s) Failed to get backend features",
> dev->path);
> +	if ((dev->device_features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)) ||
> +			dev->backend_type == VIRTIO_USER_BACKEND_VHOST_VDPA) {
> +		if (dev->ops->get_protocol_features(dev, &protocol_features)) {
> +			PMD_INIT_LOG(ERR, "(%s) Failed to get backend protocol
> features",
> +					dev->path);
>  			return -1;
>  		}
> 
> +		dev->protocol_features &= protocol_features;
> 
> -		if ((dev->device_features & (1ULL <<
> VHOST_USER_F_PROTOCOL_FEATURES)) ||
> -				(dev->backend_type == VIRTIO_USER_BACKEND_VHOST_VDPA))
> {
> -			if (dev->ops->get_protocol_features(dev, &protocol_features))
> {
> -				PMD_INIT_LOG(ERR, "(%s) Failed to get backend protocol
> features",
> -						dev->path);
> -				return -1;
> -			}
> -
> -			dev->protocol_features &= protocol_features;
> -
> -			if (dev->ops->set_protocol_features(dev, dev-
> >protocol_features)) {
> -				PMD_INIT_LOG(ERR, "(%s) Failed to set backend protocol
> features",
> -						dev->path);
> -				return -1;
> -			}
> -
> -			if (!(dev->protocol_features & (1ULL <<
> VHOST_USER_PROTOCOL_F_MQ)))
> -				dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
> +		if (dev->ops->set_protocol_features(dev, dev->protocol_features))
> {
> +			PMD_INIT_LOG(ERR, "(%s) Failed to set backend protocol
> features",
> +					dev->path);
> +			return -1;
>  		}
> -	} else {
> -		/* We just pretend vhost-user can support all these features.
> -		 * Note that this could be problematic that if some feature is
> -		 * negotiated but not supported by the vhost-user which comes
> -		 * later.
> -		 */
> -		dev->device_features = VIRTIO_USER_SUPPORTED_FEATURES;
> 
> -		/* We cannot assume VHOST_USER_PROTOCOL_F_STATUS is supported
> -		 * until it's negotiated
> -		 */
> -		dev->protocol_features &=
> -			~(1ULL << VHOST_USER_PROTOCOL_F_STATUS);
> +		if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
> +			dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
>  	}
> 
> -
> -
>  	if (!mrg_rxbuf)
>  		dev->unsupported_features |= (1ull << VIRTIO_NET_F_MRG_RXBUF);
> 
> diff --git a/drivers/net/virtio/virtio_user_ethdev.c
> b/drivers/net/virtio/virtio_user_ethdev.c
> index 5e256f4e6d..e822d93690 100644
> --- a/drivers/net/virtio/virtio_user_ethdev.c
> +++ b/drivers/net/virtio/virtio_user_ethdev.c
> @@ -174,11 +174,6 @@ virtio_user_delayed_handler(void *param)
>  		if (dev->vhostfd >= 0) {
>  			close(dev->vhostfd);
>  			dev->vhostfd = -1;
> -			/* Until the featuers are negotiated again, don't assume
> -			 * the backend supports VHOST_USER_PROTOCOL_F_STATUS
> -			 */
> -			dev->protocol_features &=
> -				~(1ULL << VHOST_USER_PROTOCOL_F_STATUS);
>  		}
>  		eth_dev->intr_handle->fd = dev->listenfd;
>  		rte_intr_callback_register(eth_dev->intr_handle,
> --
> 2.29.2

Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 38/44] net/virtio: move protocol features to Vhost-user
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 38/44] net/virtio: move protocol features to Vhost-user Maxime Coquelin
@ 2021-01-22  8:20   ` Xia, Chenbo
  0 siblings, 0 replies; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-22  8:20 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 38/44] net/virtio: move protocol features to Vhost-user
> 
> Since only protocol features are specific to Vhost-user
> backend, this patch moves all related code to Vhost-user
> file.
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user/vhost.h        | 20 +----
>  drivers/net/virtio/virtio_user/vhost_kernel.c |  9 ++
>  drivers/net/virtio/virtio_user/vhost_user.c   | 83 +++++++++++++++----
>  drivers/net/virtio/virtio_user/vhost_vdpa.c   | 34 +++++++-
>  .../net/virtio/virtio_user/virtio_user_dev.c  | 47 ++---------
>  drivers/net/virtio/virtio_user_ethdev.c       | 17 ----
>  6 files changed, 113 insertions(+), 97 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/vhost.h
> b/drivers/net/virtio/virtio_user/vhost.h
> index 2aa6b2cb70..dfa2735a20 100644
> --- a/drivers/net/virtio/virtio_user/vhost.h
> +++ b/drivers/net/virtio/virtio_user/vhost.h
> @@ -46,23 +46,6 @@ struct vhost_vring_addr {
>  	uint64_t log_guest_addr;
>  };
> 
> -#ifndef VHOST_USER_F_PROTOCOL_FEATURES
> -#define VHOST_USER_F_PROTOCOL_FEATURES 30
> -#endif
> -
> -/** Protocol features. */
> -#ifndef VHOST_USER_PROTOCOL_F_MQ
> -#define VHOST_USER_PROTOCOL_F_MQ 0
> -#endif
> -
> -#ifndef VHOST_USER_PROTOCOL_F_REPLY_ACK
> -#define VHOST_USER_PROTOCOL_F_REPLY_ACK 3
> -#endif
> -
> -#ifndef VHOST_USER_PROTOCOL_F_STATUS
> -#define VHOST_USER_PROTOCOL_F_STATUS 16
> -#endif
> -
>  #ifndef VHOST_BACKEND_F_IOTLB_MSG_V2
>  #define VHOST_BACKEND_F_IOTLB_MSG_V2 1
>  #endif
> @@ -82,11 +65,10 @@ struct virtio_user_dev;
> 
>  struct virtio_user_backend_ops {
>  	int (*setup)(struct virtio_user_dev *dev);
> +	int (*get_backend_features)(uint64_t *features);
>  	int (*set_owner)(struct virtio_user_dev *dev);
>  	int (*get_features)(struct virtio_user_dev *dev, uint64_t *features);
>  	int (*set_features)(struct virtio_user_dev *dev, uint64_t features);
> -	int (*get_protocol_features)(struct virtio_user_dev *dev, uint64_t
> *features);
> -	int (*set_protocol_features)(struct virtio_user_dev *dev, uint64_t
> features);
>  	int (*set_memory_table)(struct virtio_user_dev *dev);
>  	int (*set_vring_num)(struct virtio_user_dev *dev, struct
> vhost_vring_state *state);
>  	int (*set_vring_base)(struct virtio_user_dev *dev, struct
> vhost_vring_state *state);
> diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c
> b/drivers/net/virtio/virtio_user/vhost_kernel.c
> index 68f0c0b83d..5477eb7015 100644
> --- a/drivers/net/virtio/virtio_user/vhost_kernel.c
> +++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
> @@ -445,8 +445,17 @@ vhost_kernel_enable_queue_pair(struct virtio_user_dev
> *dev,
>  	return 0;
>  }
> 
> +static int
> +vhost_kernel_get_backend_features(uint64_t *features)
> +{
> +	*features = 0;
> +
> +	return 0;
> +}
> +
>  struct virtio_user_backend_ops virtio_ops_kernel = {
>  	.setup = vhost_kernel_setup,
> +	.get_backend_features = vhost_kernel_get_backend_features,
>  	.set_owner = vhost_kernel_set_owner,
>  	.get_features = vhost_kernel_get_features,
>  	.set_features = vhost_kernel_set_features,
> diff --git a/drivers/net/virtio/virtio_user/vhost_user.c
> b/drivers/net/virtio/virtio_user/vhost_user.c
> index a48fadd8c9..986d8ac1ac 100644
> --- a/drivers/net/virtio/virtio_user/vhost_user.c
> +++ b/drivers/net/virtio/virtio_user/vhost_user.c
> @@ -17,6 +17,29 @@
>  #include "vhost.h"
>  #include "virtio_user_dev.h"
> 
> +
> +#ifndef VHOST_USER_F_PROTOCOL_FEATURES
> +#define VHOST_USER_F_PROTOCOL_FEATURES 30
> +#endif
> +
> +/** Protocol features. */
> +#ifndef VHOST_USER_PROTOCOL_F_MQ
> +#define VHOST_USER_PROTOCOL_F_MQ 0
> +#endif
> +
> +#ifndef VHOST_USER_PROTOCOL_F_REPLY_ACK
> +#define VHOST_USER_PROTOCOL_F_REPLY_ACK 3
> +#endif
> +
> +#ifndef VHOST_USER_PROTOCOL_F_STATUS
> +#define VHOST_USER_PROTOCOL_F_STATUS 16
> +#endif
> +
> +#define VHOST_USER_SUPPORTED_PROTOCOL_FEATURES		\
> +	(1ULL << VHOST_USER_PROTOCOL_F_MQ |		\
> +	 1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK |	\
> +	 1ULL << VHOST_USER_PROTOCOL_F_STATUS)
> +
>  /* The version of the protocol we support */
>  #define VHOST_USER_VERSION    0x1
> 
> @@ -205,11 +228,11 @@ vhost_user_set_owner(struct virtio_user_dev *dev)
>  }
> 
>  static int
> -vhost_user_get_features(struct virtio_user_dev *dev, uint64_t *features)
> +vhost_user_get_protocol_features(struct virtio_user_dev *dev, uint64_t
> *features)
>  {
>  	int ret;
>  	struct vhost_user_msg msg = {
> -		.request = VHOST_USER_GET_FEATURES,
> +		.request = VHOST_USER_GET_PROTOCOL_FEATURES,
>  		.flags = VHOST_USER_VERSION,
>  	};
> 
> @@ -221,7 +244,7 @@ vhost_user_get_features(struct virtio_user_dev *dev,
> uint64_t *features)
>  	if (ret < 0)
>  		goto err;
> 
> -	if (msg.request != VHOST_USER_GET_FEATURES) {
> +	if (msg.request != VHOST_USER_GET_PROTOCOL_FEATURES) {
>  		PMD_DRV_LOG(ERR, "Unexpected request type (%d)", msg.request);
>  		goto err;
>  	}
> @@ -235,27 +258,25 @@ vhost_user_get_features(struct virtio_user_dev *dev,
> uint64_t *features)
> 
>  	return 0;
>  err:
> -	PMD_DRV_LOG(ERR, "Failed to get backend features");
> +	PMD_DRV_LOG(ERR, "Failed to get backend protocol features");
> 
>  	return -1;
>  }
> 
>  static int
> -vhost_user_set_features(struct virtio_user_dev *dev, uint64_t features)
> +vhost_user_set_protocol_features(struct virtio_user_dev *dev, uint64_t
> features)
>  {
>  	int ret;
>  	struct vhost_user_msg msg = {
> -		.request = VHOST_USER_SET_FEATURES,
> +		.request = VHOST_USER_SET_PROTOCOL_FEATURES,
>  		.flags = VHOST_USER_VERSION,
>  		.size = sizeof(features),
>  		.payload.u64 = features,
>  	};
> 
> -	msg.payload.u64 |= dev->device_features & (1ULL <<
> VHOST_USER_F_PROTOCOL_FEATURES);
> -
>  	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
>  	if (ret < 0) {
> -		PMD_DRV_LOG(ERR, "Failed to set features");
> +		PMD_DRV_LOG(ERR, "Failed to set protocol features");
>  		return -1;
>  	}
> 
> @@ -263,11 +284,11 @@ vhost_user_set_features(struct virtio_user_dev *dev,
> uint64_t features)
>  }
> 
>  static int
> -vhost_user_get_protocol_features(struct virtio_user_dev *dev, uint64_t
> *features)
> +vhost_user_get_features(struct virtio_user_dev *dev, uint64_t *features)
>  {
>  	int ret;
>  	struct vhost_user_msg msg = {
> -		.request = VHOST_USER_GET_PROTOCOL_FEATURES,
> +		.request = VHOST_USER_GET_FEATURES,
>  		.flags = VHOST_USER_VERSION,
>  	};
> 
> @@ -279,7 +300,7 @@ vhost_user_get_protocol_features(struct virtio_user_dev
> *dev, uint64_t *features
>  	if (ret < 0)
>  		goto err;
> 
> -	if (msg.request != VHOST_USER_GET_PROTOCOL_FEATURES) {
> +	if (msg.request != VHOST_USER_GET_FEATURES) {
>  		PMD_DRV_LOG(ERR, "Unexpected request type (%d)", msg.request);
>  		goto err;
>  	}
> @@ -291,27 +312,46 @@ vhost_user_get_protocol_features(struct virtio_user_dev
> *dev, uint64_t *features
> 
>  	*features = msg.payload.u64;
> 
> +	if (!(*features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)))
> +		return 0;
> +
> +	/* Negotiate protocol features */
> +	ret = vhost_user_get_protocol_features(dev, &dev->protocol_features);
> +	if (ret < 0)
> +		goto err;
> +
> +	dev->protocol_features &= VHOST_USER_SUPPORTED_PROTOCOL_FEATURES;
> +
> +	ret = vhost_user_set_protocol_features(dev, dev->protocol_features);
> +	if (ret < 0)
> +		goto err;
> +
> +	if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
> +		dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
> +
>  	return 0;
>  err:
> -	PMD_DRV_LOG(ERR, "Failed to get backend protocol features");
> +	PMD_DRV_LOG(ERR, "Failed to get backend features");
> 
>  	return -1;
>  }
> 
>  static int
> -vhost_user_set_protocol_features(struct virtio_user_dev *dev, uint64_t
> features)
> +vhost_user_set_features(struct virtio_user_dev *dev, uint64_t features)
>  {
>  	int ret;
>  	struct vhost_user_msg msg = {
> -		.request = VHOST_USER_SET_PROTOCOL_FEATURES,
> +		.request = VHOST_USER_SET_FEATURES,
>  		.flags = VHOST_USER_VERSION,
>  		.size = sizeof(features),
>  		.payload.u64 = features,
>  	};
> 
> +	msg.payload.u64 |= dev->device_features & (1ULL <<
> VHOST_USER_F_PROTOCOL_FEATURES);
> +
>  	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
>  	if (ret < 0) {
> -		PMD_DRV_LOG(ERR, "Failed to set protocol features");
> +		PMD_DRV_LOG(ERR, "Failed to set features");
>  		return -1;
>  	}
> 
> @@ -780,13 +820,20 @@ vhost_user_enable_queue_pair(struct virtio_user_dev *dev,
>  	return 0;
>  }
> 
> +static int
> +vhost_user_get_backend_features(uint64_t *features)
> +{
> +	*features = 1ULL << VHOST_USER_F_PROTOCOL_FEATURES;
> +
> +	return 0;
> +}
> +
>  struct virtio_user_backend_ops virtio_ops_user = {
>  	.setup = vhost_user_setup,
> +	.get_backend_features = vhost_user_get_backend_features,
>  	.set_owner = vhost_user_set_owner,
>  	.get_features = vhost_user_get_features,
>  	.set_features = vhost_user_set_features,
> -	.get_protocol_features = vhost_user_get_protocol_features,
> -	.set_protocol_features = vhost_user_set_protocol_features,
>  	.set_memory_table = vhost_user_set_memory_table,
>  	.set_vring_num = vhost_user_set_vring_num,
>  	.set_vring_base = vhost_user_set_vring_base,
> diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> index 7fb1249569..8d354b298e 100644
> --- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> +++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> @@ -13,6 +13,10 @@
>  #include "vhost.h"
>  #include "virtio_user_dev.h"
> 
> +#define VHOST_VDPA_SUPPORTED_BACKEND_FEATURES		\
> +	(1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2	|	\
> +	1ULL << VHOST_BACKEND_F_IOTLB_BATCH)
> +
>  /* vhost kernel & vdpa ioctls */
>  #define VHOST_VIRTIO 0xAF
>  #define VHOST_GET_FEATURES _IOR(VHOST_VIRTIO, 0x00, __u64)
> @@ -88,13 +92,13 @@ vhost_vdpa_set_owner(struct virtio_user_dev *dev)
>  }
> 
>  static int
> -vhost_vdpa_get_backend_features(struct virtio_user_dev *dev, uint64_t
> *features)
> +vhost_vdpa_get_protocol_features(struct virtio_user_dev *dev, uint64_t
> *features)
>  {
>  	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_GET_BACKEND_FEATURES,
> features);
>  }
> 
>  static int
> -vhost_vdpa_set_backend_features(struct virtio_user_dev *dev, uint64_t
> features)
> +vhost_vdpa_set_protocol_features(struct virtio_user_dev *dev, uint64_t
> features)
>  {
>  	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_BACKEND_FEATURES,
> &features);
>  }
> @@ -113,6 +117,21 @@ vhost_vdpa_get_features(struct virtio_user_dev *dev,
> uint64_t *features)
>  	/* Multiqueue not supported for now */
>  	*features &= ~(1ULL << VIRTIO_NET_F_MQ);
> 
> +	/* Negotiated vDPA backend features */
> +	ret = vhost_vdpa_get_protocol_features(dev, &dev->protocol_features);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Failed to get backend features");
> +		return -1;
> +	}
> +
> +	dev->protocol_features &= VHOST_VDPA_SUPPORTED_BACKEND_FEATURES;
> +
> +	ret = vhost_vdpa_set_protocol_features(dev, dev->protocol_features);
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Failed to set backend features");
> +		return -1;
> +	}
> +
>  	return 0;
>  }
> 
> @@ -438,13 +457,20 @@ vhost_vdpa_enable_queue_pair(struct virtio_user_dev *dev,
>  	return 0;
>  }
> 
> +static int
> +vhost_vdpa_get_backend_features(uint64_t *features)
> +{
> +	*features = 0;
> +
> +	return 0;
> +}
> +
>  struct virtio_user_backend_ops virtio_ops_vdpa = {
>  	.setup = vhost_vdpa_setup,
> +	.get_backend_features = vhost_vdpa_get_backend_features,
>  	.set_owner = vhost_vdpa_set_owner,
>  	.get_features = vhost_vdpa_get_features,
>  	.set_features = vhost_vdpa_set_features,
> -	.get_protocol_features = vhost_vdpa_get_backend_features,
> -	.set_protocol_features = vhost_vdpa_set_backend_features,
>  	.set_memory_table = vhost_vdpa_set_memory_table,
>  	.set_vring_num = vhost_vdpa_set_vring_num,
>  	.set_vring_base = vhost_vdpa_set_vring_base,
> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> index c2a41fe3a0..2614bcb349 100644
> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> @@ -480,24 +480,15 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
>  	 1ULL << VIRTIO_NET_F_GUEST_TSO6	|	\
>  	 1ULL << VIRTIO_F_IN_ORDER		|	\
>  	 1ULL << VIRTIO_F_VERSION_1		|	\
> -	 1ULL << VIRTIO_F_RING_PACKED		|	\
> -	 1ULL << VHOST_USER_F_PROTOCOL_FEATURES)
> +	 1ULL << VIRTIO_F_RING_PACKED)
> 
> -#define VHOST_USER_SUPPORTED_PROTOCOL_FEATURES		\
> -	(1ULL << VHOST_USER_PROTOCOL_F_MQ |		\
> -	 1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK |	\
> -	 1ULL << VHOST_USER_PROTOCOL_F_STATUS)
> -
> -#define VHOST_VDPA_SUPPORTED_PROTOCOL_FEATURES		\
> -	(1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2	|	\
> -	1ULL << VHOST_BACKEND_F_IOTLB_BATCH)
>  int
>  virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
>  		     int cq, int queue_size, const char *mac, char **ifname,
>  		     int server, int mrg_rxbuf, int in_order, int packed_vq,
>  		     enum virtio_user_backend_type backend_type)
>  {
> -	uint64_t protocol_features = 0;
> +	uint64_t backend_features;
> 
>  	pthread_mutex_init(&dev->mutex, NULL);
>  	strlcpy(dev->path, path, PATH_MAX);
> @@ -508,14 +499,9 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char
> *path, int queues,
>  	dev->is_server = server;
>  	dev->mac_specified = 0;
>  	dev->frontend_features = 0;
> -	dev->unsupported_features = ~VIRTIO_USER_SUPPORTED_FEATURES;
> +	dev->unsupported_features = 0;
>  	dev->backend_type = backend_type;
> 
> -	if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER)
> -		dev->protocol_features = VHOST_USER_SUPPORTED_PROTOCOL_FEATURES;
> -	else if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_VDPA)
> -		dev->protocol_features = VHOST_VDPA_SUPPORTED_PROTOCOL_FEATURES;
> -
>  	parse_mac(dev, mac);
> 
>  	if (*ifname) {
> @@ -528,38 +514,21 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char
> *path, int queues,
>  		return -1;
>  	}
> 
> -	if (dev->backend_type != VIRTIO_USER_BACKEND_VHOST_USER)
> -		dev->unsupported_features |=
> -			(1ULL << VHOST_USER_F_PROTOCOL_FEATURES);
> -
>  	if (dev->ops->set_owner(dev) < 0) {
>  		PMD_INIT_LOG(ERR, "(%s) Failed to set backend owner", dev->path);
>  		return -1;
>  	}
> 
> -	if (dev->ops->get_features(dev, &dev->device_features) < 0) {
> +	if (dev->ops->get_backend_features(&backend_features) < 0) {
>  		PMD_INIT_LOG(ERR, "(%s) Failed to get backend features", dev-
> >path);
>  		return -1;
>  	}
> 
> -	if ((dev->device_features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)) ||
> -			dev->backend_type == VIRTIO_USER_BACKEND_VHOST_VDPA) {
> -		if (dev->ops->get_protocol_features(dev, &protocol_features)) {
> -			PMD_INIT_LOG(ERR, "(%s) Failed to get backend protocol
> features",
> -					dev->path);
> -			return -1;
> -		}
> -
> -		dev->protocol_features &= protocol_features;
> -
> -		if (dev->ops->set_protocol_features(dev, dev->protocol_features))
> {
> -			PMD_INIT_LOG(ERR, "(%s) Failed to set backend protocol
> features",
> -					dev->path);
> -			return -1;
> -		}
> +	dev->unsupported_features = ~(VIRTIO_USER_SUPPORTED_FEATURES |
> backend_features);
> 
> -		if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
> -			dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
> +	if (dev->ops->get_features(dev, &dev->device_features) < 0) {
> +		PMD_INIT_LOG(ERR, "(%s) Failed to get device features", dev->path);
> +		return -1;
>  	}
> 
>  	if (!mrg_rxbuf)
> diff --git a/drivers/net/virtio/virtio_user_ethdev.c
> b/drivers/net/virtio/virtio_user_ethdev.c
> index e822d93690..e2c606a838 100644
> --- a/drivers/net/virtio/virtio_user_ethdev.c
> +++ b/drivers/net/virtio/virtio_user_ethdev.c
> @@ -70,7 +70,6 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev)
>  	int ret, connectfd, old_status;
>  	struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->port_id];
>  	struct virtio_hw *hw = &dev->hw;
> -	uint64_t protocol_features;
> 
>  	connectfd = accept(dev->listenfd, NULL, NULL);
>  	if (connectfd < 0)
> @@ -91,22 +90,6 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev)
>  		return -1;
>  	}
> 
> -	if (dev->device_features &
> -			(1ULL << VHOST_USER_F_PROTOCOL_FEATURES)) {
> -		if (dev->ops->get_protocol_features(dev, &protocol_features))
> -			return -1;
> -
> -		/* Offer VHOST_USER_PROTOCOL_F_STATUS */
> -		dev->protocol_features |= (1ULL << VHOST_USER_PROTOCOL_F_STATUS);
> -		dev->protocol_features &= protocol_features;
> -
> -		if (dev->ops->set_protocol_features(dev, dev->protocol_features))
> -			return -1;
> -
> -		if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
> -			dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
> -	}
> -
>  	dev->device_features |= dev->frontend_features;
> 
>  	/* umask vhost-user unsupported features */
> --
> 2.29.2

Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 39/44] net/virtio: introduce backend data
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 39/44] net/virtio: introduce backend data Maxime Coquelin
@ 2021-01-22  8:26   ` Xia, Chenbo
  0 siblings, 0 replies; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-22  8:26 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 39/44] net/virtio: introduce backend data
> 
> The goal of this patch is to introduce backend-specific
> data in order to better isolate what is backend-specific
> from what is generic to Virtio-user.
> 
> For now, only Vhost-user protocol features are moved to
> Vhost-user backend data.
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user/vhost.h        |  1 +
>  drivers/net/virtio/virtio_user/vhost_kernel.c |  7 +++
>  drivers/net/virtio/virtio_user/vhost_user.c   | 62 +++++++++++++++----
>  drivers/net/virtio/virtio_user/vhost_vdpa.c   |  7 +++
>  .../net/virtio/virtio_user/virtio_user_dev.c  |  2 +
>  .../net/virtio/virtio_user/virtio_user_dev.h  |  2 +
>  6 files changed, 68 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/vhost.h
> b/drivers/net/virtio/virtio_user/vhost.h
> index dfa2735a20..fc4f059c02 100644
> --- a/drivers/net/virtio/virtio_user/vhost.h
> +++ b/drivers/net/virtio/virtio_user/vhost.h
> @@ -65,6 +65,7 @@ struct virtio_user_dev;
> 
>  struct virtio_user_backend_ops {
>  	int (*setup)(struct virtio_user_dev *dev);
> +	int (*destroy)(struct virtio_user_dev *dev);
>  	int (*get_backend_features)(uint64_t *features);
>  	int (*set_owner)(struct virtio_user_dev *dev);
>  	int (*get_features)(struct virtio_user_dev *dev, uint64_t *features);
> diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c
> b/drivers/net/virtio/virtio_user/vhost_kernel.c
> index 5477eb7015..47fb4427be 100644
> --- a/drivers/net/virtio/virtio_user/vhost_kernel.c
> +++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
> @@ -357,6 +357,12 @@ vhost_kernel_setup(struct virtio_user_dev *dev)
>  	return 0;
>  }
> 
> +static int
> +vhost_kernel_destroy(struct virtio_user_dev *dev __rte_unused)
> +{
> +	return 0;
> +}
> +
>  static int
>  vhost_kernel_set_backend(int vhostfd, int tapfd)
>  {
> @@ -455,6 +461,7 @@ vhost_kernel_get_backend_features(uint64_t *features)
> 
>  struct virtio_user_backend_ops virtio_ops_kernel = {
>  	.setup = vhost_kernel_setup,
> +	.destroy = vhost_kernel_destroy,
>  	.get_backend_features = vhost_kernel_get_backend_features,
>  	.set_owner = vhost_kernel_set_owner,
>  	.get_features = vhost_kernel_get_features,
> diff --git a/drivers/net/virtio/virtio_user/vhost_user.c
> b/drivers/net/virtio/virtio_user/vhost_user.c
> index 986d8ac1ac..0147b6d963 100644
> --- a/drivers/net/virtio/virtio_user/vhost_user.c
> +++ b/drivers/net/virtio/virtio_user/vhost_user.c
> @@ -17,6 +17,9 @@
>  #include "vhost.h"
>  #include "virtio_user_dev.h"
> 
> +struct vhost_user_data {
> +	uint64_t protocol_features;
> +};
> 
>  #ifndef VHOST_USER_F_PROTOCOL_FEATURES
>  #define VHOST_USER_F_PROTOCOL_FEATURES 30
> @@ -287,6 +290,7 @@ static int
>  vhost_user_get_features(struct virtio_user_dev *dev, uint64_t *features)
>  {
>  	int ret;
> +	struct vhost_user_data *data = dev->backend_data;
>  	struct vhost_user_msg msg = {
>  		.request = VHOST_USER_GET_FEATURES,
>  		.flags = VHOST_USER_VERSION,
> @@ -316,17 +320,17 @@ vhost_user_get_features(struct virtio_user_dev *dev,
> uint64_t *features)
>  		return 0;
> 
>  	/* Negotiate protocol features */
> -	ret = vhost_user_get_protocol_features(dev, &dev->protocol_features);
> +	ret = vhost_user_get_protocol_features(dev, &data->protocol_features);
>  	if (ret < 0)
>  		goto err;
> 
> -	dev->protocol_features &= VHOST_USER_SUPPORTED_PROTOCOL_FEATURES;
> +	data->protocol_features &= VHOST_USER_SUPPORTED_PROTOCOL_FEATURES;
> 
> -	ret = vhost_user_set_protocol_features(dev, dev->protocol_features);
> +	ret = vhost_user_set_protocol_features(dev, data->protocol_features);
>  	if (ret < 0)
>  		goto err;
> 
> -	if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
> +	if (!(data->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)))
>  		dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
> 
>  	return 0;
> @@ -444,12 +448,13 @@ vhost_user_set_memory_table(struct virtio_user_dev *dev)
>  	struct walk_arg wa;
>  	int fds[VHOST_MEMORY_MAX_NREGIONS];
>  	int ret, fd_num;
> +	struct vhost_user_data *data = dev->backend_data;
>  	struct vhost_user_msg msg = {
>  		.request = VHOST_USER_SET_MEM_TABLE,
>  		.flags = VHOST_USER_VERSION,
>  	};
> 
> -	if (dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK))
> +	if (data->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK))
>  		msg.flags |= VHOST_USER_NEED_REPLY_MASK;
> 
>  	wa.region_nr = 0;
> @@ -628,6 +633,7 @@ static int
>  vhost_user_get_status(struct virtio_user_dev *dev, uint8_t *status)
>  {
>  	int ret;
> +	struct vhost_user_data *data = dev->backend_data;
>  	struct vhost_user_msg msg = {
>  		.request = VHOST_USER_GET_STATUS,
>  		.flags = VHOST_USER_VERSION,
> @@ -644,7 +650,7 @@ vhost_user_get_status(struct virtio_user_dev *dev, uint8_t
> *status)
>  	if (!(dev->device_features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)))
>  		return -ENOTSUP;
> 
> -	if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_STATUS)))
> +	if (!(data->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_STATUS)))
>  		return -ENOTSUP;
> 
>  	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
> @@ -681,6 +687,7 @@ static int
>  vhost_user_set_status(struct virtio_user_dev *dev, uint8_t status)
>  {
>  	int ret;
> +	struct vhost_user_data *data = dev->backend_data;
>  	struct vhost_user_msg msg = {
>  		.request = VHOST_USER_SET_STATUS,
>  		.flags = VHOST_USER_VERSION,
> @@ -699,10 +706,10 @@ vhost_user_set_status(struct virtio_user_dev *dev,
> uint8_t status)
>  	if (!(dev->device_features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)))
>  		return -ENOTSUP;
> 
> -	if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_STATUS)))
> +	if (!(data->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_STATUS)))
>  		return -ENOTSUP;
> 
> -	if (dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK))
> +	if (data->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK))
>  		msg.flags |= VHOST_USER_NEED_REPLY_MASK;
> 
>  	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
> @@ -762,11 +769,22 @@ vhost_user_setup(struct virtio_user_dev *dev)
>  	int fd;
>  	int flag;
>  	struct sockaddr_un un;
> +	struct vhost_user_data *data;
> +
> +	data = malloc(sizeof(*data));
> +	if (!data) {
> +		PMD_DRV_LOG(ERR, "(%s) Failed to allocate Vhost-user data\n", dev-
> >path);
> +		return -1;
> +	}
> +
> +	memset(data, 0, sizeof(*data));
> +
> +	dev->backend_data = data;
> 
>  	fd = socket(AF_UNIX, SOCK_STREAM, 0);
>  	if (fd < 0) {
>  		PMD_DRV_LOG(ERR, "socket() error, %s", strerror(errno));
> -		return -1;
> +		goto err_data;
>  	}
> 
>  	flag = fcntl(fd, F_GETFD);
> @@ -781,18 +799,35 @@ vhost_user_setup(struct virtio_user_dev *dev)
>  		dev->listenfd = fd;
>  		if (virtio_user_start_server(dev, &un) < 0) {
>  			PMD_DRV_LOG(ERR, "virtio-user startup fails in server mode");
> -			close(fd);
> -			return -1;
> +			goto err_socket;
>  		}
>  	} else {
>  		if (connect(fd, (struct sockaddr *)&un, sizeof(un)) < 0) {
>  			PMD_DRV_LOG(ERR, "connect error, %s", strerror(errno));
> -			close(fd);
> -			return -1;
> +			goto err_socket;
>  		}
>  		dev->vhostfd = fd;
>  	}
> 
> +	return 0;
> +
> +err_socket:
> +	close(fd);
> +err_data:
> +	free(data);
> +	dev->backend_data = NULL;
> +
> +	return -1;
> +}
> +
> +static int
> +vhost_user_destroy(struct virtio_user_dev *dev)
> +{
> +	if (dev->backend_data) {
> +		free(dev->backend_data);
> +		dev->backend_data = NULL;
> +	}
> +
>  	return 0;
>  }
> 
> @@ -830,6 +865,7 @@ vhost_user_get_backend_features(uint64_t *features)
> 
>  struct virtio_user_backend_ops virtio_ops_user = {
>  	.setup = vhost_user_setup,
> +	.destroy = vhost_user_destroy,
>  	.get_backend_features = vhost_user_get_backend_features,
>  	.set_owner = vhost_user_set_owner,
>  	.get_features = vhost_user_get_features,
> diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> index 8d354b298e..f5a8943993 100644
> --- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> +++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> @@ -432,6 +432,12 @@ vhost_vdpa_setup(struct virtio_user_dev *dev)
>  	return 0;
>  }
> 
> +static int
> +vhost_vdpa_destroy(struct virtio_user_dev *dev __rte_unused)
> +{
> +	return 0;
> +}
> +
>  static int
>  vhost_vdpa_enable_queue_pair(struct virtio_user_dev *dev,
>  			       uint16_t pair_idx,
> @@ -467,6 +473,7 @@ vhost_vdpa_get_backend_features(uint64_t *features)
> 
>  struct virtio_user_backend_ops virtio_ops_vdpa = {
>  	.setup = vhost_vdpa_setup,
> +	.destroy = vhost_vdpa_destroy,
>  	.get_backend_features = vhost_vdpa_get_backend_features,
>  	.set_owner = vhost_vdpa_set_owner,
>  	.get_features = vhost_vdpa_get_features,
> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> index 2614bcb349..215819d46d 100644
> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> @@ -621,6 +621,8 @@ virtio_user_dev_uninit(struct virtio_user_dev *dev)
> 
>  	if (dev->is_server)
>  		unlink(dev->path);
> +
> +	dev->ops->destroy(dev);
>  }
> 
>  uint8_t
> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h
> b/drivers/net/virtio/virtio_user/virtio_user_dev.h
> index ab62463a5b..7650097b6d 100644
> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
> @@ -66,6 +66,8 @@ struct virtio_user_dev {
>  	struct virtio_user_backend_ops *ops;
>  	pthread_mutex_t	mutex;
>  	bool		started;
> +
> +	void *backend_data;
>  };
> 
>  int virtio_user_dev_set_features(struct virtio_user_dev *dev);
> --
> 2.29.2

Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 27/44] net/virtio: add Virtio-user features ops
  2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 27/44] net/virtio: add Virtio-user features ops Maxime Coquelin
  2021-01-22  7:25   ` Xia, Chenbo
@ 2021-01-22  8:46   ` Xia, Chenbo
  1 sibling, 0 replies; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-22  8:46 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

Hi Maxime,

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 27/44] net/virtio: add Virtio-user features ops
> 
> This patch introduces new callbacks for getting
> and setting Virtio features, and implements them
> for the different backend types.
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user/vhost.h        |   2 +
>  drivers/net/virtio/virtio_user/vhost_kernel.c | 150 +++++++++---------
>  .../net/virtio/virtio_user/vhost_kernel_tap.c |  23 +++
>  .../net/virtio/virtio_user/vhost_kernel_tap.h |   1 +
>  drivers/net/virtio/virtio_user/vhost_user.c   |  64 +++++++-
>  drivers/net/virtio/virtio_user/vhost_vdpa.c   |  38 +++--
>  .../net/virtio/virtio_user/virtio_user_dev.c  |   5 +-
>  drivers/net/virtio/virtio_user_ethdev.c       |   3 +-
>  8 files changed, 190 insertions(+), 96 deletions(-)
> 

<snip>

> +
> +	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
> +	if (ret < 0)
> +		goto err;
> +
> +	ret = vhost_user_read(dev->vhostfd, &msg);
> +	if (ret < 0)
> +		goto err;

Sorry...just forgot you add a log in vhost_user_write. So it's ok not to log here..
Just ignore my similar comment.

Thanks,
Chenbo

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 40/44] net/virtio: move Vhost-user specifics to its backend
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 40/44] net/virtio: move Vhost-user specifics to its backend Maxime Coquelin
@ 2021-01-22  8:49   ` Xia, Chenbo
  0 siblings, 0 replies; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-22  8:49 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 40/44] net/virtio: move Vhost-user specifics to its backend
> 
> This patch moves all the Vhost-user backend specific
> logic like Vhost FD, listen FD and interrupt handling
> to the vhost-user backend implementation.
> 
> In order to achieve that, new ops are created to update
> the link status, disconnect and reconnect the server,
> and fetch the link state interrupt FD.
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user/vhost.h        |   4 +
>  drivers/net/virtio/virtio_user/vhost_kernel.c |  18 +-
>  drivers/net/virtio/virtio_user/vhost_user.c   | 176 ++++++++++++++---
>  drivers/net/virtio/virtio_user/vhost_vdpa.c   |  16 ++
>  .../net/virtio/virtio_user/virtio_user_dev.c  | 181 +++++++++++++++---
>  .../net/virtio/virtio_user/virtio_user_dev.h  |   9 +-
>  drivers/net/virtio/virtio_user_ethdev.c       | 179 +----------------
>  7 files changed, 350 insertions(+), 233 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/vhost.h
> b/drivers/net/virtio/virtio_user/vhost.h
> index fc4f059c02..c49e88036d 100644
> --- a/drivers/net/virtio/virtio_user/vhost.h
> +++ b/drivers/net/virtio/virtio_user/vhost.h
> @@ -82,6 +82,10 @@ struct virtio_user_backend_ops {
>  	int (*enable_qp)(struct virtio_user_dev *dev, uint16_t pair_idx, int
> enable);
>  	int (*dma_map)(struct virtio_user_dev *dev, void *addr, uint64_t iova,
> size_t len);
>  	int (*dma_unmap)(struct virtio_user_dev *dev, void *addr, uint64_t iova,
> size_t len);
> +	int (*update_link_state)(struct virtio_user_dev *dev);
> +	int (*server_disconnect)(struct virtio_user_dev *dev);
> +	int (*server_reconnect)(struct virtio_user_dev *dev);
> +	int (*get_intr_fd)(struct virtio_user_dev *dev);
>  };
> 
>  extern struct virtio_user_backend_ops virtio_ops_user;
> diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c
> b/drivers/net/virtio/virtio_user/vhost_kernel.c
> index 47fb4427be..aa1f9ece5e 100644
> --- a/drivers/net/virtio/virtio_user/vhost_kernel.c
> +++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
> @@ -459,6 +459,20 @@ vhost_kernel_get_backend_features(uint64_t *features)
>  	return 0;
>  }
> 
> +static int
> +vhost_kernel_update_link_state(struct virtio_user_dev *dev __rte_unused)
> +{
> +	/* Nothing to update (Maybe get TAP interface link state?) */
> +	return 0;
> +}
> +
> +static int
> +vhost_kernel_get_intr_fd(struct virtio_user_dev *dev __rte_unused)
> +{
> +	/* No link state interrupt with Vhost-kernel */
> +	return -1;
> +}
> +
>  struct virtio_user_backend_ops virtio_ops_kernel = {
>  	.setup = vhost_kernel_setup,
>  	.destroy = vhost_kernel_destroy,
> @@ -475,5 +489,7 @@ struct virtio_user_backend_ops virtio_ops_kernel = {
>  	.set_vring_addr = vhost_kernel_set_vring_addr,
>  	.get_status = vhost_kernel_get_status,
>  	.set_status = vhost_kernel_set_status,
> -	.enable_qp = vhost_kernel_enable_queue_pair
> +	.enable_qp = vhost_kernel_enable_queue_pair,
> +	.update_link_state = vhost_kernel_update_link_state,
> +	.get_intr_fd = vhost_kernel_get_intr_fd,
>  };
> diff --git a/drivers/net/virtio/virtio_user/vhost_user.c
> b/drivers/net/virtio/virtio_user/vhost_user.c
> index 0147b6d963..f046655af6 100644
> --- a/drivers/net/virtio/virtio_user/vhost_user.c
> +++ b/drivers/net/virtio/virtio_user/vhost_user.c
> @@ -11,6 +11,7 @@
>  #include <string.h>
>  #include <errno.h>
> 
> +#include <rte_alarm.h>
>  #include <rte_string_fns.h>
>  #include <rte_fbarray.h>
> 
> @@ -18,6 +19,8 @@
>  #include "virtio_user_dev.h"
> 
>  struct vhost_user_data {
> +	int vhostfd;
> +	int listenfd;
>  	uint64_t protocol_features;
>  };
> 
> @@ -182,13 +185,14 @@ vhost_user_read(int fd, struct vhost_user_msg *msg)
>  static int
>  vhost_user_check_reply_ack(struct virtio_user_dev *dev, struct vhost_user_msg
> *msg)
>  {
> +	struct vhost_user_data *data = dev->backend_data;
>  	enum vhost_user_request req = msg->request;
>  	int ret;
> 
>  	if (!(msg->flags & VHOST_USER_NEED_REPLY_MASK))
>  		return 0;
> 
> -	ret = vhost_user_read(dev->vhostfd, msg);
> +	ret = vhost_user_read(data->vhostfd, msg);
>  	if (ret < 0) {
>  		PMD_DRV_LOG(ERR, "Failed to read reply-ack");
>  		return -1;
> @@ -216,12 +220,13 @@ static int
>  vhost_user_set_owner(struct virtio_user_dev *dev)
>  {
>  	int ret;
> +	struct vhost_user_data *data = dev->backend_data;
>  	struct vhost_user_msg msg = {
>  		.request = VHOST_USER_SET_OWNER,
>  		.flags = VHOST_USER_VERSION,
>  	};
> 
> -	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
> +	ret = vhost_user_write(data->vhostfd, &msg, NULL, 0);
>  	if (ret < 0) {
>  		PMD_DRV_LOG(ERR, "Failed to set owner");
>  		return -1;
> @@ -234,16 +239,17 @@ static int
>  vhost_user_get_protocol_features(struct virtio_user_dev *dev, uint64_t
> *features)
>  {
>  	int ret;
> +	struct vhost_user_data *data = dev->backend_data;
>  	struct vhost_user_msg msg = {
>  		.request = VHOST_USER_GET_PROTOCOL_FEATURES,
>  		.flags = VHOST_USER_VERSION,
>  	};
> 
> -	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
> +	ret = vhost_user_write(data->vhostfd, &msg, NULL, 0);
>  	if (ret < 0)
>  		goto err;
> 
> -	ret = vhost_user_read(dev->vhostfd, &msg);
> +	ret = vhost_user_read(data->vhostfd, &msg);
>  	if (ret < 0)
>  		goto err;
> 
> @@ -270,6 +276,7 @@ static int
>  vhost_user_set_protocol_features(struct virtio_user_dev *dev, uint64_t
> features)
>  {
>  	int ret;
> +	struct vhost_user_data *data = dev->backend_data;
>  	struct vhost_user_msg msg = {
>  		.request = VHOST_USER_SET_PROTOCOL_FEATURES,
>  		.flags = VHOST_USER_VERSION,
> @@ -277,7 +284,7 @@ vhost_user_set_protocol_features(struct virtio_user_dev
> *dev, uint64_t features)
>  		.payload.u64 = features,
>  	};
> 
> -	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
> +	ret = vhost_user_write(data->vhostfd, &msg, NULL, 0);
>  	if (ret < 0) {
>  		PMD_DRV_LOG(ERR, "Failed to set protocol features");
>  		return -1;
> @@ -296,11 +303,11 @@ vhost_user_get_features(struct virtio_user_dev *dev,
> uint64_t *features)
>  		.flags = VHOST_USER_VERSION,
>  	};
> 
> -	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
> +	ret = vhost_user_write(data->vhostfd, &msg, NULL, 0);
>  	if (ret < 0)
>  		goto err;
> 
> -	ret = vhost_user_read(dev->vhostfd, &msg);
> +	ret = vhost_user_read(data->vhostfd, &msg);
>  	if (ret < 0)
>  		goto err;
> 
> @@ -344,6 +351,7 @@ static int
>  vhost_user_set_features(struct virtio_user_dev *dev, uint64_t features)
>  {
>  	int ret;
> +	struct vhost_user_data *data = dev->backend_data;
>  	struct vhost_user_msg msg = {
>  		.request = VHOST_USER_SET_FEATURES,
>  		.flags = VHOST_USER_VERSION,
> @@ -353,7 +361,7 @@ vhost_user_set_features(struct virtio_user_dev *dev,
> uint64_t features)
> 
>  	msg.payload.u64 |= dev->device_features & (1ULL <<
> VHOST_USER_F_PROTOCOL_FEATURES);
> 
> -	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
> +	ret = vhost_user_write(data->vhostfd, &msg, NULL, 0);
>  	if (ret < 0) {
>  		PMD_DRV_LOG(ERR, "Failed to set features");
>  		return -1;
> @@ -477,7 +485,7 @@ vhost_user_set_memory_table(struct virtio_user_dev *dev)
>  	msg.size += sizeof(msg.payload.memory.padding);
>  	msg.size += fd_num * sizeof(struct vhost_memory_region);
> 
> -	ret = vhost_user_write(dev->vhostfd, &msg, fds, fd_num);
> +	ret = vhost_user_write(data->vhostfd, &msg, fds, fd_num);
>  	if (ret < 0)
>  		goto err;
> 
> @@ -492,6 +500,7 @@ vhost_user_set_vring(struct virtio_user_dev *dev, enum
> vhost_user_request req,
>  		struct vhost_vring_state *state)
>  {
>  	int ret;
> +	struct vhost_user_data *data = dev->backend_data;
>  	struct vhost_user_msg msg = {
>  		.request = req,
>  		.flags = VHOST_USER_VERSION,
> @@ -499,7 +508,7 @@ vhost_user_set_vring(struct virtio_user_dev *dev, enum
> vhost_user_request req,
>  		.payload.state = *state,
>  	};
> 
> -	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
> +	ret = vhost_user_write(data->vhostfd, &msg, NULL, 0);
>  	if (ret < 0) {
>  		PMD_DRV_LOG(ERR, "Failed to set vring state (request %d)", req);
>  		return -1;
> @@ -531,6 +540,7 @@ vhost_user_get_vring_base(struct virtio_user_dev *dev,
> struct vhost_vring_state
>  {
>  	int ret;
>  	struct vhost_user_msg msg;
> +	struct vhost_user_data *data = dev->backend_data;
>  	unsigned int index = state->index;
> 
>  	ret = vhost_user_set_vring(dev, VHOST_USER_GET_VRING_BASE, state);
> @@ -539,7 +549,7 @@ vhost_user_get_vring_base(struct virtio_user_dev *dev,
> struct vhost_vring_state
>  		goto err;
>  	}
> 
> -	ret = vhost_user_read(dev->vhostfd, &msg);
> +	ret = vhost_user_read(data->vhostfd, &msg);
>  	if (ret < 0) {
>  		PMD_DRV_LOG(ERR, "Failed to read reply");
>  		goto err;
> @@ -575,6 +585,7 @@ vhost_user_set_vring_file(struct virtio_user_dev *dev,
> enum vhost_user_request r
>  	int ret;
>  	int fd = file->fd;
>  	int num_fd = 0;
> +	struct vhost_user_data *data = dev->backend_data;
>  	struct vhost_user_msg msg = {
>  		.request = req,
>  		.flags = VHOST_USER_VERSION,
> @@ -587,7 +598,7 @@ vhost_user_set_vring_file(struct virtio_user_dev *dev,
> enum vhost_user_request r
>  	else
>  		msg.payload.u64 |= VHOST_USER_VRING_NOFD_MASK;
> 
> -	ret = vhost_user_write(dev->vhostfd, &msg, &fd, num_fd);
> +	ret = vhost_user_write(data->vhostfd, &msg, &fd, num_fd);
>  	if (ret < 0) {
>  		PMD_DRV_LOG(ERR, "Failed to set vring file (request %d)", req);
>  		return -1;
> @@ -613,6 +624,7 @@ static int
>  vhost_user_set_vring_addr(struct virtio_user_dev *dev, struct
> vhost_vring_addr *addr)
>  {
>  	int ret;
> +	struct vhost_user_data *data = dev->backend_data;
>  	struct vhost_user_msg msg = {
>  		.request = VHOST_USER_SET_VRING_ADDR,
>  		.flags = VHOST_USER_VERSION,
> @@ -620,7 +632,7 @@ vhost_user_set_vring_addr(struct virtio_user_dev *dev,
> struct vhost_vring_addr *
>  		.payload.addr = *addr,
>  	};
> 
> -	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
> +	ret = vhost_user_write(data->vhostfd, &msg, NULL, 0);
>  	if (ret < 0) {
>  		PMD_DRV_LOG(ERR, "Failed to send vring addresses");
>  		return -1;
> @@ -653,13 +665,13 @@ vhost_user_get_status(struct virtio_user_dev *dev,
> uint8_t *status)
>  	if (!(data->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_STATUS)))
>  		return -ENOTSUP;
> 
> -	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
> +	ret = vhost_user_write(data->vhostfd, &msg, NULL, 0);
>  	if (ret < 0) {
>  		PMD_DRV_LOG(ERR, "Failed to send request");
>  		goto err;
>  	}
> 
> -	ret = vhost_user_read(dev->vhostfd, &msg);
> +	ret = vhost_user_read(data->vhostfd, &msg);
>  	if (ret < 0) {
>  		PMD_DRV_LOG(ERR, "Failed to recv request");
>  		goto err;
> @@ -712,7 +724,7 @@ vhost_user_set_status(struct virtio_user_dev *dev, uint8_t
> status)
>  	if (data->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK))
>  		msg.flags |= VHOST_USER_NEED_REPLY_MASK;
> 
> -	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
> +	ret = vhost_user_write(data->vhostfd, &msg, NULL, 0);
>  	if (ret < 0) {
>  		PMD_DRV_LOG(ERR, "Failed to send get status request");
>  		return -1;
> @@ -723,11 +735,12 @@ vhost_user_set_status(struct virtio_user_dev *dev,
> uint8_t status)
> 
>  #define MAX_VIRTIO_USER_BACKLOG 1
>  static int
> -virtio_user_start_server(struct virtio_user_dev *dev, struct sockaddr_un *un)
> +vhost_user_start_server(struct virtio_user_dev *dev, struct sockaddr_un *un)
>  {
>  	int ret;
>  	int flag;
> -	int fd = dev->listenfd;
> +	struct vhost_user_data *data = dev->backend_data;
> +	int fd = data->listenfd;
> 
>  	ret = bind(fd, (struct sockaddr *)un, sizeof(*un));
>  	if (ret < 0) {
> @@ -740,8 +753,8 @@ virtio_user_start_server(struct virtio_user_dev *dev,
> struct sockaddr_un *un)
>  		return -1;
> 
>  	PMD_DRV_LOG(NOTICE, "(%s) waiting for client connection...", dev->path);
> -	dev->vhostfd = accept(fd, NULL, NULL);
> -	if (dev->vhostfd < 0) {
> +	data->vhostfd = accept(fd, NULL, NULL);
> +	if (data->vhostfd < 0) {
>  		PMD_DRV_LOG(ERR, "Failed to accept initial client connection (%s)",
>  				strerror(errno));
>  		return -1;
> @@ -756,6 +769,37 @@ virtio_user_start_server(struct virtio_user_dev *dev,
> struct sockaddr_un *un)
>  	return 0;
>  }
> 
> +static int
> +vhost_user_server_disconnect(struct virtio_user_dev *dev)
> +{
> +	struct vhost_user_data *data = dev->backend_data;
> +
> +	if (data->vhostfd < 0) {
> +		PMD_DRV_LOG(ERR, "(%s) Expected valid Vhost FD", dev->path);
> +		return -1;
> +	}
> +
> +	close(data->vhostfd);
> +	data->vhostfd = -1;
> +
> +	return 0;
> +}
> +
> +static int
> +vhost_user_server_reconnect(struct virtio_user_dev *dev)
> +{
> +	struct vhost_user_data *data = dev->backend_data;
> +	int fd;
> +
> +	fd = accept(data->listenfd, NULL, NULL);
> +	if (fd < 0)
> +		return -1;
> +
> +	data->vhostfd = fd;
> +
> +	return 0;
> +}
> +
>  /**
>   * Set up environment to talk with a vhost user backend.
>   *
> @@ -781,6 +825,8 @@ vhost_user_setup(struct virtio_user_dev *dev)
> 
>  	dev->backend_data = data;
> 
> +	data->vhostfd = -1;
> +
>  	fd = socket(AF_UNIX, SOCK_STREAM, 0);
>  	if (fd < 0) {
>  		PMD_DRV_LOG(ERR, "socket() error, %s", strerror(errno));
> @@ -796,8 +842,8 @@ vhost_user_setup(struct virtio_user_dev *dev)
>  	strlcpy(un.sun_path, dev->path, sizeof(un.sun_path));
> 
>  	if (dev->is_server) {
> -		dev->listenfd = fd;
> -		if (virtio_user_start_server(dev, &un) < 0) {
> +		data->listenfd = fd;
> +		if (vhost_user_start_server(dev, &un) < 0) {
>  			PMD_DRV_LOG(ERR, "virtio-user startup fails in server mode");
>  			goto err_socket;
>  		}
> @@ -806,7 +852,7 @@ vhost_user_setup(struct virtio_user_dev *dev)
>  			PMD_DRV_LOG(ERR, "connect error, %s", strerror(errno));
>  			goto err_socket;
>  		}
> -		dev->vhostfd = fd;
> +		data->vhostfd = fd;
>  	}
> 
>  	return 0;
> @@ -823,11 +869,24 @@ vhost_user_setup(struct virtio_user_dev *dev)
>  static int
>  vhost_user_destroy(struct virtio_user_dev *dev)
>  {
> -	if (dev->backend_data) {
> -		free(dev->backend_data);
> -		dev->backend_data = NULL;
> +	struct vhost_user_data *data = dev->backend_data;
> +
> +	if (!data)
> +		return 0;
> +
> +	if (data->vhostfd >= 0) {
> +		close(data->vhostfd);
> +		data->vhostfd = -1;
>  	}
> 
> +	if (data->listenfd >= 0) {
> +		close(data->listenfd);
> +		data->listenfd = -1;
> +	}
> +
> +	free(data);
> +	dev->backend_data = NULL;
> +
>  	return 0;
>  }
> 
> @@ -836,8 +895,12 @@ vhost_user_enable_queue_pair(struct virtio_user_dev *dev,
>  			     uint16_t pair_idx,
>  			     int enable)
>  {
> +	struct vhost_user_data *data = dev->backend_data;
>  	int i;
> 
> +	if (data->vhostfd < 0)
> +		return 0;
> +
>  	if (dev->qp_enabled[pair_idx] == enable)
>  		return 0;
> 
> @@ -863,6 +926,61 @@ vhost_user_get_backend_features(uint64_t *features)
>  	return 0;
>  }
> 
> +static int
> +vhost_user_update_link_state(struct virtio_user_dev *dev)
> +{
> +	struct vhost_user_data *data = dev->backend_data;
> +	char buf[128];
> +
> +	if (data->vhostfd >= 0) {
> +		int r;
> +		int flags;
> +
> +		flags = fcntl(data->vhostfd, F_GETFL);
> +		if (fcntl(data->vhostfd, F_SETFL, flags | O_NONBLOCK) == -1) {
> +			PMD_DRV_LOG(ERR, "error setting O_NONBLOCK flag");
> +			return -1;
> +		}
> +
> +		r = recv(data->vhostfd, buf, 128, MSG_PEEK);
> +		if (r == 0 || (r < 0 && errno != EAGAIN)) {
> +			dev->net_status &= (~VIRTIO_NET_S_LINK_UP);
> +			PMD_DRV_LOG(ERR, "virtio-user port %u is down", dev-
> >port_id);
> +
> +			/* This function could be called in the process
> +			 * of interrupt handling, callback cannot be
> +			 * unregistered here, set an alarm to do it.
> +			 */
> +			rte_eal_alarm_set(1, virtio_user_dev_delayed_handler, (void
> *)dev);
> +		} else {
> +			dev->net_status |= VIRTIO_NET_S_LINK_UP;
> +		}
> +
> +		if (fcntl(data->vhostfd, F_SETFL,
> +					flags & ~O_NONBLOCK) == -1) {
> +			PMD_DRV_LOG(ERR, "error clearing O_NONBLOCK flag");
> +			return -1;
> +		}
> +	} else if (dev->is_server) {
> +		dev->net_status &= (~VIRTIO_NET_S_LINK_UP);
> +		if (virtio_user_dev_server_reconnect(dev) >= 0)
> +			dev->net_status |= VIRTIO_NET_S_LINK_UP;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +vhost_user_get_intr_fd(struct virtio_user_dev *dev)
> +{
> +	struct vhost_user_data *data = dev->backend_data;
> +
> +	if (dev->is_server && data->vhostfd == -1)
> +		return data->listenfd;
> +
> +	return data->vhostfd;
> +}
> +
>  struct virtio_user_backend_ops virtio_ops_user = {
>  	.setup = vhost_user_setup,
>  	.destroy = vhost_user_destroy,
> @@ -879,5 +997,9 @@ struct virtio_user_backend_ops virtio_ops_user = {
>  	.set_vring_addr = vhost_user_set_vring_addr,
>  	.get_status = vhost_user_get_status,
>  	.set_status = vhost_user_set_status,
> -	.enable_qp = vhost_user_enable_queue_pair
> +	.enable_qp = vhost_user_enable_queue_pair,
> +	.update_link_state = vhost_user_update_link_state,
> +	.server_disconnect = vhost_user_server_disconnect,
> +	.server_reconnect = vhost_user_server_reconnect,
> +	.get_intr_fd = vhost_user_get_intr_fd,
>  };
> diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> index f5a8943993..5e3778b682 100644
> --- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> +++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> @@ -471,6 +471,20 @@ vhost_vdpa_get_backend_features(uint64_t *features)
>  	return 0;
>  }
> 
> +static int
> +vhost_vdpa_update_link_state(struct virtio_user_dev *dev __rte_unused)
> +{
> +	/* Nothing to update (for now?) */
> +	return 0;
> +}
> +
> +static int
> +vhost_vdpa_get_intr_fd(struct virtio_user_dev *dev __rte_unused)
> +{
> +	/* No link state interrupt with Vhost-vDPA */
> +	return -1;
> +}
> +
>  struct virtio_user_backend_ops virtio_ops_vdpa = {
>  	.setup = vhost_vdpa_setup,
>  	.destroy = vhost_vdpa_destroy,
> @@ -490,4 +504,6 @@ struct virtio_user_backend_ops virtio_ops_vdpa = {
>  	.enable_qp = vhost_vdpa_enable_queue_pair,
>  	.dma_map = vhost_vdpa_dma_map_batch,
>  	.dma_unmap = vhost_vdpa_dma_unmap_batch,
> +	.update_link_state = vhost_vdpa_update_link_state,
> +	.get_intr_fd = vhost_vdpa_get_intr_fd,
>  };
> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> index 215819d46d..7128457e32 100644
> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> @@ -343,11 +343,7 @@ virtio_user_fill_intr_handle(struct virtio_user_dev *dev)
>  	eth_dev->intr_handle->type = RTE_INTR_HANDLE_VDEV;
>  	/* For virtio vdev, no need to read counter for clean */
>  	eth_dev->intr_handle->efd_counter_size = 0;
> -	eth_dev->intr_handle->fd = -1;
> -	if (dev->vhostfd >= 0)
> -		eth_dev->intr_handle->fd = dev->vhostfd;
> -	else if (dev->is_server)
> -		eth_dev->intr_handle->fd = dev->listenfd;
> +	eth_dev->intr_handle->fd = dev->ops->get_intr_fd(dev);
> 
>  	return 0;
>  }
> @@ -404,7 +400,6 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
>  {
>  	uint32_t q;
> 
> -	dev->vhostfd = -1;
>  	dev->vhostfds = NULL;
>  	dev->tapfds = NULL;
> 
> @@ -598,15 +593,6 @@ virtio_user_dev_uninit(struct virtio_user_dev *dev)
>  		close(dev->callfds[i]);
>  		close(dev->kickfds[i]);
>  	}
> -
> -	if (dev->vhostfd >= 0)
> -		close(dev->vhostfd);
> -
> -	if (dev->is_server && dev->listenfd >= 0) {
> -		close(dev->listenfd);
> -		dev->listenfd = -1;
> -	}
> -
>  	if (dev->vhostfds) {
>  		for (i = 0; i < dev->max_queue_pairs; ++i) {
>  			close(dev->vhostfds[i]);
> @@ -637,15 +623,11 @@ virtio_user_handle_mq(struct virtio_user_dev *dev,
> uint16_t q_pairs)
>  		return -1;
>  	}
> 
> -	/* Server mode can't enable queue pairs if vhostfd is invalid,
> -	 * always return 0 in this case.
> -	 */
> -	if (!dev->is_server || dev->vhostfd >= 0) {
> -		for (i = 0; i < q_pairs; ++i)
> -			ret |= dev->ops->enable_qp(dev, i, 1);
> -		for (i = q_pairs; i < dev->max_queue_pairs; ++i)
> -			ret |= dev->ops->enable_qp(dev, i, 0);
> -	}
> +	for (i = 0; i < q_pairs; ++i)
> +		ret |= dev->ops->enable_qp(dev, i, 1);
> +	for (i = q_pairs; i < dev->max_queue_pairs; ++i)
> +		ret |= dev->ops->enable_qp(dev, i, 0);
> +
>  	dev->queue_pairs = q_pairs;
> 
>  	return ret;
> @@ -860,3 +842,154 @@ virtio_user_dev_update_status(struct virtio_user_dev
> *dev)
>  	pthread_mutex_unlock(&dev->mutex);
>  	return ret;
>  }
> +
> +int
> +virtio_user_dev_update_link_state(struct virtio_user_dev *dev)
> +{
> +	if (dev->ops->update_link_state)
> +		return dev->ops->update_link_state(dev);
> +
> +	return 0;
> +}
> +
> +static void
> +virtio_user_dev_reset_queues_packed(struct rte_eth_dev *eth_dev)
> +{
> +	struct virtio_user_dev *dev = eth_dev->data->dev_private;
> +	struct virtio_hw *hw = &dev->hw;
> +	struct virtnet_rx *rxvq;
> +	struct virtnet_tx *txvq;
> +	uint16_t i;
> +
> +	/* Add lock to avoid queue contention. */
> +	rte_spinlock_lock(&hw->state_lock);
> +	hw->started = 0;
> +
> +	/*
> +	 * Waiting for datapath to complete before resetting queues.
> +	 * 1 ms should be enough for the ongoing Tx/Rx function to finish.
> +	 */
> +	rte_delay_ms(1);
> +
> +	/* Vring reset for each Tx queue and Rx queue. */
> +	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
> +		rxvq = eth_dev->data->rx_queues[i];
> +		virtqueue_rxvq_reset_packed(rxvq->vq);
> +		virtio_dev_rx_queue_setup_finish(eth_dev, i);
> +	}
> +
> +	for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
> +		txvq = eth_dev->data->tx_queues[i];
> +		virtqueue_txvq_reset_packed(txvq->vq);
> +	}
> +
> +	hw->started = 1;
> +	rte_spinlock_unlock(&hw->state_lock);
> +}
> +
> +void
> +virtio_user_dev_delayed_handler(void *param)
> +{
> +	struct virtio_user_dev *dev = param;
> +	struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->port_id];
> +
> +	if (rte_intr_disable(eth_dev->intr_handle) < 0) {
> +		PMD_DRV_LOG(ERR, "interrupt disable failed");
> +		return;
> +	}
> +	rte_intr_callback_unregister(eth_dev->intr_handle,
> +				     virtio_interrupt_handler, eth_dev);
> +	if (dev->is_server) {
> +		if (dev->ops->server_disconnect)
> +			dev->ops->server_disconnect(dev);
> +		eth_dev->intr_handle->fd = dev->ops->get_intr_fd(dev);
> +		rte_intr_callback_register(eth_dev->intr_handle,
> +					   virtio_interrupt_handler, eth_dev);
> +		if (rte_intr_enable(eth_dev->intr_handle) < 0) {
> +			PMD_DRV_LOG(ERR, "interrupt enable failed");
> +			return;
> +		}
> +	}
> +}
> +
> +int
> +virtio_user_dev_server_reconnect(struct virtio_user_dev *dev)
> +{
> +	int ret, old_status;
> +	struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->port_id];
> +	struct virtio_hw *hw = &dev->hw;
> +
> +	if (!dev->ops->server_reconnect) {
> +		PMD_DRV_LOG(ERR, "(%s) Missing server reconnect callback", dev-
> >path);
> +		return -1;
> +	}
> +
> +	if (dev->ops->server_reconnect(dev)) {
> +		PMD_DRV_LOG(ERR, "(%s) Reconnect callback call failed", dev->path);
> +		return -1;
> +	}
> +
> +	old_status = dev->status;
> +
> +	virtio_reset(hw);
> +
> +	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_ACK);
> +
> +	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);
> +
> +	if (dev->ops->get_features(dev, &dev->device_features) < 0) {
> +		PMD_INIT_LOG(ERR, "get_features failed: %s",
> +			     strerror(errno));
> +		return -1;
> +	}
> +
> +	dev->device_features |= dev->frontend_features;
> +
> +	/* unmask vhost-user unsupported features */
> +	dev->device_features &= ~(dev->unsupported_features);
> +
> +	dev->features &= dev->device_features;
> +
> +	/* For packed ring, resetting queues is required in reconnection. */
> +	if (virtio_with_packed_queue(hw) &&
> +	   (old_status & VIRTIO_CONFIG_STATUS_DRIVER_OK)) {
> +		PMD_INIT_LOG(NOTICE, "Packets on the fly will be dropped"
> +				" when packed ring reconnecting.");
> +		virtio_user_dev_reset_queues_packed(eth_dev);
> +	}
> +
> +	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_FEATURES_OK);
> +
> +	/* Start the device */
> +	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER_OK);
> +	if (!dev->started)
> +		return -1;
> +
> +	if (dev->queue_pairs > 1) {
> +		ret = virtio_user_handle_mq(dev, dev->queue_pairs);
> +		if (ret != 0) {
> +			PMD_INIT_LOG(ERR, "Fails to enable multi-queue pairs!");
> +			return -1;
> +		}
> +	}
> +	if (eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC) {
> +		if (rte_intr_disable(eth_dev->intr_handle) < 0) {
> +			PMD_DRV_LOG(ERR, "interrupt disable failed");
> +			return -1;
> +		}
> +		rte_intr_callback_unregister(eth_dev->intr_handle,
> +					     virtio_interrupt_handler,
> +					     eth_dev);
> +
> +		eth_dev->intr_handle->fd = dev->ops->get_intr_fd(dev);
> +		rte_intr_callback_register(eth_dev->intr_handle,
> +					   virtio_interrupt_handler, eth_dev);
> +
> +		if (rte_intr_enable(eth_dev->intr_handle) < 0) {
> +			PMD_DRV_LOG(ERR, "interrupt enable failed");
> +			return -1;
> +		}
> +	}
> +	PMD_INIT_LOG(NOTICE, "server mode virtio-user reconnection succeeds!");
> +	return 0;
> +}
> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h
> b/drivers/net/virtio/virtio_user/virtio_user_dev.h
> index 7650097b6d..36d2410546 100644
> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
> @@ -27,11 +27,11 @@ struct virtio_user_queue {
>  struct virtio_user_dev {
>  	struct virtio_hw hw;
>  	enum virtio_user_backend_type backend_type;
> -	/* for vhost_user backend */
> -	int		vhostfd;
> -	int		listenfd;   /* listening fd */
>  	bool		is_server;  /* server or client mode */
> 
> +	/* for vhost_vdpa backend */
> +	int		vhostfd;
> +
>  	/* for vhost_kernel backend */
>  	char		*ifname;
>  	int		*vhostfds;
> @@ -85,5 +85,8 @@ void virtio_user_handle_cq_packed(struct virtio_user_dev
> *dev,
>  uint8_t virtio_user_handle_mq(struct virtio_user_dev *dev, uint16_t q_pairs);
>  int virtio_user_dev_set_status(struct virtio_user_dev *dev, uint8_t status);
>  int virtio_user_dev_update_status(struct virtio_user_dev *dev);
> +int virtio_user_dev_update_link_state(struct virtio_user_dev *dev);
> +void virtio_user_dev_delayed_handler(void *param);
> +int virtio_user_dev_server_reconnect(struct virtio_user_dev *dev);
>  extern const char * const virtio_user_backend_strings[];
>  #endif
> diff --git a/drivers/net/virtio/virtio_user_ethdev.c
> b/drivers/net/virtio/virtio_user_ethdev.c
> index e2c606a838..063a723872 100644
> --- a/drivers/net/virtio/virtio_user_ethdev.c
> +++ b/drivers/net/virtio/virtio_user_ethdev.c
> @@ -28,146 +28,6 @@
> 
>  #define virtio_user_get_dev(hwp) container_of(hwp, struct virtio_user_dev, hw)
> 
> -static void
> -virtio_user_reset_queues_packed(struct rte_eth_dev *eth_dev)
> -{
> -	struct virtio_user_dev *dev = eth_dev->data->dev_private;
> -	struct virtio_hw *hw = &dev->hw;
> -	struct virtnet_rx *rxvq;
> -	struct virtnet_tx *txvq;
> -	uint16_t i;
> -
> -	/* Add lock to avoid queue contention. */
> -	rte_spinlock_lock(&hw->state_lock);
> -	hw->started = 0;
> -
> -	/*
> -	 * Waitting for datapath to complete before resetting queues.
> -	 * 1 ms should be enough for the ongoing Tx/Rx function to finish.
> -	 */
> -	rte_delay_ms(1);
> -
> -	/* Vring reset for each Tx queue and Rx queue. */
> -	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
> -		rxvq = eth_dev->data->rx_queues[i];
> -		virtqueue_rxvq_reset_packed(rxvq->vq);
> -		virtio_dev_rx_queue_setup_finish(eth_dev, i);
> -	}
> -
> -	for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
> -		txvq = eth_dev->data->tx_queues[i];
> -		virtqueue_txvq_reset_packed(txvq->vq);
> -	}
> -
> -	hw->started = 1;
> -	rte_spinlock_unlock(&hw->state_lock);
> -}
> -
> -
> -static int
> -virtio_user_server_reconnect(struct virtio_user_dev *dev)
> -{
> -	int ret, connectfd, old_status;
> -	struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->port_id];
> -	struct virtio_hw *hw = &dev->hw;
> -
> -	connectfd = accept(dev->listenfd, NULL, NULL);
> -	if (connectfd < 0)
> -		return -1;
> -
> -	dev->vhostfd = connectfd;
> -	old_status = dev->status;
> -
> -	virtio_reset(hw);
> -
> -	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_ACK);
> -
> -	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);
> -
> -	if (dev->ops->get_features(dev, &dev->device_features) < 0) {
> -		PMD_INIT_LOG(ERR, "get_features failed: %s",
> -			     strerror(errno));
> -		return -1;
> -	}
> -
> -	dev->device_features |= dev->frontend_features;
> -
> -	/* umask vhost-user unsupported features */
> -	dev->device_features &= ~(dev->unsupported_features);
> -
> -	dev->features &= dev->device_features;
> -
> -	/* For packed ring, resetting queues is required in reconnection. */
> -	if (virtio_with_packed_queue(hw) &&
> -	   (old_status & VIRTIO_CONFIG_STATUS_DRIVER_OK)) {
> -		PMD_INIT_LOG(NOTICE, "Packets on the fly will be dropped"
> -				" when packed ring reconnecting.");
> -		virtio_user_reset_queues_packed(eth_dev);
> -	}
> -
> -	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_FEATURES_OK);
> -
> -	/* Start the device */
> -	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER_OK);
> -	if (!dev->started)
> -		return -1;
> -
> -	if (dev->queue_pairs > 1) {
> -		ret = virtio_user_handle_mq(dev, dev->queue_pairs);
> -		if (ret != 0) {
> -			PMD_INIT_LOG(ERR, "Fails to enable multi-queue pairs!");
> -			return -1;
> -		}
> -	}
> -	if (eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC) {
> -		if (rte_intr_disable(eth_dev->intr_handle) < 0) {
> -			PMD_DRV_LOG(ERR, "interrupt disable failed");
> -			return -1;
> -		}
> -		rte_intr_callback_unregister(eth_dev->intr_handle,
> -					     virtio_interrupt_handler,
> -					     eth_dev);
> -		eth_dev->intr_handle->fd = connectfd;
> -		rte_intr_callback_register(eth_dev->intr_handle,
> -					   virtio_interrupt_handler, eth_dev);
> -
> -		if (rte_intr_enable(eth_dev->intr_handle) < 0) {
> -			PMD_DRV_LOG(ERR, "interrupt enable failed");
> -			return -1;
> -		}
> -	}
> -	PMD_INIT_LOG(NOTICE, "server mode virtio-user reconnection succeeds!");
> -	return 0;
> -}
> -
> -static void
> -virtio_user_delayed_handler(void *param)
> -{
> -	struct virtio_hw *hw = (struct virtio_hw *)param;
> -	struct rte_eth_dev *eth_dev = &rte_eth_devices[hw->port_id];
> -	struct virtio_user_dev *dev = virtio_user_get_dev(hw);
> -
> -	if (rte_intr_disable(eth_dev->intr_handle) < 0) {
> -		PMD_DRV_LOG(ERR, "interrupt disable failed");
> -		return;
> -	}
> -	rte_intr_callback_unregister(eth_dev->intr_handle,
> -				     virtio_interrupt_handler, eth_dev);
> -	if (dev->is_server) {
> -		if (dev->vhostfd >= 0) {
> -			close(dev->vhostfd);
> -			dev->vhostfd = -1;
> -		}
> -		eth_dev->intr_handle->fd = dev->listenfd;
> -		rte_intr_callback_register(eth_dev->intr_handle,
> -					   virtio_interrupt_handler, eth_dev);
> -		if (rte_intr_enable(eth_dev->intr_handle) < 0) {
> -			PMD_DRV_LOG(ERR, "interrupt enable failed");
> -			return;
> -		}
> -	}
> -}
> -
>  static void
>  virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset,
>  		     void *dst, int length)
> @@ -183,44 +43,7 @@ virtio_user_read_dev_config(struct virtio_hw *hw, size_t
> offset,
>  	}
> 
>  	if (offset == offsetof(struct virtio_net_config, status)) {
> -		char buf[128];
> -
> -		if (dev->vhostfd >= 0) {
> -			int r;
> -			int flags;
> -
> -			flags = fcntl(dev->vhostfd, F_GETFL);
> -			if (fcntl(dev->vhostfd, F_SETFL,
> -					flags | O_NONBLOCK) == -1) {
> -				PMD_DRV_LOG(ERR, "error setting O_NONBLOCK flag");
> -				return;
> -			}
> -			r = recv(dev->vhostfd, buf, 128, MSG_PEEK);
> -			if (r == 0 || (r < 0 && errno != EAGAIN)) {
> -				dev->net_status &= (~VIRTIO_NET_S_LINK_UP);
> -				PMD_DRV_LOG(ERR, "virtio-user port %u is down",
> -					    hw->port_id);
> -
> -				/* This function could be called in the process
> -				 * of interrupt handling, callback cannot be
> -				 * unregistered here, set an alarm to do it.
> -				 */
> -				rte_eal_alarm_set(1,
> -						  virtio_user_delayed_handler,
> -						  (void *)hw);
> -			} else {
> -				dev->net_status |= VIRTIO_NET_S_LINK_UP;
> -			}
> -			if (fcntl(dev->vhostfd, F_SETFL,
> -					flags & ~O_NONBLOCK) == -1) {
> -				PMD_DRV_LOG(ERR, "error clearing O_NONBLOCK flag");
> -				return;
> -			}
> -		} else if (dev->is_server) {
> -			dev->net_status &= (~VIRTIO_NET_S_LINK_UP);
> -			if (virtio_user_server_reconnect(dev) >= 0)
> -				dev->net_status |= VIRTIO_NET_S_LINK_UP;
> -		}
> +		virtio_user_dev_update_link_state(dev);
> 
>  		*(uint16_t *)dst = dev->net_status;
>  	}
> --
> 2.29.2

Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 41/44] net/virtio: move Vhost-kernel data to its backend
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 41/44] net/virtio: move Vhost-kernel data " Maxime Coquelin
@ 2021-01-22  8:55   ` Xia, Chenbo
  2021-01-25 14:59     ` Maxime Coquelin
  0 siblings, 1 reply; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-22  8:55 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

Hi Maxime,

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 41/44] net/virtio: move Vhost-kernel data to its backend
> 
> As done earlier for Vhost-user, this patch moves the
> Vhost-Kernel specific data to its backend file.
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user/vhost_kernel.c | 106 +++++++++++++++---
>  .../net/virtio/virtio_user/virtio_user_dev.c  |  43 ++-----
>  .../net/virtio/virtio_user/virtio_user_dev.h  |   7 +-
>  3 files changed, 98 insertions(+), 58 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c
> b/drivers/net/virtio/virtio_user/vhost_kernel.c
> index aa1f9ece5e..bc4b3461e1 100644
> --- a/drivers/net/virtio/virtio_user/vhost_kernel.c
> +++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
> @@ -14,6 +14,11 @@
>  #include "virtio_user_dev.h"
>  #include "vhost_kernel_tap.h"
> 
> +struct vhost_kernel_data {
> +	int *vhostfds;
> +	int *tapfds;
> +};
> +
>  struct vhost_memory_kernel {
>  	uint32_t nregions;
>  	uint32_t padding;
> @@ -96,7 +101,9 @@ vhost_kernel_ioctl(int fd, uint64_t request, void *arg)
>  static int
>  vhost_kernel_set_owner(struct virtio_user_dev *dev)
>  {
> -	return vhost_kernel_ioctl(dev->vhostfds[0], VHOST_SET_OWNER, NULL);
> +	struct vhost_kernel_data *data = dev->backend_data;
> +
> +	return vhost_kernel_ioctl(data->vhostfds[0], VHOST_SET_OWNER, NULL);
>  }
> 
>  static int
> @@ -104,8 +111,9 @@ vhost_kernel_get_features(struct virtio_user_dev *dev,
> uint64_t *features)
>  {
>  	int ret;
>  	unsigned int tap_features;
> +	struct vhost_kernel_data *data = dev->backend_data;
> 
> -	ret = vhost_kernel_ioctl(dev->vhostfds[0], VHOST_GET_FEATURES, features);
> +	ret = vhost_kernel_ioctl(data->vhostfds[0], VHOST_GET_FEATURES,
> features);
>  	if (ret < 0) {
>  		PMD_DRV_LOG(ERR, "Failed to get features");
>  		return -1;
> @@ -138,6 +146,8 @@ vhost_kernel_get_features(struct virtio_user_dev *dev,
> uint64_t *features)
>  static int
>  vhost_kernel_set_features(struct virtio_user_dev *dev, uint64_t features)
>  {
> +	struct vhost_kernel_data *data = dev->backend_data;
> +
>  	/* We don't need memory protection here */
>  	features &= ~(1ULL << VIRTIO_F_IOMMU_PLATFORM);
>  	/* VHOST kernel does not know about below flags */
> @@ -145,7 +155,7 @@ vhost_kernel_set_features(struct virtio_user_dev *dev,
> uint64_t features)
>  	features &= ~VHOST_KERNEL_HOST_OFFLOADS_MASK;
>  	features &= ~(1ULL << VIRTIO_NET_F_MQ);
> 
> -	return vhost_kernel_ioctl(dev->vhostfds[0], VHOST_SET_FEATURES,
> &features);
> +	return vhost_kernel_ioctl(data->vhostfds[0], VHOST_SET_FEATURES,
> &features);
>  }
> 
>  static int
> @@ -185,6 +195,7 @@ add_memseg_list(const struct rte_memseg_list *msl, void
> *arg)
>  static int
>  vhost_kernel_set_memory_table(struct virtio_user_dev *dev)
>  {
> +	struct vhost_kernel_data *data = dev->backend_data;
>  	struct vhost_memory_kernel *vm;
>  	int ret;
> 
> @@ -205,7 +216,7 @@ vhost_kernel_set_memory_table(struct virtio_user_dev *dev)
>  	if (ret < 0)
>  		goto err_free;
> 
> -	ret = vhost_kernel_ioctl(dev->vhostfds[0], VHOST_SET_MEM_TABLE, vm);
> +	ret = vhost_kernel_ioctl(data->vhostfds[0], VHOST_SET_MEM_TABLE, vm);
>  	if (ret < 0)
>  		goto err_free;
> 
> @@ -224,9 +235,10 @@ vhost_kernel_set_vring(struct virtio_user_dev *dev,
> uint64_t req, struct vhost_v
>  {
>  	int ret, fd;
>  	unsigned int index = state->index;
> +	struct vhost_kernel_data *data = dev->backend_data;
> 
>  	/* Convert from queue index to queue-pair & offset */
> -	fd = dev->vhostfds[state->index / 2];
> +	fd = data->vhostfds[state->index / 2];
>  	state->index %= 2;
> 
>  	ret = vhost_kernel_ioctl(fd, req, state);
> @@ -265,9 +277,10 @@ vhost_kernel_set_vring_file(struct virtio_user_dev *dev,
> uint64_t req,
>  {
>  	int ret, fd;
>  	unsigned int index = file->index;
> +	struct vhost_kernel_data *data = dev->backend_data;
> 
>  	/* Convert from queue index to queue-pair & offset */
> -	fd = dev->vhostfds[file->index / 2];
> +	fd = data->vhostfds[file->index / 2];
>  	file->index %= 2;
> 
>  	ret = vhost_kernel_ioctl(fd, req, file);
> @@ -299,9 +312,10 @@ vhost_kernel_set_vring_addr(struct virtio_user_dev *dev,
> struct vhost_vring_addr
>  {
>  	int ret, fd;
>  	unsigned int index = addr->index;
> +	struct vhost_kernel_data *data = dev->backend_data;
> 
>  	/* Convert from queue index to queue-pair & offset */
> -	fd = dev->vhostfds[addr->index / 2];
> +	fd = data->vhostfds[addr->index / 2];
>  	addr->index %= 2;
> 
>  	ret = vhost_kernel_ioctl(fd, VHOST_SET_VRING_ADDR, addr);
> @@ -339,27 +353,82 @@ static int
>  vhost_kernel_setup(struct virtio_user_dev *dev)
>  {
>  	int vhostfd;
> -	uint32_t i;
> +	uint32_t q, i;
> +	struct vhost_kernel_data *data;
> +
> +	data = malloc(sizeof(*data));
> +	if (!data) {
> +		PMD_INIT_LOG(ERR, "(%s) Failed to allocate Vhost-kernel data",
> dev->path);
> +		return -1;
> +	}
> +
> +	data->vhostfds = malloc(dev->max_queue_pairs * sizeof(int));
> +	if (!data->vhostfds) {
> +		PMD_INIT_LOG(ERR, "(%s) Failed to allocate Vhost FDs", dev->path);
> +		goto err_data;
> +	}
> +	data->tapfds = malloc(dev->max_queue_pairs * sizeof(int));
> +	if (!data->tapfds) {
> +		PMD_INIT_LOG(ERR, "(%s) Failed to allocate FDs", dev->path);

'allocate tap FDs'?

With this fixed:

Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>

> +		goto err_vhostfds;
> +	}
> +
> +	for (q = 0; q < dev->max_queue_pairs; ++q) {
> +		data->vhostfds[q] = -1;
> +		data->tapfds[q] = -1;
> +	}
> 
>  	get_vhost_kernel_max_regions();
> 
>  	for (i = 0; i < dev->max_queue_pairs; ++i) {
>  		vhostfd = open(dev->path, O_RDWR);
>  		if (vhostfd < 0) {
> -			PMD_DRV_LOG(ERR, "fail to open %s, %s",
> -				    dev->path, strerror(errno));
> -			return -1;
> +			PMD_DRV_LOG(ERR, "fail to open %s, %s", dev->path,
> strerror(errno));
> +			goto err_tapfds;
>  		}
> 
> -		dev->vhostfds[i] = vhostfd;
> +		data->vhostfds[i] = vhostfd;
>  	}
> 
> +	dev->backend_data = data;
> +
>  	return 0;
> +
> +err_tapfds:
> +	for (i = 0; i < dev->max_queue_pairs; i++)
> +		if (data->vhostfds[i] >= 0)
> +			close(data->vhostfds[i]);
> +
> +	free(data->tapfds);
> +err_vhostfds:
> +	free(data->vhostfds);
> +err_data:
> +	free(data);
> +
> +	return -1;
>  }
> 
>  static int
> -vhost_kernel_destroy(struct virtio_user_dev *dev __rte_unused)
> +vhost_kernel_destroy(struct virtio_user_dev *dev)
>  {
> +	struct vhost_kernel_data *data = dev->backend_data;
> +	uint32_t i;
> +
> +	if (!data)
> +		return 0;
> +
> +	for (i = 0; i < dev->max_queue_pairs; ++i) {
> +		if (data->vhostfds[i] >= 0)
> +			close(data->vhostfds[i]);
> +		if (data->tapfds[i] >= 0)
> +			close(data->tapfds[i]);
> +	}
> +
> +	free(data->vhostfds);
> +	free(data->tapfds);
> +	free(data);
> +	dev->backend_data = NULL;
> +
>  	return 0;
>  }
> 
> @@ -395,14 +464,15 @@ vhost_kernel_enable_queue_pair(struct virtio_user_dev
> *dev,
>  	int vhostfd;
>  	int tapfd;
>  	int req_mq = (dev->max_queue_pairs > 1);
> +	struct vhost_kernel_data *data = dev->backend_data;
> 
> -	vhostfd = dev->vhostfds[pair_idx];
> +	vhostfd = data->vhostfds[pair_idx];
> 
>  	if (dev->qp_enabled[pair_idx] == enable)
>  		return 0;
> 
>  	if (!enable) {
> -		tapfd = dev->tapfds[pair_idx];
> +		tapfd = data->tapfds[pair_idx];
>  		if (vhost_kernel_set_backend(vhostfd, -1) < 0) {
>  			PMD_DRV_LOG(ERR, "fail to set backend for vhost kernel");
>  			return -1;
> @@ -415,8 +485,8 @@ vhost_kernel_enable_queue_pair(struct virtio_user_dev *dev,
>  		return 0;
>  	}
> 
> -	if (dev->tapfds[pair_idx] >= 0) {
> -		tapfd = dev->tapfds[pair_idx];
> +	if (data->tapfds[pair_idx] >= 0) {
> +		tapfd = data->tapfds[pair_idx];
>  		if (vhost_kernel_tap_set_offload(tapfd, dev->features) == -1)
>  			return -1;
>  		if (req_mq && vhost_kernel_tap_set_queue(tapfd, true) < 0) {
> @@ -439,7 +509,7 @@ vhost_kernel_enable_queue_pair(struct virtio_user_dev *dev,
>  		return -1;
>  	}
> 
> -	dev->tapfds[pair_idx] = tapfd;
> +	data->tapfds[pair_idx] = tapfd;
> 
>  set_backend:
>  	if (vhost_kernel_set_backend(vhostfd, tapfd) < 0) {
> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> index 7128457e32..a1e32158bb 100644
> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> @@ -398,11 +398,6 @@ virtio_user_mem_event_cb(enum rte_mem_event type
> __rte_unused,
>  static int
>  virtio_user_dev_setup(struct virtio_user_dev *dev)
>  {
> -	uint32_t q;
> -
> -	dev->vhostfds = NULL;
> -	dev->tapfds = NULL;
> -
>  	if (dev->is_server) {
>  		if (dev->backend_type != VIRTIO_USER_BACKEND_VHOST_USER) {
>  			PMD_DRV_LOG(ERR, "Server mode only supports vhost-user!");
> @@ -410,34 +405,21 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
>  		}
>  	}
> 
> -	if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER) {
> +	switch (dev->backend_type) {
> +	case VIRTIO_USER_BACKEND_VHOST_USER:
>  		dev->ops = &virtio_ops_user;
> -	} else if (dev->backend_type ==
> -			VIRTIO_USER_BACKEND_VHOST_KERNEL) {
> +		break;
> +	case VIRTIO_USER_BACKEND_VHOST_KERNEL:
>  		dev->ops = &virtio_ops_kernel;
> -
> -		dev->vhostfds = malloc(dev->max_queue_pairs *
> -				sizeof(int));
> -		dev->tapfds = malloc(dev->max_queue_pairs *
> -				sizeof(int));
> -		if (!dev->vhostfds || !dev->tapfds) {
> -			PMD_INIT_LOG(ERR, "(%s) Failed to allocate FDs", dev->path);
> -			return -1;
> -		}
> -
> -		for (q = 0; q < dev->max_queue_pairs; ++q) {
> -			dev->vhostfds[q] = -1;
> -			dev->tapfds[q] = -1;
> -		}
> -	} else if (dev->backend_type ==
> -			VIRTIO_USER_BACKEND_VHOST_VDPA) {
> +		break;
> +	case VIRTIO_USER_BACKEND_VHOST_VDPA:
>  		dev->ops = &virtio_ops_vdpa;
> -	} else {
> +		break;
> +	default:
>  		PMD_DRV_LOG(ERR, "(%s) Unknown backend type", dev->path);
>  		return -1;
>  	}
> 
> -
>  	if (dev->ops->setup(dev) < 0) {
>  		PMD_INIT_LOG(ERR, "(%s) Failed to setup backend\n", dev->path);
>  		return -1;
> @@ -593,15 +575,6 @@ virtio_user_dev_uninit(struct virtio_user_dev *dev)
>  		close(dev->callfds[i]);
>  		close(dev->kickfds[i]);
>  	}
> -	if (dev->vhostfds) {
> -		for (i = 0; i < dev->max_queue_pairs; ++i) {
> -			close(dev->vhostfds[i]);
> -			if (dev->tapfds[i] >= 0)
> -				close(dev->tapfds[i]);
> -		}
> -		free(dev->vhostfds);
> -		free(dev->tapfds);
> -	}
> 
>  	free(dev->ifname);
> 
> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h
> b/drivers/net/virtio/virtio_user/virtio_user_dev.h
> index 36d2410546..36a9cadcad 100644
> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
> @@ -32,11 +32,6 @@ struct virtio_user_dev {
>  	/* for vhost_vdpa backend */
>  	int		vhostfd;
> 
> -	/* for vhost_kernel backend */
> -	char		*ifname;
> -	int		*vhostfds;
> -	int		*tapfds;
> -
>  	/* for both vhost_user and vhost_kernel */
>  	int		callfds[VIRTIO_MAX_VIRTQUEUES];
>  	int		kickfds[VIRTIO_MAX_VIRTQUEUES];
> @@ -56,6 +51,8 @@ struct virtio_user_dev {
>  	uint16_t	port_id;
>  	uint8_t		mac_addr[RTE_ETHER_ADDR_LEN];
>  	char		path[PATH_MAX];
> +	char		*ifname;
> +
>  	union {
>  		struct vring		vrings[VIRTIO_MAX_VIRTQUEUES];
>  		struct vring_packed	packed_vrings[VIRTIO_MAX_VIRTQUEUES];
> --
> 2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 42/44] net/virtio: move Vhost-vDPA data to its backend
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 42/44] net/virtio: move Vhost-vDPA " Maxime Coquelin
@ 2021-01-22  9:06   ` Xia, Chenbo
  2021-01-25 15:02     ` Maxime Coquelin
  0 siblings, 1 reply; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-22  9:06 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

Hi Maxime,

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 42/44] net/virtio: move Vhost-vDPA data to its backend
> 
> As done earlier for Vhost-user and Vhost-kernel, this
> patch moves the Vhost-vDPA specific data to its backend
> file.
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user/vhost_vdpa.c   | 120 +++++++++++++-----
>  .../net/virtio/virtio_user/virtio_user_dev.h  |   4 -
>  2 files changed, 89 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> index 5e3778b682..e2d6d3504d 100644
> --- a/drivers/net/virtio/virtio_user/vhost_vdpa.c
> +++ b/drivers/net/virtio/virtio_user/vhost_vdpa.c
> @@ -13,6 +13,11 @@
>  #include "vhost.h"
>  #include "virtio_user_dev.h"
> 
> +struct vhost_vdpa_data {
> +	int vhostfd;
> +	uint64_t protocol_features;
> +};
> +
>  #define VHOST_VDPA_SUPPORTED_BACKEND_FEATURES		\
>  	(1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2	|	\
>  	1ULL << VHOST_BACKEND_F_IOTLB_BATCH)
> @@ -88,27 +93,34 @@ vhost_vdpa_ioctl(int fd, uint64_t request, void *arg)
>  static int
>  vhost_vdpa_set_owner(struct virtio_user_dev *dev)
>  {
> -	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_OWNER, NULL);
> +	struct vhost_vdpa_data *data = dev->backend_data;
> +
> +	return vhost_vdpa_ioctl(data->vhostfd, VHOST_SET_OWNER, NULL);
>  }
> 
>  static int
>  vhost_vdpa_get_protocol_features(struct virtio_user_dev *dev, uint64_t
> *features)
>  {
> -	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_GET_BACKEND_FEATURES,
> features);
> +	struct vhost_vdpa_data *data = dev->backend_data;
> +
> +	return vhost_vdpa_ioctl(data->vhostfd, VHOST_GET_BACKEND_FEATURES,
> features);
>  }
> 
>  static int
>  vhost_vdpa_set_protocol_features(struct virtio_user_dev *dev, uint64_t
> features)
>  {
> -	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_BACKEND_FEATURES,
> &features);
> +	struct vhost_vdpa_data *data = dev->backend_data;
> +
> +	return vhost_vdpa_ioctl(data->vhostfd, VHOST_SET_BACKEND_FEATURES,
> &features);
>  }
> 
>  static int
>  vhost_vdpa_get_features(struct virtio_user_dev *dev, uint64_t *features)
>  {
> +	struct vhost_vdpa_data *data = dev->backend_data;
>  	int ret;
> 
> -	ret = vhost_vdpa_ioctl(dev->vhostfd, VHOST_GET_FEATURES, features);
> +	ret = vhost_vdpa_ioctl(data->vhostfd, VHOST_GET_FEATURES, features);
>  	if (ret) {
>  		PMD_DRV_LOG(ERR, "Failed to get features");
>  		return -1;
> @@ -118,15 +130,15 @@ vhost_vdpa_get_features(struct virtio_user_dev *dev,
> uint64_t *features)
>  	*features &= ~(1ULL << VIRTIO_NET_F_MQ);
> 
>  	/* Negotiated vDPA backend features */
> -	ret = vhost_vdpa_get_protocol_features(dev, &dev->protocol_features);
> +	ret = vhost_vdpa_get_protocol_features(dev, &data->protocol_features);
>  	if (ret < 0) {
>  		PMD_DRV_LOG(ERR, "Failed to get backend features");
>  		return -1;
>  	}
> 
> -	dev->protocol_features &= VHOST_VDPA_SUPPORTED_BACKEND_FEATURES;
> +	data->protocol_features &= VHOST_VDPA_SUPPORTED_BACKEND_FEATURES;
> 
> -	ret = vhost_vdpa_set_protocol_features(dev, dev->protocol_features);
> +	ret = vhost_vdpa_set_protocol_features(dev, data->protocol_features);
>  	if (ret < 0) {
>  		PMD_DRV_LOG(ERR, "Failed to set backend features");
>  		return -1;
> @@ -138,21 +150,24 @@ vhost_vdpa_get_features(struct virtio_user_dev *dev,
> uint64_t *features)
>  static int
>  vhost_vdpa_set_features(struct virtio_user_dev *dev, uint64_t features)
>  {
> +	struct vhost_vdpa_data *data = dev->backend_data;
> +
>  	/* WORKAROUND */
>  	features |= 1ULL << VIRTIO_F_IOMMU_PLATFORM;
> 
> -	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_FEATURES, &features);
> +	return vhost_vdpa_ioctl(data->vhostfd, VHOST_SET_FEATURES, &features);
>  }
> 
>  static int
>  vhost_vdpa_iotlb_batch_begin(struct virtio_user_dev *dev)
>  {
> +	struct vhost_vdpa_data *data = dev->backend_data;
>  	struct vhost_msg msg = {};
> 
> -	if (!(dev->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_BATCH)))
> +	if (!(data->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_BATCH)))
>  		return 0;
> 
> -	if (!(dev->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2)))
> {
> +	if (!(data->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2)))
> {
>  		PMD_DRV_LOG(ERR, "IOTLB_MSG_V2 not supported by the backend.");
>  		return -1;
>  	}
> @@ -160,7 +175,7 @@ vhost_vdpa_iotlb_batch_begin(struct virtio_user_dev *dev)
>  	msg.type = VHOST_IOTLB_MSG_V2;
>  	msg.iotlb.type = VHOST_IOTLB_BATCH_BEGIN;
> 
> -	if (write(dev->vhostfd, &msg, sizeof(msg)) != sizeof(msg)) {
> +	if (write(data->vhostfd, &msg, sizeof(msg)) != sizeof(msg)) {
>  		PMD_DRV_LOG(ERR, "Failed to send IOTLB batch begin (%s)",
>  				strerror(errno));
>  		return -1;
> @@ -172,12 +187,13 @@ vhost_vdpa_iotlb_batch_begin(struct virtio_user_dev *dev)
>  static int
>  vhost_vdpa_iotlb_batch_end(struct virtio_user_dev *dev)
>  {
> +	struct vhost_vdpa_data *data = dev->backend_data;
>  	struct vhost_msg msg = {};
> 
> -	if (!(dev->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_BATCH)))
> +	if (!(data->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_BATCH)))
>  		return 0;
> 
> -	if (!(dev->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2)))
> {
> +	if (!(data->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2)))
> {
>  		PMD_DRV_LOG(ERR, "IOTLB_MSG_V2 not supported by the backend.");
>  		return -1;
>  	}
> @@ -185,7 +201,7 @@ vhost_vdpa_iotlb_batch_end(struct virtio_user_dev *dev)
>  	msg.type = VHOST_IOTLB_MSG_V2;
>  	msg.iotlb.type = VHOST_IOTLB_BATCH_END;
> 
> -	if (write(dev->vhostfd, &msg, sizeof(msg)) != sizeof(msg)) {
> +	if (write(data->vhostfd, &msg, sizeof(msg)) != sizeof(msg)) {
>  		PMD_DRV_LOG(ERR, "Failed to send IOTLB batch end (%s)",
>  				strerror(errno));
>  		return -1;
> @@ -198,9 +214,10 @@ static int
>  vhost_vdpa_dma_map(struct virtio_user_dev *dev, void *addr,
>  				  uint64_t iova, size_t len)
>  {
> +	struct vhost_vdpa_data *data = dev->backend_data;
>  	struct vhost_msg msg = {};
> 
> -	if (!(dev->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2)))
> {
> +	if (!(data->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2)))
> {
>  		PMD_DRV_LOG(ERR, "IOTLB_MSG_V2 not supported by the backend.");
>  		return -1;
>  	}
> @@ -215,7 +232,7 @@ vhost_vdpa_dma_map(struct virtio_user_dev *dev, void *addr,
>  	PMD_DRV_LOG(DEBUG, "%s: iova: 0x%" PRIx64 ", addr: %p, len: 0x%zx",
>  			__func__, iova, addr, len);
> 
> -	if (write(dev->vhostfd, &msg, sizeof(msg)) != sizeof(msg)) {
> +	if (write(data->vhostfd, &msg, sizeof(msg)) != sizeof(msg)) {
>  		PMD_DRV_LOG(ERR, "Failed to send IOTLB update (%s)",
>  				strerror(errno));
>  		return -1;
> @@ -228,9 +245,10 @@ static int
>  vhost_vdpa_dma_unmap(struct virtio_user_dev *dev, __rte_unused void *addr,
>  				  uint64_t iova, size_t len)
>  {
> +	struct vhost_vdpa_data *data = dev->backend_data;
>  	struct vhost_msg msg = {};
> 
> -	if (!(dev->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2)))
> {
> +	if (!(data->protocol_features & (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2)))
> {
>  		PMD_DRV_LOG(ERR, "IOTLB_MSG_V2 not supported by the backend.");
>  		return -1;
>  	}
> @@ -243,7 +261,7 @@ vhost_vdpa_dma_unmap(struct virtio_user_dev *dev,
> __rte_unused void *addr,
>  	PMD_DRV_LOG(DEBUG, "%s: iova: 0x%" PRIx64 ", len: 0x%zx",
>  			__func__, iova, len);
> 
> -	if (write(dev->vhostfd, &msg, sizeof(msg)) != sizeof(msg)) {
> +	if (write(data->vhostfd, &msg, sizeof(msg)) != sizeof(msg)) {
>  		PMD_DRV_LOG(ERR, "Failed to send IOTLB invalidate (%s)",
>  				strerror(errno));
>  		return -1;
> @@ -353,55 +371,73 @@ vhost_vdpa_set_memory_table(struct virtio_user_dev *dev)
>  static int
>  vhost_vdpa_set_vring_enable(struct virtio_user_dev *dev, struct
> vhost_vring_state *state)
>  {
> -	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_VDPA_SET_VRING_ENABLE,
> state);
> +	struct vhost_vdpa_data *data = dev->backend_data;
> +
> +	return vhost_vdpa_ioctl(data->vhostfd, VHOST_VDPA_SET_VRING_ENABLE,
> state);
>  }
> 
>  static int
>  vhost_vdpa_set_vring_num(struct virtio_user_dev *dev, struct
> vhost_vring_state *state)
>  {
> -	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_NUM, state);
> +	struct vhost_vdpa_data *data = dev->backend_data;
> +
> +	return vhost_vdpa_ioctl(data->vhostfd, VHOST_SET_VRING_NUM, state);
>  }
> 
>  static int
>  vhost_vdpa_set_vring_base(struct virtio_user_dev *dev, struct
> vhost_vring_state *state)
>  {
> -	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_BASE, state);
> +	struct vhost_vdpa_data *data = dev->backend_data;
> +
> +	return vhost_vdpa_ioctl(data->vhostfd, VHOST_SET_VRING_BASE, state);
>  }
> 
>  static int
>  vhost_vdpa_get_vring_base(struct virtio_user_dev *dev, struct
> vhost_vring_state *state)
>  {
> -	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_GET_VRING_BASE, state);
> +	struct vhost_vdpa_data *data = dev->backend_data;
> +
> +	return vhost_vdpa_ioctl(data->vhostfd, VHOST_GET_VRING_BASE, state);
>  }
> 
>  static int
>  vhost_vdpa_set_vring_call(struct virtio_user_dev *dev, struct
> vhost_vring_file *file)
>  {
> -	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_CALL, file);
> +	struct vhost_vdpa_data *data = dev->backend_data;
> +
> +	return vhost_vdpa_ioctl(data->vhostfd, VHOST_SET_VRING_CALL, file);
>  }
> 
>  static int
>  vhost_vdpa_set_vring_kick(struct virtio_user_dev *dev, struct
> vhost_vring_file *file)
>  {
> -	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_KICK, file);
> +	struct vhost_vdpa_data *data = dev->backend_data;
> +
> +	return vhost_vdpa_ioctl(data->vhostfd, VHOST_SET_VRING_KICK, file);
>  }
> 
>  static int
>  vhost_vdpa_set_vring_addr(struct virtio_user_dev *dev, struct
> vhost_vring_addr *addr)
>  {
> -	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_SET_VRING_ADDR, addr);
> +	struct vhost_vdpa_data *data = dev->backend_data;
> +
> +	return vhost_vdpa_ioctl(data->vhostfd, VHOST_SET_VRING_ADDR, addr);
>  }
> 
>  static int
>  vhost_vdpa_get_status(struct virtio_user_dev *dev, uint8_t *status)
>  {
> -	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_VDPA_GET_STATUS, status);
> +	struct vhost_vdpa_data *data = dev->backend_data;
> +
> +	return vhost_vdpa_ioctl(data->vhostfd, VHOST_VDPA_GET_STATUS, status);
>  }
> 
>  static int
>  vhost_vdpa_set_status(struct virtio_user_dev *dev, uint8_t status)
>  {
> -	return vhost_vdpa_ioctl(dev->vhostfd, VHOST_VDPA_SET_STATUS, &status);
> +	struct vhost_vdpa_data *data = dev->backend_data;
> +
> +	return vhost_vdpa_ioctl(data->vhostfd, VHOST_VDPA_SET_STATUS, &status);
>  }
> 
>  /**
> @@ -414,27 +450,49 @@ vhost_vdpa_set_status(struct virtio_user_dev *dev,
> uint8_t status)
>  static int
>  vhost_vdpa_setup(struct virtio_user_dev *dev)
>  {
> +	struct vhost_vdpa_data *data;
>  	uint32_t did = (uint32_t)-1;
> 
> -	dev->vhostfd = open(dev->path, O_RDWR);
> -	if (dev->vhostfd < 0) {
> +	data = malloc(sizeof(*data));
> +	if (!data) {
> +		PMD_DRV_LOG(ERR, "(%s) Faidle to allocate backend data", dev-
> >path);
> +		return -1;
> +	}
> +
> +	data->vhostfd = open(dev->path, O_RDWR);
> +	if (data->vhostfd < 0) {
>  		PMD_DRV_LOG(ERR, "Failed to open %s: %s\n",
>  				dev->path, strerror(errno));
> +		free(data);
>  		return -1;
>  	}
> 
> -	if (ioctl(dev->vhostfd, VHOST_VDPA_GET_DEVICE_ID, &did) < 0 ||
> +	if (ioctl(data->vhostfd, VHOST_VDPA_GET_DEVICE_ID, &did) < 0 ||
>  			did != VIRTIO_ID_NETWORK) {
>  		PMD_DRV_LOG(ERR, "Invalid vdpa device ID: %u\n", did);
> +		close(data->vhostfd);
> +		free(data);
>  		return -1;
>  	}
> 
> +	dev->backend_data = data;
> +
>  	return 0;
>  }
> 
>  static int
> -vhost_vdpa_destroy(struct virtio_user_dev *dev __rte_unused)
> +vhost_vdpa_destroy(struct virtio_user_dev *dev)
>  {
> +	struct vhost_vdpa_data *data = dev->backend_data;
> +
> +	if (!data)
> +		return 0;
> +
> +	close(data->vhostfd);
> +
> +	free(data);
> +	dev->backend_data = NULL;
> +
>  	return 0;
>  }
> 
> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h
> b/drivers/net/virtio/virtio_user/virtio_user_dev.h
> index 36a9cadcad..9a6723da24 100644
> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
> @@ -29,9 +29,6 @@ struct virtio_user_dev {
>  	enum virtio_user_backend_type backend_type;
>  	bool		is_server;  /* server or client mode */
> 
> -	/* for vhost_vdpa backend */
> -	int		vhostfd;
> -
>  	/* for both vhost_user and vhost_kernel */

I remember you agreed that this comment is no longer needed?

I also noticed that there're multiple calls of PMD_DRV_LOG that add
'\n' in the end, which is necessary. But, let's clean it up later..

With above fixed:

Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>

>  	int		callfds[VIRTIO_MAX_VIRTQUEUES];
>  	int		kickfds[VIRTIO_MAX_VIRTQUEUES];
> @@ -45,7 +42,6 @@ struct virtio_user_dev {
>  	uint64_t	device_features; /* supported features by device */
>  	uint64_t	frontend_features; /* enabled frontend features */
>  	uint64_t	unsupported_features; /* unsupported features mask */
> -	uint64_t	protocol_features; /* negotiated protocol features */
>  	uint8_t		status;
>  	uint16_t	net_status;
>  	uint16_t	port_id;
> --
> 2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 43/44] net/virtio: improve Vhost-user error logging
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 43/44] net/virtio: improve Vhost-user error logging Maxime Coquelin
@ 2021-01-22  9:11   ` Xia, Chenbo
  2021-01-25 15:04     ` Maxime Coquelin
  0 siblings, 1 reply; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-22  9:11 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

Hi Maxime,

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 43/44] net/virtio: improve Vhost-user error logging
> 
> This patch improves error logging in vhost_user_read,
> especially printing errno when recv() fails.
> 
> Suggested-by: Adrian Moreno <amorenoz@redhat.com>
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user/vhost_user.c | 29 ++++++++++++---------
>  1 file changed, 17 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/vhost_user.c
> b/drivers/net/virtio/virtio_user/vhost_user.c
> index f046655af6..be91c99cea 100644
> --- a/drivers/net/virtio/virtio_user/vhost_user.c
> +++ b/drivers/net/virtio/virtio_user/vhost_user.c
> @@ -148,38 +148,43 @@ vhost_user_read(int fd, struct vhost_user_msg *msg)
>  	int ret, sz_hdr = VHOST_USER_HDR_SIZE, sz_payload;
> 
>  	ret = recv(fd, (void *)msg, sz_hdr, 0);
> -	if (ret < sz_hdr) {
> +	if (ret < 0) {
> +		PMD_DRV_LOG(ERR, "Failed to recv msg header: %s", strerror(errno));
> +		return -1;
> +	} else if (ret < sz_hdr) {
>  		PMD_DRV_LOG(ERR, "Failed to recv msg hdr: %d instead of %d.",
>  			    ret, sz_hdr);
> -		goto fail;
> +		return -1;
>  	}
> 
>  	/* validate msg flags */
>  	if (msg->flags != (valid_flags)) {
>  		PMD_DRV_LOG(ERR, "Failed to recv msg: flags %x instead of %x.",
>  			    msg->flags, valid_flags);
> -		goto fail;
> +		return -1;

Since you are here, also add '0x' before '%x' here?

Thanks,
Chenbo

>  	}
> 
>  	sz_payload = msg->size;
> 
> -	if ((size_t)sz_payload > sizeof(msg->payload))
> -		goto fail;
> +	if ((size_t)sz_payload > sizeof(msg->payload)) {
> +		PMD_DRV_LOG(ERR, "Payload size overflow, header says %d but
> max %zu\n",
> +				sz_payload, sizeof(msg->payload));
> +		return -1;
> +	}
> 
>  	if (sz_payload) {
>  		ret = recv(fd, (void *)((char *)msg + sz_hdr), sz_payload, 0);
> -		if (ret < sz_payload) {
> -			PMD_DRV_LOG(ERR,
> -				"Failed to recv msg payload: %d instead of %d.",
> +		if (ret < 0) {
> +			PMD_DRV_LOG(ERR, "Failed to recv msg payload: %s",
> strerror(errno));
> +			return -1;
> +		} else if (ret < sz_payload) {
> +			PMD_DRV_LOG(ERR, "Failed to recv msg payload: %d instead
> of %u.",
>  				ret, msg->size);
> -			goto fail;
> +			return -1;
>  		}
>  	}
> 
>  	return 0;
> -
> -fail:
> -	return -1;
>  }
> 
>  static int
> --
> 2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 44/44] net/virtio: handle Virtio-user setup failure properly
  2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 44/44] net/virtio: handle Virtio-user setup failure properly Maxime Coquelin
@ 2021-01-22  9:24   ` Xia, Chenbo
  2021-01-25 16:16     ` Maxime Coquelin
  0 siblings, 1 reply; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-22  9:24 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

Hi Maxime,

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, January 20, 2021 5:25 AM
> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Subject: [PATCH v2 44/44] net/virtio: handle Virtio-user setup failure
> properly
> 
> This patch fixes virtio_user_dev_setup() error path,
> by cleaning all resources it allocates.
> 
> Suggested-by: Adrian Moreno <amorenoz@redhat.com>
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  drivers/net/virtio/virtio_user/virtio_user_dev.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> index a1e32158bb..2f7dc574b6 100644
> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
> @@ -427,15 +427,22 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
> 
>  	if (virtio_user_dev_init_notify(dev) < 0) {
>  		PMD_INIT_LOG(ERR, "(%s) Failed to init notifiers\n", dev->path);
> -		return -1;
> +		goto destroy;
>  	}
> 
>  	if (virtio_user_fill_intr_handle(dev) < 0) {
>  		PMD_INIT_LOG(ERR, "(%s) Failed to init interrupt handler\n", dev-
> >path);
> -		return -1;
> +		goto uninit;
>  	}
> 
>  	return 0;
> +
> +uninit:
> +	virtio_user_dev_uninit(dev);

IMHO, it may not be the best choice to call virtio_user_dev_uninit here..

Logically when virtio_user_fill_intr_handle fails, we want to release the resources
which is allocated in virtio_user_dev_init_notify (i.e., fds), but virtio_user_dev_uninit
does more. For example, unregister the event callback that have not been registered yet and
it also leads to destroy callback called twice. Although things done but not needed will
not lead to error, but it looks not in the best way. What do you think?

Thanks,
Chenbo

> +destroy:
> +	dev->ops->destroy(dev);
> +
> +	return -1;
>  }
> 
>  /* Use below macro to filter features from vhost backend */
> --
> 2.29.2


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 01/44] bus/vdev: add helper to get vdev from eth dev
  2021-01-20  0:56   ` Thomas Monjalon
@ 2021-01-25 10:53     ` Maxime Coquelin
  2021-01-25 11:04       ` Thomas Monjalon
  0 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-25 10:53 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand



On 1/20/21 1:56 AM, Thomas Monjalon wrote:
> 19/01/2021 22:24, Maxime Coquelin:
>> This patch adds an helper macro to get the rte_vdev_device
>> pointer from a rte_eth_dev pointer.
>>
>> This is similar to RTE_ETH_DEV_TO_PCI().
> [...]
>> --- a/drivers/bus/vdev/rte_bus_vdev.h
>> +++ b/drivers/bus/vdev/rte_bus_vdev.h
>> @@ -34,6 +34,8 @@ struct rte_vdev_device {
>> +#define RTE_ETH_DEV_TO_VDEV(eth_dev)	RTE_DEV_TO_VDEV((eth_dev)->device)
> 
> Why these macros (vdev and PCI) are not in ethdev?
> 
> 

I think because that would put a dependency on vdev & pci bus drivers in
ethdev library.

Indeed, RTE_DEV_TO_VDEV needs to know about rte_vdev_device layout:

#define RTE_DEV_TO_VDEV(ptr) \
	container_of(ptr, struct rte_vdev_device, device)

Regards,
Maxime


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 01/44] bus/vdev: add helper to get vdev from eth dev
  2021-01-25 10:53     ` Maxime Coquelin
@ 2021-01-25 11:04       ` Thomas Monjalon
  0 siblings, 0 replies; 86+ messages in thread
From: Thomas Monjalon @ 2021-01-25 11:04 UTC (permalink / raw)
  To: Maxime Coquelin; +Cc: dev, chenbo.xia, olivier.matz, amorenoz, david.marchand

25/01/2021 11:53, Maxime Coquelin:
> 
> On 1/20/21 1:56 AM, Thomas Monjalon wrote:
> > 19/01/2021 22:24, Maxime Coquelin:
> >> This patch adds an helper macro to get the rte_vdev_device
> >> pointer from a rte_eth_dev pointer.
> >>
> >> This is similar to RTE_ETH_DEV_TO_PCI().
> > [...]
> >> --- a/drivers/bus/vdev/rte_bus_vdev.h
> >> +++ b/drivers/bus/vdev/rte_bus_vdev.h
> >> @@ -34,6 +34,8 @@ struct rte_vdev_device {
> >> +#define RTE_ETH_DEV_TO_VDEV(eth_dev)	RTE_DEV_TO_VDEV((eth_dev)->device)
> > 
> > Why these macros (vdev and PCI) are not in ethdev?
> > 
> > 
> 
> I think because that would put a dependency on vdev & pci bus drivers in
> ethdev library.
> 
> Indeed, RTE_DEV_TO_VDEV needs to know about rte_vdev_device layout:
> 
> #define RTE_DEV_TO_VDEV(ptr) \
> 	container_of(ptr, struct rte_vdev_device, device)

OK



^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 19/44] net/virtio: move features definition to generic header
  2021-01-21  6:47   ` Xia, Chenbo
@ 2021-01-25 12:35     ` Maxime Coquelin
  0 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-25 12:35 UTC (permalink / raw)
  To: Xia, Chenbo, dev, olivier.matz, amorenoz, david.marchand



On 1/21/21 7:47 AM, Xia, Chenbo wrote:
> Hi Maxime,
> 
>> -----Original Message-----
>> From: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Sent: Wednesday, January 20, 2021 5:25 AM
>> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
>> amorenoz@redhat.com; david.marchand@redhat.com
>> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Subject: [PATCH v2 19/44] net/virtio: move features definition to generic
>> header
>>
>> This patch moves all the Virtio definition to the generic
>> header. It also renames some helpers to no more reference
>> PCI.
>>
>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>> ---
>>  drivers/net/virtio/meson.build                |   3 +-
>>  drivers/net/virtio/virtio.c                   |  22 ++++
>>  drivers/net/virtio/virtio.h                   |  94 +++++++++++++++
>>  drivers/net/virtio/virtio_ethdev.c            | 114 +++++++++---------
>>  drivers/net/virtio/virtio_pci.c               |  21 +---
>>  drivers/net/virtio/virtio_pci.h               |  90 --------------
>>  drivers/net/virtio/virtio_ring.h              |   2 +-
>>  drivers/net/virtio/virtio_rxtx.c              |  38 +++---
>>  drivers/net/virtio/virtio_rxtx_packed.h       |   6 +-
>>  .../net/virtio/virtio_user/vhost_kernel_tap.c |   2 +-
>>  drivers/net/virtio/virtio_user_ethdev.c       |   6 +-
>>  drivers/net/virtio/virtqueue.c                |   4 +-
>>  drivers/net/virtio/virtqueue.h                |   8 +-
>>  13 files changed, 211 insertions(+), 199 deletions(-)
>>  create mode 100644 drivers/net/virtio/virtio.c
>>
>> diff --git a/drivers/net/virtio/meson.build b/drivers/net/virtio/meson.build
>> index f2873d6180..d595cfdcab 100644
>> --- a/drivers/net/virtio/meson.build
>> +++ b/drivers/net/virtio/meson.build
> 
> <snip>
> 
>>
>> -	if (vtpci_with_feature(hw, VIRTIO_F_RING_PACKED)) {
>> +	if (virtio_with_feature(hw, VIRTIO_F_RING_PACKED)) {
> 
> As discussed before, let's also replace here with virtio_with_packed_queue 😊

Indeed, I missed that one.
It is fixed now and will be in v3.

Thanks,
Maxime

> Thanks
> Chenbo


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 09/44] net/virtio: move MSIX detection to PCI ethdev
  2021-01-21  7:12   ` Xia, Chenbo
@ 2021-01-25 12:41     ` Maxime Coquelin
  0 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-25 12:41 UTC (permalink / raw)
  To: Xia, Chenbo, dev, olivier.matz, amorenoz, david.marchand



On 1/21/21 8:12 AM, Xia, Chenbo wrote:
> Hi Maxime,
> 
>> -----Original Message-----
>> From: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Sent: Wednesday, January 20, 2021 5:25 AM
>> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
>> amorenoz@redhat.com; david.marchand@redhat.com
>> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Subject: [PATCH v2 09/44] net/virtio: move MSIX detection to PCI ethdev
>>
>> This patch introduces a new callback to notify the bus
>> driver some interrupt related operation was done.
>>
>> This is used by Virtio PCI driver to check msix status.
>>
>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>> ---
>>  drivers/net/virtio/virtio_ethdev.c     |  12 +--
>>  drivers/net/virtio/virtio_pci.c        | 120 ++++++++++++++-----------
>>  drivers/net/virtio/virtio_pci.h        |   6 +-
>>  drivers/net/virtio/virtio_pci_ethdev.c |   2 +
>>  4 files changed, 82 insertions(+), 58 deletions(-)
>>
>> diff --git a/drivers/net/virtio/virtio_ethdev.c
>> b/drivers/net/virtio/virtio_ethdev.c
>> index a3e81f336d..13d5a76376 100644
>> --- a/drivers/net/virtio/virtio_ethdev.c
>> +++ b/drivers/net/virtio/virtio_ethdev.c
>> @@ -1287,8 +1287,8 @@ virtio_intr_unmask(struct rte_eth_dev *dev)
>>  	if (rte_intr_ack(dev->intr_handle) < 0)
>>  		return -1;
>>
>> -	if (hw->bus_type == VIRTIO_BUS_PCI_LEGACY || hw->bus_type ==
>> VIRTIO_BUS_PCI_MODERN)
>> -		hw->use_msix = vtpci_msix_detect(RTE_ETH_DEV_TO_PCI(dev));
>> +	if (VTPCI_OPS(hw)->intr_event)
> 
> Emmm.. why is callback called intr_event? The callback detects/checks msix and lsc.
> IMHO, maybe intr_detect? Or another similar verb you like 😊

I called it intr_event because it could be used for other purpose than
intr detection. But this is the only use for now so let's immplement
your suggestion and we can revisit later if needed.

>> +		VTPCI_OPS(hw)->intr_event(hw);
>>
>>  	return 0;
> 
> <snip>
> 
>>
>> +msix_detect:
>> +	hw->use_msix = vtpci_msix_detect(dev);
>> +
> 
> Just use use the callback introduced? Should also work later when intr_lsc is added.

I didn't do it given that it was in the same file and that the callback
was to report an event happened. With renaming the callback as you
suggest, it makes sense to use it.

I will fix in v3.

Thanks,
Maxime

> Thanks,
> Chenbo
> 


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 36/44] net/virtio: move Vhost-user reqs to Vhost-user backend
  2021-01-21  8:56   ` Xia, Chenbo
@ 2021-01-25 14:50     ` Maxime Coquelin
  0 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-25 14:50 UTC (permalink / raw)
  To: Xia, Chenbo, dev, olivier.matz, amorenoz, david.marchand



On 1/21/21 9:56 AM, Xia, Chenbo wrote:
> Hi Maxime,
> 
>> -----Original Message-----
>> From: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Sent: Wednesday, January 20, 2021 5:25 AM
>> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
>> amorenoz@redhat.com; david.marchand@redhat.com
>> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Subject: [PATCH v2 36/44] net/virtio: move Vhost-user reqs to Vhost-user
> 
> Better use full name 'requests' if the title's not too long?

Fixed, that's not too long with requests.

> Same thing could be done for 'net/virtio: make Vhost-user req sender consistent'

Ditto

> With this fixed:
> 
> Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
> 

Thanks,
Maxime

>> backend
>>
>> Now that we have a proper isolation of the backends,
>> we can move Vhost-user requests declaration to the
>> Vhost-user backend file.
>>
>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>> ---
>>  drivers/net/virtio/virtio_user/vhost.h      | 25 ---------------------
>>  drivers/net/virtio/virtio_user/vhost_user.c | 25 +++++++++++++++++++++
>>  2 files changed, 25 insertions(+), 25 deletions(-)
>>
>> diff --git a/drivers/net/virtio/virtio_user/vhost.h
>> b/drivers/net/virtio/virtio_user/vhost.h
>> index 6294b8afee..2aa6b2cb70 100644
>> --- a/drivers/net/virtio/virtio_user/vhost.h
>> +++ b/drivers/net/virtio/virtio_user/vhost.h
>> @@ -63,31 +63,6 @@ struct vhost_vring_addr {
>>  #define VHOST_USER_PROTOCOL_F_STATUS 16
>>  #endif
>>
>> -enum vhost_user_request {
>> -	VHOST_USER_NONE = 0,
>> -	VHOST_USER_GET_FEATURES = 1,
>> -	VHOST_USER_SET_FEATURES = 2,
>> -	VHOST_USER_SET_OWNER = 3,
>> -	VHOST_USER_RESET_OWNER = 4,
>> -	VHOST_USER_SET_MEM_TABLE = 5,
>> -	VHOST_USER_SET_LOG_BASE = 6,
>> -	VHOST_USER_SET_LOG_FD = 7,
>> -	VHOST_USER_SET_VRING_NUM = 8,
>> -	VHOST_USER_SET_VRING_ADDR = 9,
>> -	VHOST_USER_SET_VRING_BASE = 10,
>> -	VHOST_USER_GET_VRING_BASE = 11,
>> -	VHOST_USER_SET_VRING_KICK = 12,
>> -	VHOST_USER_SET_VRING_CALL = 13,
>> -	VHOST_USER_SET_VRING_ERR = 14,
>> -	VHOST_USER_GET_PROTOCOL_FEATURES = 15,
>> -	VHOST_USER_SET_PROTOCOL_FEATURES = 16,
>> -	VHOST_USER_GET_QUEUE_NUM = 17,
>> -	VHOST_USER_SET_VRING_ENABLE = 18,
>> -	VHOST_USER_SET_STATUS = 39,
>> -	VHOST_USER_GET_STATUS = 40,
>> -	VHOST_USER_MAX
>> -};
>> -
>>  #ifndef VHOST_BACKEND_F_IOTLB_MSG_V2
>>  #define VHOST_BACKEND_F_IOTLB_MSG_V2 1
>>  #endif
>> diff --git a/drivers/net/virtio/virtio_user/vhost_user.c
>> b/drivers/net/virtio/virtio_user/vhost_user.c
>> index d46e25b64b..fb6fcc82c9 100644
>> --- a/drivers/net/virtio/virtio_user/vhost_user.c
>> +++ b/drivers/net/virtio/virtio_user/vhost_user.c
>> @@ -27,6 +27,31 @@ struct vhost_memory {
>>  	struct vhost_memory_region regions[VHOST_MEMORY_MAX_NREGIONS];
>>  };
>>
>> +enum vhost_user_request {
>> +	VHOST_USER_NONE = 0,
>> +	VHOST_USER_GET_FEATURES = 1,
>> +	VHOST_USER_SET_FEATURES = 2,
>> +	VHOST_USER_SET_OWNER = 3,
>> +	VHOST_USER_RESET_OWNER = 4,
>> +	VHOST_USER_SET_MEM_TABLE = 5,
>> +	VHOST_USER_SET_LOG_BASE = 6,
>> +	VHOST_USER_SET_LOG_FD = 7,
>> +	VHOST_USER_SET_VRING_NUM = 8,
>> +	VHOST_USER_SET_VRING_ADDR = 9,
>> +	VHOST_USER_SET_VRING_BASE = 10,
>> +	VHOST_USER_GET_VRING_BASE = 11,
>> +	VHOST_USER_SET_VRING_KICK = 12,
>> +	VHOST_USER_SET_VRING_CALL = 13,
>> +	VHOST_USER_SET_VRING_ERR = 14,
>> +	VHOST_USER_GET_PROTOCOL_FEATURES = 15,
>> +	VHOST_USER_SET_PROTOCOL_FEATURES = 16,
>> +	VHOST_USER_GET_QUEUE_NUM = 17,
>> +	VHOST_USER_SET_VRING_ENABLE = 18,
>> +	VHOST_USER_SET_STATUS = 39,
>> +	VHOST_USER_GET_STATUS = 40,
>> +	VHOST_USER_MAX
>> +};
>> +
>>  struct vhost_user_msg {
>>  	enum vhost_user_request request;
>>
>> --
>> 2.29.2
> 


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 01/44] bus/vdev: add helper to get vdev from eth dev
  2021-01-21  8:58   ` Xia, Chenbo
@ 2021-01-25 14:51     ` Maxime Coquelin
  0 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-25 14:51 UTC (permalink / raw)
  To: Xia, Chenbo, dev, olivier.matz, amorenoz, david.marchand



On 1/21/21 9:58 AM, Xia, Chenbo wrote:
> Hi Maxime,
> 
>> -----Original Message-----
>> From: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Sent: Wednesday, January 20, 2021 5:24 AM
>> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
>> amorenoz@redhat.com; david.marchand@redhat.com
>> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Subject: [PATCH v2 01/44] bus/vdev: add helper to get vdev from eth dev
> 
> Sorry that I missed the title in v1..
> 
> Better use 'ethdev' or 'eth device'here?

Changed to ethedv.

Thanks,
Maxime

> Thanks,
> Chenbo
> 
>>
>> This patch adds an helper macro to get the rte_vdev_device
>> pointer from a rte_eth_dev pointer.
>>
>> This is similar to RTE_ETH_DEV_TO_PCI().
>>
>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
>> Reviewed-by: David Marchand <david.marchand@redhat.com>
>> ---
>>  drivers/bus/vdev/rte_bus_vdev.h | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/bus/vdev/rte_bus_vdev.h b/drivers/bus/vdev/rte_bus_vdev.h
>> index d14eeb41b0..f99a41f825 100644
>> --- a/drivers/bus/vdev/rte_bus_vdev.h
>> +++ b/drivers/bus/vdev/rte_bus_vdev.h
>> @@ -34,6 +34,8 @@ struct rte_vdev_device {
>>  #define RTE_DEV_TO_VDEV_CONST(ptr) \
>>  	container_of(ptr, const struct rte_vdev_device, device)
>>
>> +#define RTE_ETH_DEV_TO_VDEV(eth_dev)	RTE_DEV_TO_VDEV((eth_dev)->device)
>> +
>>  static inline const char *
>>  rte_vdev_device_name(const struct rte_vdev_device *dev)
>>  {
>> --
>> 2.29.2
> 


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 27/44] net/virtio: add Virtio-user features ops
  2021-01-22  7:25   ` Xia, Chenbo
@ 2021-01-25 14:53     ` Maxime Coquelin
  0 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-25 14:53 UTC (permalink / raw)
  To: Xia, Chenbo, dev, olivier.matz, amorenoz, david.marchand



On 1/22/21 8:25 AM, Xia, Chenbo wrote:
> Hi Maxime,
> 
>> -----Original Message-----
>> From: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Sent: Wednesday, January 20, 2021 5:25 AM
>> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
>> amorenoz@redhat.com; david.marchand@redhat.com
>> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Subject: [PATCH v2 27/44] net/virtio: add Virtio-user features ops
>>
>> This patch introduces new callbacks for getting
>> and setting Virtio features, and implements them
>> for the different backend types.
>>
>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>> ---
>>  drivers/net/virtio/virtio_user/vhost.h        |   2 +
>>  drivers/net/virtio/virtio_user/vhost_kernel.c | 150 +++++++++---------
>>  .../net/virtio/virtio_user/vhost_kernel_tap.c |  23 +++
>>  .../net/virtio/virtio_user/vhost_kernel_tap.h |   1 +
>>  drivers/net/virtio/virtio_user/vhost_user.c   |  64 +++++++-
>>  drivers/net/virtio/virtio_user/vhost_vdpa.c   |  38 +++--
>>  .../net/virtio/virtio_user/virtio_user_dev.c  |   5 +-
>>  drivers/net/virtio/virtio_user_ethdev.c       |   3 +-
>>  8 files changed, 190 insertions(+), 96 deletions(-)
>>
>> diff --git a/drivers/net/virtio/virtio_user/vhost.h
>> b/drivers/net/virtio/virtio_user/vhost.h
>> index 5413ec6778..13a88c7671 100644
>> --- a/drivers/net/virtio/virtio_user/vhost.h
>> +++ b/drivers/net/virtio/virtio_user/vhost.h
>> @@ -110,6 +110,8 @@ struct virtio_user_dev;
> 
> <snip>
> 
>> +
>> +	ret = tap_support_features(&tap_features);
>> +	if (ret < 0) {
>> +		PMD_DRV_LOG(ERR, "Failed to get TAP features)");
> 
> Delete the ')' before " ?

Indeed, done.

>> +		return -1;
>> +	}
>> +
> 
> <snip>
> 
>>
>> +static int
>> +vhost_user_get_features(struct virtio_user_dev *dev, uint64_t *features)
>> +{
>> +	int ret;
>> +	struct vhost_user_msg msg = {
>> +		.request = VHOST_USER_GET_FEATURES,
>> +		.flags = VHOST_USER_VERSION,
>> +	};
>> +
>> +	ret = vhost_user_write(dev->vhostfd, &msg, NULL, 0);
>> +	if (ret < 0)
>> +		goto err;
>> +
>> +	ret = vhost_user_read(dev->vhostfd, &msg);
>> +	if (ret < 0)
>> +		goto err;
> 
> Better add error log both after write and read?

As you replied later, we already log in read & write functions, so
skipping this comment.

> Thanks!
> Chenbo
> 

Thanks,
Maxime


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 29/44] net/virtio: add Virtio-user memory tables ops
  2021-01-22  7:34   ` Xia, Chenbo
@ 2021-01-25 14:56     ` Maxime Coquelin
  0 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-25 14:56 UTC (permalink / raw)
  To: Xia, Chenbo, dev, olivier.matz, amorenoz, david.marchand



On 1/22/21 8:34 AM, Xia, Chenbo wrote:
> Hi Maxime,
> 
>> -----Original Message-----
>> From: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Sent: Wednesday, January 20, 2021 5:25 AM
>> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
>> amorenoz@redhat.com; david.marchand@redhat.com
>> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Subject: [PATCH v2 29/44] net/virtio: add Virtio-user memory tables ops
>>
>> This patch implements a dedicated callback for
>> preparing and sending memory table to the backends.
>>
>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>> ---
>>  drivers/net/virtio/virtio_user/vhost.h        |  1 +
>>  drivers/net/virtio/virtio_user/vhost_kernel.c | 60 ++++++-------
>>  drivers/net/virtio/virtio_user/vhost_user.c   | 86 ++++++++++++++-----
>>  drivers/net/virtio/virtio_user/vhost_vdpa.c   |  8 +-
>>  .../net/virtio/virtio_user/virtio_user_dev.c  |  4 +-
>>  5 files changed, 101 insertions(+), 58 deletions(-)
>>
...
>> +static int
>> +vhost_user_check_reply_ack(struct virtio_user_dev *dev, struct vhost_user_msg
>> *msg)
>> +{
>> +	enum vhost_user_request req = msg->request;
>> +	int ret;
>> +
>> +	if (!(msg->flags & VHOST_USER_NEED_REPLY_MASK))
>> +		return 0;
>> +
>> +	ret = vhost_user_read(dev->vhostfd, msg);
>> +	if (ret < 0) {
>> +		PMD_DRV_LOG(ERR, "Failed to read reply-ack");
>> +		return -1;
>> +	}
>> +
>> +	if (req != msg->request) {
>> +		PMD_DRV_LOG(ERR, "Unexpected reply-ack request type (%d)", msg-
>>> request);
>> +		return -1;
>> +	}
>> +
>> +	if (msg->size != sizeof(msg->payload.u64)) {
>> +		PMD_DRV_LOG(ERR, "Unexpected reply-ack payload size (%d)", msg-
>>> size);
> 
> Better to use '%u'?

Done

>> +		return -1;
>> +	}
>> +
>> +	if (msg->payload.u64) {
>> +		PMD_DRV_LOG(ERR, "Slave replied NACK to request type %d", msg-
>>> request);
> 
> Replace '%d' with '(%d)' to align with the above style? :P

Added to make style consistent.

> Thanks,
> Chenbo
> 

Thanks,
Maxime


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 41/44] net/virtio: move Vhost-kernel data to its backend
  2021-01-22  8:55   ` Xia, Chenbo
@ 2021-01-25 14:59     ` Maxime Coquelin
  0 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-25 14:59 UTC (permalink / raw)
  To: Xia, Chenbo, dev, olivier.matz, amorenoz, david.marchand



On 1/22/21 9:55 AM, Xia, Chenbo wrote:
> Hi Maxime,
> 
>> -----Original Message-----
>> From: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Sent: Wednesday, January 20, 2021 5:25 AM
>> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
>> amorenoz@redhat.com; david.marchand@redhat.com
>> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Subject: [PATCH v2 41/44] net/virtio: move Vhost-kernel data to its backend
>>
>> As done earlier for Vhost-user, this patch moves the
>> Vhost-Kernel specific data to its backend file.
>>
>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>> ---
>>  drivers/net/virtio/virtio_user/vhost_kernel.c | 106 +++++++++++++++---
>>  .../net/virtio/virtio_user/virtio_user_dev.c  |  43 ++-----
>>  .../net/virtio/virtio_user/virtio_user_dev.h  |   7 +-
>>  3 files changed, 98 insertions(+), 58 deletions(-)
>>
>> diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c
>> b/drivers/net/virtio/virtio_user/vhost_kernel.c
>> index aa1f9ece5e..bc4b3461e1 100644
>> --- a/drivers/net/virtio/virtio_user/vhost_kernel.c
>> +++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
>> @@ -14,6 +14,11 @@
>>  #include "virtio_user_dev.h"
>>  #include "vhost_kernel_tap.h"
>>
>> +struct vhost_kernel_data {
>> +	int *vhostfds;
>> +	int *tapfds;
>> +};
>> +
>>  struct vhost_memory_kernel {
>>  	uint32_t nregions;
>>  	uint32_t padding;
>> @@ -96,7 +101,9 @@ vhost_kernel_ioctl(int fd, uint64_t request, void *arg)
>>  static int
>>  vhost_kernel_set_owner(struct virtio_user_dev *dev)
>>  {
>> -	return vhost_kernel_ioctl(dev->vhostfds[0], VHOST_SET_OWNER, NULL);
>> +	struct vhost_kernel_data *data = dev->backend_data;
>> +
>> +	return vhost_kernel_ioctl(data->vhostfds[0], VHOST_SET_OWNER, NULL);
>>  }
>>
>>  static int
>> @@ -104,8 +111,9 @@ vhost_kernel_get_features(struct virtio_user_dev *dev,
>> uint64_t *features)
>>  {
>>  	int ret;
>>  	unsigned int tap_features;
>> +	struct vhost_kernel_data *data = dev->backend_data;
>>
>> -	ret = vhost_kernel_ioctl(dev->vhostfds[0], VHOST_GET_FEATURES, features);
>> +	ret = vhost_kernel_ioctl(data->vhostfds[0], VHOST_GET_FEATURES,
>> features);
>>  	if (ret < 0) {
>>  		PMD_DRV_LOG(ERR, "Failed to get features");
>>  		return -1;
>> @@ -138,6 +146,8 @@ vhost_kernel_get_features(struct virtio_user_dev *dev,
>> uint64_t *features)
>>  static int
>>  vhost_kernel_set_features(struct virtio_user_dev *dev, uint64_t features)
>>  {
>> +	struct vhost_kernel_data *data = dev->backend_data;
>> +
>>  	/* We don't need memory protection here */
>>  	features &= ~(1ULL << VIRTIO_F_IOMMU_PLATFORM);
>>  	/* VHOST kernel does not know about below flags */
>> @@ -145,7 +155,7 @@ vhost_kernel_set_features(struct virtio_user_dev *dev,
>> uint64_t features)
>>  	features &= ~VHOST_KERNEL_HOST_OFFLOADS_MASK;
>>  	features &= ~(1ULL << VIRTIO_NET_F_MQ);
>>
>> -	return vhost_kernel_ioctl(dev->vhostfds[0], VHOST_SET_FEATURES,
>> &features);
>> +	return vhost_kernel_ioctl(data->vhostfds[0], VHOST_SET_FEATURES,
>> &features);
>>  }
>>
>>  static int
>> @@ -185,6 +195,7 @@ add_memseg_list(const struct rte_memseg_list *msl, void
>> *arg)
>>  static int
>>  vhost_kernel_set_memory_table(struct virtio_user_dev *dev)
>>  {
>> +	struct vhost_kernel_data *data = dev->backend_data;
>>  	struct vhost_memory_kernel *vm;
>>  	int ret;
>>
>> @@ -205,7 +216,7 @@ vhost_kernel_set_memory_table(struct virtio_user_dev *dev)
>>  	if (ret < 0)
>>  		goto err_free;
>>
>> -	ret = vhost_kernel_ioctl(dev->vhostfds[0], VHOST_SET_MEM_TABLE, vm);
>> +	ret = vhost_kernel_ioctl(data->vhostfds[0], VHOST_SET_MEM_TABLE, vm);
>>  	if (ret < 0)
>>  		goto err_free;
>>
>> @@ -224,9 +235,10 @@ vhost_kernel_set_vring(struct virtio_user_dev *dev,
>> uint64_t req, struct vhost_v
>>  {
>>  	int ret, fd;
>>  	unsigned int index = state->index;
>> +	struct vhost_kernel_data *data = dev->backend_data;
>>
>>  	/* Convert from queue index to queue-pair & offset */
>> -	fd = dev->vhostfds[state->index / 2];
>> +	fd = data->vhostfds[state->index / 2];
>>  	state->index %= 2;
>>
>>  	ret = vhost_kernel_ioctl(fd, req, state);
>> @@ -265,9 +277,10 @@ vhost_kernel_set_vring_file(struct virtio_user_dev *dev,
>> uint64_t req,
>>  {
>>  	int ret, fd;
>>  	unsigned int index = file->index;
>> +	struct vhost_kernel_data *data = dev->backend_data;
>>
>>  	/* Convert from queue index to queue-pair & offset */
>> -	fd = dev->vhostfds[file->index / 2];
>> +	fd = data->vhostfds[file->index / 2];
>>  	file->index %= 2;
>>
>>  	ret = vhost_kernel_ioctl(fd, req, file);
>> @@ -299,9 +312,10 @@ vhost_kernel_set_vring_addr(struct virtio_user_dev *dev,
>> struct vhost_vring_addr
>>  {
>>  	int ret, fd;
>>  	unsigned int index = addr->index;
>> +	struct vhost_kernel_data *data = dev->backend_data;
>>
>>  	/* Convert from queue index to queue-pair & offset */
>> -	fd = dev->vhostfds[addr->index / 2];
>> +	fd = data->vhostfds[addr->index / 2];
>>  	addr->index %= 2;
>>
>>  	ret = vhost_kernel_ioctl(fd, VHOST_SET_VRING_ADDR, addr);
>> @@ -339,27 +353,82 @@ static int
>>  vhost_kernel_setup(struct virtio_user_dev *dev)
>>  {
>>  	int vhostfd;
>> -	uint32_t i;
>> +	uint32_t q, i;
>> +	struct vhost_kernel_data *data;
>> +
>> +	data = malloc(sizeof(*data));
>> +	if (!data) {
>> +		PMD_INIT_LOG(ERR, "(%s) Failed to allocate Vhost-kernel data",
>> dev->path);
>> +		return -1;
>> +	}
>> +
>> +	data->vhostfds = malloc(dev->max_queue_pairs * sizeof(int));
>> +	if (!data->vhostfds) {
>> +		PMD_INIT_LOG(ERR, "(%s) Failed to allocate Vhost FDs", dev->path);
>> +		goto err_data;
>> +	}
>> +	data->tapfds = malloc(dev->max_queue_pairs * sizeof(int));
>> +	if (!data->tapfds) {
>> +		PMD_INIT_LOG(ERR, "(%s) Failed to allocate FDs", dev->path);
> 
> 'allocate tap FDs'?

Done.

> With this fixed:
> 
> Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>

Thanks,
Maxime


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 42/44] net/virtio: move Vhost-vDPA data to its backend
  2021-01-22  9:06   ` Xia, Chenbo
@ 2021-01-25 15:02     ` Maxime Coquelin
  0 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-25 15:02 UTC (permalink / raw)
  To: Xia, Chenbo, dev, olivier.matz, amorenoz, david.marchand



On 1/22/21 10:06 AM, Xia, Chenbo wrote:
> Hi Maxime,
> 
>> -----Original Message-----
>> From: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Sent: Wednesday, January 20, 2021 5:25 AM
>> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
>> amorenoz@redhat.com; david.marchand@redhat.com
>> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Subject: [PATCH v2 42/44] net/virtio: move Vhost-vDPA data to its backend
>>
>> As done earlier for Vhost-user and Vhost-kernel, this
>> patch moves the Vhost-vDPA specific data to its backend
>> file.
>>
>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>> ---
>>  drivers/net/virtio/virtio_user/vhost_vdpa.c   | 120 +++++++++++++-----
>>  .../net/virtio/virtio_user/virtio_user_dev.h  |   4 -
>>  2 files changed, 89 insertions(+), 35 deletions(-)
>>
...
>>
>> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h
>> b/drivers/net/virtio/virtio_user/virtio_user_dev.h
>> index 36a9cadcad..9a6723da24 100644
>> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
>> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
>> @@ -29,9 +29,6 @@ struct virtio_user_dev {
>>  	enum virtio_user_backend_type backend_type;
>>  	bool		is_server;  /* server or client mode */
>>
>> -	/* for vhost_vdpa backend */
>> -	int		vhostfd;
>> -
>>  	/* for both vhost_user and vhost_kernel */
> 
> I remember you agreed that this comment is no longer needed?

Indeed, I missed to remove it. Done now.

> I also noticed that there're multiple calls of PMD_DRV_LOG that add
> '\n' in the end, which is necessary. But, let's clean it up later..

Yes, there may still be redundant new lines at some places, I agree we
fix that later.

> With above fixed:
> 
> Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
> 


Thanks,
Maxime


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 43/44] net/virtio: improve Vhost-user error logging
  2021-01-22  9:11   ` Xia, Chenbo
@ 2021-01-25 15:04     ` Maxime Coquelin
  2021-01-26  6:10       ` Xia, Chenbo
  0 siblings, 1 reply; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-25 15:04 UTC (permalink / raw)
  To: Xia, Chenbo, dev, olivier.matz, amorenoz, david.marchand



On 1/22/21 10:11 AM, Xia, Chenbo wrote:
> Hi Maxime,
> 
>> -----Original Message-----
>> From: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Sent: Wednesday, January 20, 2021 5:25 AM
>> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
>> amorenoz@redhat.com; david.marchand@redhat.com
>> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Subject: [PATCH v2 43/44] net/virtio: improve Vhost-user error logging
>>
>> This patch improves error logging in vhost_user_read,
>> especially printing errno when recv() fails.
>>
>> Suggested-by: Adrian Moreno <amorenoz@redhat.com>
>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>> ---
>>  drivers/net/virtio/virtio_user/vhost_user.c | 29 ++++++++++++---------
>>  1 file changed, 17 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/net/virtio/virtio_user/vhost_user.c
>> b/drivers/net/virtio/virtio_user/vhost_user.c
>> index f046655af6..be91c99cea 100644
>> --- a/drivers/net/virtio/virtio_user/vhost_user.c
>> +++ b/drivers/net/virtio/virtio_user/vhost_user.c
>> @@ -148,38 +148,43 @@ vhost_user_read(int fd, struct vhost_user_msg *msg)
>>  	int ret, sz_hdr = VHOST_USER_HDR_SIZE, sz_payload;
>>
>>  	ret = recv(fd, (void *)msg, sz_hdr, 0);
>> -	if (ret < sz_hdr) {
>> +	if (ret < 0) {
>> +		PMD_DRV_LOG(ERR, "Failed to recv msg header: %s", strerror(errno));
>> +		return -1;
>> +	} else if (ret < sz_hdr) {
>>  		PMD_DRV_LOG(ERR, "Failed to recv msg hdr: %d instead of %d.",
>>  			    ret, sz_hdr);
>> -		goto fail;
>> +		return -1;
>>  	}
>>
>>  	/* validate msg flags */
>>  	if (msg->flags != (valid_flags)) {
>>  		PMD_DRV_LOG(ERR, "Failed to recv msg: flags %x instead of %x.",
>>  			    msg->flags, valid_flags);
>> -		goto fail;
>> +		return -1;
> 
> Since you are here, also add '0x' before '%x' here?

Done.

> Thanks,
> Chenbo

Thanks,
Maxime


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 44/44] net/virtio: handle Virtio-user setup failure properly
  2021-01-22  9:24   ` Xia, Chenbo
@ 2021-01-25 16:16     ` Maxime Coquelin
  0 siblings, 0 replies; 86+ messages in thread
From: Maxime Coquelin @ 2021-01-25 16:16 UTC (permalink / raw)
  To: Xia, Chenbo, dev, olivier.matz, amorenoz, david.marchand



On 1/22/21 10:24 AM, Xia, Chenbo wrote:
> Hi Maxime,
> 
>> -----Original Message-----
>> From: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Sent: Wednesday, January 20, 2021 5:25 AM
>> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>; olivier.matz@6wind.com;
>> amorenoz@redhat.com; david.marchand@redhat.com
>> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
>> Subject: [PATCH v2 44/44] net/virtio: handle Virtio-user setup failure
>> properly
>>
>> This patch fixes virtio_user_dev_setup() error path,
>> by cleaning all resources it allocates.
>>
>> Suggested-by: Adrian Moreno <amorenoz@redhat.com>
>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>> ---
>>  drivers/net/virtio/virtio_user/virtio_user_dev.c | 11 +++++++++--
>>  1 file changed, 9 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c
>> b/drivers/net/virtio/virtio_user/virtio_user_dev.c
>> index a1e32158bb..2f7dc574b6 100644
>> --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
>> +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
>> @@ -427,15 +427,22 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
>>
>>  	if (virtio_user_dev_init_notify(dev) < 0) {
>>  		PMD_INIT_LOG(ERR, "(%s) Failed to init notifiers\n", dev->path);
>> -		return -1;
>> +		goto destroy;
>>  	}
>>
>>  	if (virtio_user_fill_intr_handle(dev) < 0) {
>>  		PMD_INIT_LOG(ERR, "(%s) Failed to init interrupt handler\n", dev-
>>> path);
>> -		return -1;
>> +		goto uninit;
>>  	}
>>
>>  	return 0;
>> +
>> +uninit:
>> +	virtio_user_dev_uninit(dev);
> 
> IMHO, it may not be the best choice to call virtio_user_dev_uninit here..
> 
> Logically when virtio_user_fill_intr_handle fails, we want to release the resources
> which is allocated in virtio_user_dev_init_notify (i.e., fds), but virtio_user_dev_uninit
> does more. For example, unregister the event callback that have not been registered yet and
> it also leads to destroy callback called twice. Although things done but not needed will
> not lead to error, but it looks not in the best way. What do you think?

I agree, I'm reworking it for v3.

Kick and call FDs will be initialized to -1 at virtio_user_dev_init()
time. I introduce a virtio_user_dev_uninit_notify that will close all
kick and call FDs is opened and reset their value to -1.

Thenb I call this function in the error path of virtio_user_dev_setup()
and also in virtio_user_dev_uninit().

Doing that, I can also simplifies virtio_user_dev_init_notify() and only
loop for max queue pairs instead of VIRTIO_MAX_VIRTQUEUES and so avoid
setting FDs to -1 a second time.

Thanks,
Maxime

> Thanks,
> Chenbo
> 
>> +destroy:
>> +	dev->ops->destroy(dev);
>> +
>> +	return -1;
>>  }
>>
>>  /* Use below macro to filter features from vhost backend */
>> --
>> 2.29.2
> 


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [dpdk-dev] [PATCH v2 43/44] net/virtio: improve Vhost-user error logging
  2021-01-25 15:04     ` Maxime Coquelin
@ 2021-01-26  6:10       ` Xia, Chenbo
  0 siblings, 0 replies; 86+ messages in thread
From: Xia, Chenbo @ 2021-01-26  6:10 UTC (permalink / raw)
  To: Maxime Coquelin, dev, olivier.matz, amorenoz, david.marchand

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Monday, January 25, 2021 11:04 PM
> To: Xia, Chenbo <chenbo.xia@intel.com>; dev@dpdk.org; olivier.matz@6wind.com;
> amorenoz@redhat.com; david.marchand@redhat.com
> Subject: Re: [PATCH v2 43/44] net/virtio: improve Vhost-user error logging
> 
> 
> 
> On 1/22/21 10:11 AM, Xia, Chenbo wrote:
> > Hi Maxime,
> >
> >> -----Original Message-----
> >> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> >> Sent: Wednesday, January 20, 2021 5:25 AM
> >> To: dev@dpdk.org; Xia, Chenbo <chenbo.xia@intel.com>;
> olivier.matz@6wind.com;
> >> amorenoz@redhat.com; david.marchand@redhat.com
> >> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> >> Subject: [PATCH v2 43/44] net/virtio: improve Vhost-user error logging
> >>
> >> This patch improves error logging in vhost_user_read,
> >> especially printing errno when recv() fails.
> >>
> >> Suggested-by: Adrian Moreno <amorenoz@redhat.com>
> >> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> >> ---
> >>  drivers/net/virtio/virtio_user/vhost_user.c | 29 ++++++++++++---------
> >>  1 file changed, 17 insertions(+), 12 deletions(-)
> >>
> >> diff --git a/drivers/net/virtio/virtio_user/vhost_user.c
> >> b/drivers/net/virtio/virtio_user/vhost_user.c
> >> index f046655af6..be91c99cea 100644
> >> --- a/drivers/net/virtio/virtio_user/vhost_user.c
> >> +++ b/drivers/net/virtio/virtio_user/vhost_user.c
> >> @@ -148,38 +148,43 @@ vhost_user_read(int fd, struct vhost_user_msg *msg)
> >>  	int ret, sz_hdr = VHOST_USER_HDR_SIZE, sz_payload;
> >>
> >>  	ret = recv(fd, (void *)msg, sz_hdr, 0);
> >> -	if (ret < sz_hdr) {
> >> +	if (ret < 0) {
> >> +		PMD_DRV_LOG(ERR, "Failed to recv msg header: %s", strerror(errno));
> >> +		return -1;
> >> +	} else if (ret < sz_hdr) {
> >>  		PMD_DRV_LOG(ERR, "Failed to recv msg hdr: %d instead of %d.",
> >>  			    ret, sz_hdr);
> >> -		goto fail;
> >> +		return -1;
> >>  	}
> >>
> >>  	/* validate msg flags */
> >>  	if (msg->flags != (valid_flags)) {
> >>  		PMD_DRV_LOG(ERR, "Failed to recv msg: flags %x instead of %x.",
> >>  			    msg->flags, valid_flags);
> >> -		goto fail;
> >> +		return -1;
> >
> > Since you are here, also add '0x' before '%x' here?
> 
> Done.
> 
> > Thanks,
> > Chenbo
> 
> Thanks,
> Maxime

Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>

^ permalink raw reply	[flat|nested] 86+ messages in thread

end of thread, other threads:[~2021-01-26  6:10 UTC | newest]

Thread overview: 86+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-19 21:24 [dpdk-dev] [PATCH v2 00/44] net/virtio: Virtio PMD rework Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 01/44] bus/vdev: add helper to get vdev from eth dev Maxime Coquelin
2021-01-20  0:56   ` Thomas Monjalon
2021-01-25 10:53     ` Maxime Coquelin
2021-01-25 11:04       ` Thomas Monjalon
2021-01-21  8:58   ` Xia, Chenbo
2021-01-25 14:51     ` Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 02/44] bus/vdev: add driver IOVA VA mode requirement Maxime Coquelin
2021-01-20 15:32   ` David Marchand
2021-01-20 17:47     ` Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 03/44] net/virtio: fix getting old status on reconnect Maxime Coquelin
2021-01-21  7:12   ` Xia, Chenbo
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 04/44] net/virtio: introduce Virtio bus type Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 05/44] net/virtio: refactor virtio-user device Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 06/44] net/virtio: introduce PCI device metadata Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 07/44] net/virtio: move PCI device init in dedicated file Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 08/44] net/virtio: move PCI specific dev init to PCI ethdev init Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 09/44] net/virtio: move MSIX detection to PCI ethdev Maxime Coquelin
2021-01-21  7:12   ` Xia, Chenbo
2021-01-25 12:41     ` Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 10/44] net/virtio: force IOVA as VA mode for Virtio-user Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 11/44] net/virtio: store PCI type in Virtio device metadata Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 12/44] net/virtio: add callback for device closing Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 13/44] net/virtio: validate features at bus level Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 14/44] net/virtio: remove bus type enum Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 15/44] net/virtio: move PCI-specific fields to PCI device Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 16/44] net/virtio: pack virtio HW struct Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 17/44] net/virtio: move legacy IO to Virtio PCI Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 18/44] net/virtio: introduce generic virtio header Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 19/44] net/virtio: move features definition to generic header Maxime Coquelin
2021-01-21  6:47   ` Xia, Chenbo
2021-01-25 12:35     ` Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 20/44] net/virtio: move virtqueue defines in " Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 21/44] net/virtio: move config definitions to " Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 22/44] net/virtio: make interrupt handling more generic Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 23/44] net/virtio: move vring alignment to generic header Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 24/44] net/virtio: remove last PCI refs in non-PCI code Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 25/44] net/virtio: make Vhost-user req sender consistent Maxime Coquelin
2021-01-21  8:50   ` Xia, Chenbo
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 26/44] net/virtio: add Virtio-user ops to set owner Maxime Coquelin
2021-01-22  3:27   ` Xia, Chenbo
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 27/44] net/virtio: add Virtio-user features ops Maxime Coquelin
2021-01-22  7:25   ` Xia, Chenbo
2021-01-25 14:53     ` Maxime Coquelin
2021-01-22  8:46   ` Xia, Chenbo
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 28/44] net/virtio: add Virtio-user protocol " Maxime Coquelin
2021-01-22  7:27   ` Xia, Chenbo
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 29/44] net/virtio: add Virtio-user memory tables ops Maxime Coquelin
2021-01-22  7:34   ` Xia, Chenbo
2021-01-25 14:56     ` Maxime Coquelin
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 30/44] net/virtio: add Virtio-user vring setting ops Maxime Coquelin
2021-01-22  7:49   ` Xia, Chenbo
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 31/44] net/virtio: add Virtio-user vring file ops Maxime Coquelin
2021-01-22  8:01   ` Xia, Chenbo
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 32/44] net/virtio: add Virtio-user vring address ops Maxime Coquelin
2021-01-22  8:02   ` Xia, Chenbo
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 33/44] net/virtio: add Virtio-user status ops Maxime Coquelin
2021-01-22  8:02   ` Xia, Chenbo
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 34/44] net/virtio: remove useless request ops Maxime Coquelin
2021-01-22  8:10   ` Xia, Chenbo
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 35/44] net/virtio: improve Virtio-user errors handling Maxime Coquelin
2021-01-22  8:10   ` Xia, Chenbo
2021-01-19 21:24 ` [dpdk-dev] [PATCH v2 36/44] net/virtio: move Vhost-user reqs to Vhost-user backend Maxime Coquelin
2021-01-21  8:56   ` Xia, Chenbo
2021-01-25 14:50     ` Maxime Coquelin
2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 37/44] net/virtio: make server mode blocking Maxime Coquelin
2021-01-22  8:19   ` Xia, Chenbo
2021-01-19 21:25 ` [dpdk-dev] [PATCH v2 38/44] net/virtio: move protocol features to Vhost-user Maxime Coquelin
2021-01-22  8:20   ` Xia, Chenbo