DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH v1 0/4] add async data path in vhost sample
@ 2020-09-10  6:43 Cheng Jiang
  2020-09-10  6:43 ` [dpdk-dev] [PATCH v1 1/4] example/vhost: add async vhost driver args parsing function Cheng Jiang
                   ` (5 more replies)
  0 siblings, 6 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-09-10  6:43 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang, john.mcnamara,
	marko.kovacevic
  Cc: dev, patrick.fu, Cheng Jiang

This patch set makes vhost-vswitch be able to use vhost async APIs
for enqueue operations. Demonstrated how the application
leverage IOAT DMA channel with vhost async APIs.

We introduce two parameters to enable DMA acceleration for Tx
operations of queues:
-async_vhost_driver Async vhost-user net driver will be used when this
option is given. It is disabled by default.
-dmas This parameter is used to specify the assigned DMA device of a
vhost device.

Cheng Jiang (4):
  example/vhost: add async vhost driver args parsing function
  example/vhost: add support for vhost async data path
  doc: update vhost sample doc for vhost async data path
  doc: update release notes for vhost sample

 doc/guides/rel_notes/release_20_11.rst |   6 +
 doc/guides/sample_app_ug/vhost.rst     |  10 +
 examples/vhost/main.c                  | 254 ++++++++++++++++++++++++-
 examples/vhost/main.h                  |   1 +
 4 files changed, 267 insertions(+), 4 deletions(-)

--
2.27.0


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

* [dpdk-dev] [PATCH v1 1/4] example/vhost: add async vhost driver args parsing function
  2020-09-10  6:43 [dpdk-dev] [PATCH v1 0/4] add async data path in vhost sample Cheng Jiang
@ 2020-09-10  6:43 ` Cheng Jiang
  2020-09-23  8:25   ` Maxime Coquelin
  2020-09-10  6:43 ` [dpdk-dev] [PATCH v1 2/4] example/vhost: add support for vhost async data path Cheng Jiang
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 71+ messages in thread
From: Cheng Jiang @ 2020-09-10  6:43 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang, john.mcnamara,
	marko.kovacevic
  Cc: dev, patrick.fu, Cheng Jiang

This patch is to add async vhost driver arguments parsing function
for CBDMA channel. With these arguments vhost sample can be set to
use CBDMA or CPU for enqueue operation and bind vhost device with
specific CBDMA channel to accelerate vhost data-path.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 examples/vhost/main.c | 133 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 131 insertions(+), 2 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index e1578e795..011e3da21 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -24,6 +24,9 @@
 #include <rte_ip.h>
 #include <rte_tcp.h>
 #include <rte_pause.h>
+#include <rte_rawdev.h>
+#include <rte_ioat_rawdev.h>
+#include <rte_pci.h>
 
 #include "main.h"
 
@@ -58,6 +61,12 @@
 /* Maximum long option length for option parsing. */
 #define MAX_LONG_OPT_SZ 64
 
+#define IOAT_RING_SIZE 4096
+
+#define MAX_ENQUEUED_SIZE 2048
+
+#define MAX_VHOST_DEVICE 1024
+
 /* mask of enabled ports */
 static uint32_t enabled_port_mask = 0;
 
@@ -96,6 +105,21 @@ static int dequeue_zero_copy;
 
 static int builtin_net_driver;
 
+static int async_vhost_driver;
+
+struct dma_info {
+	struct rte_pci_addr addr;
+	uint16_t dev_id;
+	bool is_valid;
+};
+
+struct dma_for_vhost {
+	struct dma_info dmas[RTE_MAX_QUEUES_PER_PORT * 2];
+	uint16_t nr;
+};
+
+static struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
+
 /* Specify timeout (in useconds) between retries on RX. */
 static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
 /* Specify the number of retries on RX. */
@@ -182,6 +206,97 @@ struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];
 				 / US_PER_S * BURST_TX_DRAIN_US)
 #define VLAN_HLEN       4
 
+static inline int
+open_dma(const char *value, void *dma_bind_info)
+{
+	struct dma_for_vhost *dma_info = dma_bind_info;
+	char *input = strndup(value, strlen(value) + 1);
+	char *addrs = input;
+	char *ptrs[2];
+	char *start, *end, *substr;
+	int64_t vid, vring_id;
+	struct rte_ioat_rawdev_config config;
+	struct rte_rawdev_info info = { .dev_private = &config };
+	char name[32];
+	int dev_id;
+	int ret = 0;
+	uint16_t i = 0;
+
+	while (isblank(*addrs))
+		addrs++;
+	if (*addrs == '\0') {
+		ret = -1;
+		goto out;
+	}
+
+	/* process DMA devices within bracket. */
+	addrs++;
+	substr = strtok(addrs, ";]");
+	if (!substr) {
+		ret = -1;
+		goto out;
+	}
+	char *dma_arg[MAX_VHOST_DEVICE];
+	rte_strsplit(substr, strlen(substr), dma_arg, MAX_VHOST_DEVICE, ',');
+	do {
+		char *arg_temp = dma_arg[i];
+		rte_strsplit(arg_temp, strlen(arg_temp), ptrs, 2, '@');
+
+		start = strstr(ptrs[0], "txd");
+		if (start == NULL) {
+			ret = -1;
+			goto out;
+		}
+
+		start += 3;
+		vid = strtol(start, &end, 0);
+		if (end == start) {
+			ret = -1;
+			goto out;
+		}
+
+		vring_id = 0 + VIRTIO_RXQ;
+		if (rte_pci_addr_parse(ptrs[1],
+				&(dma_info + vid)->dmas[vring_id].addr) < 0) {
+			ret = -1;
+			goto out;
+		}
+
+		rte_pci_device_name(&(dma_info + vid)->dmas[vring_id].addr,
+				    name, sizeof(name));
+		dev_id = rte_rawdev_get_dev_id(name);
+		if (dev_id == (uint16_t)(-ENODEV) ||
+		    dev_id == (uint16_t)(-EINVAL)) {
+			ret = -1;
+			goto out;
+		}
+
+		if (rte_rawdev_info_get(dev_id, &info) < 0 ||
+		    strstr(info.driver_name, "ioat") == NULL) {
+			ret = -1;
+			goto out;
+		}
+
+		(dma_info + vid)->dmas[vring_id].dev_id = dev_id;
+		(dma_info + vid)->dmas[vring_id].is_valid = true;
+		config.ring_size = IOAT_RING_SIZE;
+		if (rte_rawdev_configure(dev_id, &info) < 0) {
+			ret = -1;
+			goto out;
+		}
+		rte_rawdev_start(dev_id);
+
+		dma_info->nr++;
+
+		arg_temp = strtok(NULL, ";]");
+		i++;
+	} while (dma_arg[i]);
+
+out:
+	free(input);
+	return ret;
+}
+
 /*
  * Builds up the correct configuration for VMDQ VLAN pool map
  * according to the pool & queue limits.
@@ -485,6 +600,8 @@ us_vhost_parse_args(int argc, char **argv)
 		{"client", no_argument, &client_mode, 1},
 		{"dequeue-zero-copy", no_argument, &dequeue_zero_copy, 1},
 		{"builtin-net-driver", no_argument, &builtin_net_driver, 1},
+		{"async_vhost_driver", no_argument, &async_vhost_driver, 1},
+		{"dmas", required_argument, NULL, 0},
 		{NULL, 0, 0, 0},
 	};
 
@@ -620,13 +737,25 @@ us_vhost_parse_args(int argc, char **argv)
 						"socket-file", MAX_LONG_OPT_SZ)) {
 				if (us_vhost_parse_socket_path(optarg) == -1) {
 					RTE_LOG(INFO, VHOST_CONFIG,
-					"Invalid argument for socket name (Max %d characters)\n",
-					PATH_MAX);
+						"Invalid argument for socket name (Max %d characters)\n",
+						PATH_MAX);
 					us_vhost_usage(prgname);
 					return -1;
 				}
 			}
 
+			if (!strncmp(long_option[option_index].name,
+						"dmas", MAX_LONG_OPT_SZ)) {
+				if (open_dma(optarg, &dma_bind) == -1) {
+					if (*optarg == -1) {
+						RTE_LOG(INFO, VHOST_CONFIG,
+							"Wrong DMA args\n");
+						us_vhost_usage(prgname);
+						return -1;
+					}
+				}
+			}
+
 			break;
 
 			/* Invalid option - print options. */
-- 
2.27.0


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

* [dpdk-dev] [PATCH v1 2/4] example/vhost: add support for vhost async data path
  2020-09-10  6:43 [dpdk-dev] [PATCH v1 0/4] add async data path in vhost sample Cheng Jiang
  2020-09-10  6:43 ` [dpdk-dev] [PATCH v1 1/4] example/vhost: add async vhost driver args parsing function Cheng Jiang
@ 2020-09-10  6:43 ` Cheng Jiang
  2020-09-10  6:43 ` [dpdk-dev] [PATCH v1 3/4] doc: update vhost sample doc " Cheng Jiang
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-09-10  6:43 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang, john.mcnamara,
	marko.kovacevic
  Cc: dev, patrick.fu, Cheng Jiang

This patch is to implement vhost DMA operation callbacks for CBDMA
PMD and add vhost async data-path in vhost sample. With providing
callback implementation for CBDMA, vhost sample can leverage
CBDMA to accelerate vhost async data-path.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 examples/vhost/main.c | 129 ++++++++++++++++++++++++++++++++++++++++--
 examples/vhost/main.h |   1 +
 2 files changed, 124 insertions(+), 6 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 011e3da21..b2a4e4370 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -24,6 +24,7 @@
 #include <rte_ip.h>
 #include <rte_tcp.h>
 #include <rte_pause.h>
+#include <rte_vhost_async.h>
 #include <rte_rawdev.h>
 #include <rte_ioat_rawdev.h>
 #include <rte_pci.h>
@@ -31,7 +32,7 @@
 #include "main.h"
 
 #ifndef MAX_QUEUES
-#define MAX_QUEUES 128
+#define MAX_QUEUES 512
 #endif
 
 /* the maximum number of external ports supported */
@@ -165,6 +166,62 @@ static struct rte_eth_conf vmdq_conf_default = {
 	},
 };
 
+static uint32_t
+ioat_transfer_data_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_desc *descs,
+		struct rte_vhost_async_status *opaque_data, uint16_t count)
+{
+	int ret;
+	uint32_t i_desc;
+
+	struct rte_vhost_iov_iter *src = NULL;
+	struct rte_vhost_iov_iter *dst = NULL;
+	unsigned long i_seg;
+
+	int dev_id = dma_bind[vid].dmas[queue_id * 2 + VIRTIO_RXQ].dev_id;
+	if (likely(!opaque_data)) {
+		for (i_desc = 0; i_desc < count; i_desc++) {
+			src = descs[i_desc].src;
+			dst = descs[i_desc].dst;
+			i_seg = 0;
+			while (i_seg < src->nr_segs) {
+				ret = rte_ioat_enqueue_copy(dev_id,
+					(uintptr_t)(src->iov[i_seg].iov_base)
+						+ src->offset,
+					(uintptr_t)(dst->iov[i_seg].iov_base)
+						+ dst->offset,
+					src->iov[i_seg].iov_len,
+					0,
+					0,
+					0);
+				if (ret != 1)
+					break;
+				i_seg++;
+			}
+		}
+	} else {
+		/* Opaque data is not supported */
+		return -1;
+	}
+	/* ring the doorbell */
+	rte_ioat_do_copies(dev_id);
+	return i_desc;
+}
+
+static uint32_t
+ioat_check_completed_copies_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_status *opaque_data,
+		uint16_t max_packets __rte_unused)
+{
+	if (!opaque_data) {
+		uintptr_t dump[255];
+		return rte_ioat_completed_copies(dma_bind[vid].dmas[queue_id * 2
+			+ VIRTIO_RXQ].dev_id, 255, dump, dump);
+	} else {
+		/* Opaque data is not supported */
+		return -1;
+	}
+}
 
 static unsigned lcore_ids[RTE_MAX_LCORE];
 static uint16_t ports[RTE_MAX_ETHPORTS];
@@ -206,6 +263,11 @@ struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];
 				 / US_PER_S * BURST_TX_DRAIN_US)
 #define VLAN_HLEN       4
 
+/*
+ * Builds up the correct configuration for VMDQ VLAN pool map
+ * according to the pool & queue limits.
+ */
+
 static inline int
 open_dma(const char *value, void *dma_bind_info)
 {
@@ -297,10 +359,6 @@ open_dma(const char *value, void *dma_bind_info)
 	return ret;
 }
 
-/*
- * Builds up the correct configuration for VMDQ VLAN pool map
- * according to the pool & queue limits.
- */
 static inline int
 get_eth_conf(struct rte_eth_conf *eth_conf, uint32_t num_devices)
 {
@@ -911,9 +969,26 @@ virtio_xmit(struct vhost_dev *dst_vdev, struct vhost_dev *src_vdev,
 	    struct rte_mbuf *m)
 {
 	uint16_t ret;
+	struct rte_mbuf *m_cpl[1];
 
 	if (builtin_net_driver) {
 		ret = vs_enqueue_pkts(dst_vdev, VIRTIO_RXQ, &m, 1);
+	} else if (async_vhost_driver) {
+		ret = rte_vhost_submit_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ,
+						&m, 1);
+
+		if (likely(ret)) {
+			dst_vdev->nr_async_pkts++;
+			rte_mbuf_refcnt_update(m, 1);
+		}
+
+		while (likely(dst_vdev->nr_async_pkts)) {
+			if (rte_vhost_poll_enqueue_completed(dst_vdev->vid,
+					VIRTIO_RXQ, m_cpl, 1)) {
+				dst_vdev->nr_async_pkts--;
+				rte_pktmbuf_free(*m_cpl);
+			}
+		}
 	} else {
 		ret = rte_vhost_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ, &m, 1);
 	}
@@ -1162,6 +1237,19 @@ drain_mbuf_table(struct mbuf_table *tx_q)
 	}
 }
 
+static __rte_always_inline void
+complete_async_pkts(struct vhost_dev *vdev, uint16_t qid)
+{
+	struct rte_mbuf *p_cpl[MAX_PKT_BURST];
+	uint16_t complete_count;
+
+	complete_count = rte_vhost_poll_enqueue_completed(vdev->vid,
+						qid, p_cpl, MAX_PKT_BURST);
+	vdev->nr_async_pkts -= complete_count;
+	if (complete_count)
+		free_pkts(p_cpl, complete_count);
+}
+
 static __rte_always_inline void
 drain_eth_rx(struct vhost_dev *vdev)
 {
@@ -1170,6 +1258,10 @@ drain_eth_rx(struct vhost_dev *vdev)
 
 	rx_count = rte_eth_rx_burst(ports[0], vdev->vmdq_rx_q,
 				    pkts, MAX_PKT_BURST);
+
+	while (likely(vdev->nr_async_pkts))
+		complete_async_pkts(vdev, VIRTIO_RXQ);
+
 	if (!rx_count)
 		return;
 
@@ -1194,16 +1286,22 @@ drain_eth_rx(struct vhost_dev *vdev)
 	if (builtin_net_driver) {
 		enqueue_count = vs_enqueue_pkts(vdev, VIRTIO_RXQ,
 						pkts, rx_count);
+	} else if (async_vhost_driver) {
+		enqueue_count = rte_vhost_submit_enqueue_burst(vdev->vid,
+					VIRTIO_RXQ, pkts, rx_count);
+		vdev->nr_async_pkts += enqueue_count;
 	} else {
 		enqueue_count = rte_vhost_enqueue_burst(vdev->vid, VIRTIO_RXQ,
 						pkts, rx_count);
 	}
+
 	if (enable_stats) {
 		rte_atomic64_add(&vdev->stats.rx_total_atomic, rx_count);
 		rte_atomic64_add(&vdev->stats.rx_atomic, enqueue_count);
 	}
 
-	free_pkts(pkts, rx_count);
+	if (!async_vhost_driver)
+		free_pkts(pkts, rx_count);
 }
 
 static __rte_always_inline void
@@ -1350,6 +1448,9 @@ destroy_device(int vid)
 		"(%d) device has been removed from data core\n",
 		vdev->vid);
 
+	if (async_vhost_driver)
+		rte_vhost_async_channel_unregister(vid, VIRTIO_RXQ);
+
 	rte_free(vdev);
 }
 
@@ -1364,6 +1465,12 @@ new_device(int vid)
 	uint32_t device_num_min = num_devices;
 	struct vhost_dev *vdev;
 
+	struct rte_vhost_async_channel_ops channel_ops = {
+		.transfer_data = ioat_transfer_data_cb,
+		.check_completed_copies = ioat_check_completed_copies_cb
+	};
+	struct rte_vhost_async_features f;
+
 	vdev = rte_zmalloc("vhost device", sizeof(*vdev), RTE_CACHE_LINE_SIZE);
 	if (vdev == NULL) {
 		RTE_LOG(INFO, VHOST_DATA,
@@ -1404,6 +1511,13 @@ new_device(int vid)
 		"(%d) device has been added to data core %d\n",
 		vid, vdev->coreid);
 
+	if (async_vhost_driver) {
+		f.async_inorder = 1;
+		f.async_threshold = 256;
+		return rte_vhost_async_channel_register(vid, VIRTIO_RXQ,
+			f.intval, &channel_ops);
+	}
+
 	return 0;
 }
 
@@ -1645,6 +1759,9 @@ main(int argc, char *argv[])
 	/* Register vhost user driver to handle vhost messages. */
 	for (i = 0; i < nb_sockets; i++) {
 		char *file = socket_files + i * PATH_MAX;
+		if (async_vhost_driver)
+			flags = flags | RTE_VHOST_USER_ASYNC_COPY;
+
 		ret = rte_vhost_driver_register(file, flags);
 		if (ret != 0) {
 			unregister_drivers(i);
diff --git a/examples/vhost/main.h b/examples/vhost/main.h
index 7cba0edbf..4317b6ae8 100644
--- a/examples/vhost/main.h
+++ b/examples/vhost/main.h
@@ -51,6 +51,7 @@ struct vhost_dev {
 	uint64_t features;
 	size_t hdr_len;
 	uint16_t nr_vrings;
+	uint16_t nr_async_pkts;
 	struct rte_vhost_memory *mem;
 	struct device_statistics stats;
 	TAILQ_ENTRY(vhost_dev) global_vdev_entry;
-- 
2.27.0


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

* [dpdk-dev] [PATCH v1 3/4] doc: update vhost sample doc for vhost async data path
  2020-09-10  6:43 [dpdk-dev] [PATCH v1 0/4] add async data path in vhost sample Cheng Jiang
  2020-09-10  6:43 ` [dpdk-dev] [PATCH v1 1/4] example/vhost: add async vhost driver args parsing function Cheng Jiang
  2020-09-10  6:43 ` [dpdk-dev] [PATCH v1 2/4] example/vhost: add support for vhost async data path Cheng Jiang
@ 2020-09-10  6:43 ` Cheng Jiang
  2020-09-10  6:43 ` [dpdk-dev] [PATCH v1 4/4] doc: update release notes for vhost sample Cheng Jiang
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-09-10  6:43 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang, john.mcnamara,
	marko.kovacevic
  Cc: dev, patrick.fu, Cheng Jiang

Add vhost async driver arguments information for vhost async data
path in vhost sample application.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 doc/guides/sample_app_ug/vhost.rst | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/doc/guides/sample_app_ug/vhost.rst b/doc/guides/sample_app_ug/vhost.rst
index b7ed4f8bd..c8b5c7c9a 100644
--- a/doc/guides/sample_app_ug/vhost.rst
+++ b/doc/guides/sample_app_ug/vhost.rst
@@ -162,6 +162,16 @@ enabled and cannot be disabled.
 A very simple vhost-user net driver which demonstrates how to use the generic
 vhost APIs will be used when this option is given. It is disabled by default.
 
+**--async_vhost_driver**
+Async vhost-user net driver which demonstrates how to use the async vhost APIs
+will be used when this option is given. It is disabled by default.
+
+**--dmas**
+This parameter is used to specify the assigned DMA device of a vhost device.
+For example --dmas [txd0@00:04.0,txd1@00:04.1] means use CBDMA channel 00:04.0
+for vhost device 0 enqueue operation and use CBDMA channel 00:04.1 for vhost
+device 1 enqueue operation.
+
 Common Issues
 -------------
 
-- 
2.27.0


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

* [dpdk-dev] [PATCH v1 4/4] doc: update release notes for vhost sample
  2020-09-10  6:43 [dpdk-dev] [PATCH v1 0/4] add async data path in vhost sample Cheng Jiang
                   ` (2 preceding siblings ...)
  2020-09-10  6:43 ` [dpdk-dev] [PATCH v1 3/4] doc: update vhost sample doc " Cheng Jiang
@ 2020-09-10  6:43 ` Cheng Jiang
  2020-09-29  6:42 ` [dpdk-dev] [PATCH v2 0/4] add async data path in " Cheng Jiang
  2020-10-22  8:59 ` [dpdk-dev] [PATCH v10 " Cheng Jiang
  5 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-09-10  6:43 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang, john.mcnamara,
	marko.kovacevic
  Cc: dev, patrick.fu, Cheng Jiang

Add release notes for vhost async data path support in vhost sample.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 doc/guides/rel_notes/release_20_11.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst
index df227a177..6e3d09cb2 100644
--- a/doc/guides/rel_notes/release_20_11.rst
+++ b/doc/guides/rel_notes/release_20_11.rst
@@ -55,6 +55,12 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Updated vhost sample application.**
+
+  Added vhost asynchronous APIs support, which demonstrated how the application
+  leverage IOAT DMA channel with vhost asynchronous APIs.
+  See the :doc:`../sample_app_ug/vhost` for more details.
+
 
 Removed Items
 -------------
-- 
2.27.0


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

* Re: [dpdk-dev] [PATCH v1 1/4] example/vhost: add async vhost driver args parsing function
  2020-09-10  6:43 ` [dpdk-dev] [PATCH v1 1/4] example/vhost: add async vhost driver args parsing function Cheng Jiang
@ 2020-09-23  8:25   ` Maxime Coquelin
  2020-09-28  6:09     ` Jiang, Cheng1
  0 siblings, 1 reply; 71+ messages in thread
From: Maxime Coquelin @ 2020-09-23  8:25 UTC (permalink / raw)
  To: Cheng Jiang, chenbo.xia, zhihong.wang, john.mcnamara, marko.kovacevic
  Cc: dev, patrick.fu



On 9/10/20 8:43 AM, Cheng Jiang wrote:
> This patch is to add async vhost driver arguments parsing function
> for CBDMA channel. With these arguments vhost sample can be set to
> use CBDMA or CPU for enqueue operation and bind vhost device with
> specific CBDMA channel to accelerate vhost data-path.
> 
> Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
> ---
>  examples/vhost/main.c | 133 +++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 131 insertions(+), 2 deletions(-)
> 
> diff --git a/examples/vhost/main.c b/examples/vhost/main.c
> index e1578e795..011e3da21 100644
> --- a/examples/vhost/main.c
> +++ b/examples/vhost/main.c
> @@ -24,6 +24,9 @@
>  #include <rte_ip.h>
>  #include <rte_tcp.h>
>  #include <rte_pause.h>
> +#include <rte_rawdev.h>
> +#include <rte_ioat_rawdev.h>
> +#include <rte_pci.h>
>  
>  #include "main.h"
>  
> @@ -58,6 +61,12 @@
>  /* Maximum long option length for option parsing. */
>  #define MAX_LONG_OPT_SZ 64
>  
> +#define IOAT_RING_SIZE 4096
> +
> +#define MAX_ENQUEUED_SIZE 2048
> +
> +#define MAX_VHOST_DEVICE 1024
> +
>  /* mask of enabled ports */
>  static uint32_t enabled_port_mask = 0;
>  
> @@ -96,6 +105,21 @@ static int dequeue_zero_copy;
>  
>  static int builtin_net_driver;
>  
> +static int async_vhost_driver;
> +
> +struct dma_info {
> +	struct rte_pci_addr addr;
> +	uint16_t dev_id;
> +	bool is_valid;
> +};
> +
> +struct dma_for_vhost {
> +	struct dma_info dmas[RTE_MAX_QUEUES_PER_PORT * 2];
> +	uint16_t nr;
> +};
> +
> +static struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
> +
>  /* Specify timeout (in useconds) between retries on RX. */
>  static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
>  /* Specify the number of retries on RX. */
> @@ -182,6 +206,97 @@ struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];
>  				 / US_PER_S * BURST_TX_DRAIN_US)
>  #define VLAN_HLEN       4
>  
> +static inline int
> +open_dma(const char *value, void *dma_bind_info)
> +{
> +	struct dma_for_vhost *dma_info = dma_bind_info;
> +	char *input = strndup(value, strlen(value) + 1);
> +	char *addrs = input;
> +	char *ptrs[2];
> +	char *start, *end, *substr;
> +	int64_t vid, vring_id;
> +	struct rte_ioat_rawdev_config config;
> +	struct rte_rawdev_info info = { .dev_private = &config };
> +	char name[32];
> +	int dev_id;
> +	int ret = 0;
> +	uint16_t i = 0;
> +
> +	while (isblank(*addrs))
> +		addrs++;
> +	if (*addrs == '\0') {
> +		ret = -1;
> +		goto out;
> +	}
> +
> +	/* process DMA devices within bracket. */
> +	addrs++;
> +	substr = strtok(addrs, ";]");
> +	if (!substr) {
> +		ret = -1;
> +		goto out;
> +	}
> +	char *dma_arg[MAX_VHOST_DEVICE];
> +	rte_strsplit(substr, strlen(substr), dma_arg, MAX_VHOST_DEVICE, ',');
> +	do {
> +		char *arg_temp = dma_arg[i];
> +		rte_strsplit(arg_temp, strlen(arg_temp), ptrs, 2, '@');
> +
> +		start = strstr(ptrs[0], "txd");
> +		if (start == NULL) {
> +			ret = -1;
> +			goto out;
> +		}
> +
> +		start += 3;
> +		vid = strtol(start, &end, 0);
> +		if (end == start) {
> +			ret = -1;
> +			goto out;
> +		}
> +
> +		vring_id = 0 + VIRTIO_RXQ;
> +		if (rte_pci_addr_parse(ptrs[1],
> +				&(dma_info + vid)->dmas[vring_id].addr) < 0) {
> +			ret = -1;
> +			goto out;
> +		}
> +
> +		rte_pci_device_name(&(dma_info + vid)->dmas[vring_id].addr,
> +				    name, sizeof(name));
> +		dev_id = rte_rawdev_get_dev_id(name);
> +		if (dev_id == (uint16_t)(-ENODEV) ||
> +		    dev_id == (uint16_t)(-EINVAL)) {
> +			ret = -1;
> +			goto out;
> +		}
> +
> +		if (rte_rawdev_info_get(dev_id, &info) < 0 ||
> +		    strstr(info.driver_name, "ioat") == NULL) {
> +			ret = -1;
> +			goto out;
> +		}
> +
> +		(dma_info + vid)->dmas[vring_id].dev_id = dev_id;
> +		(dma_info + vid)->dmas[vring_id].is_valid = true;
> +		config.ring_size = IOAT_RING_SIZE;
> +		if (rte_rawdev_configure(dev_id, &info) < 0) {
> +			ret = -1;
> +			goto out;
> +		}
> +		rte_rawdev_start(dev_id);
> +
> +		dma_info->nr++;
> +
> +		arg_temp = strtok(NULL, ";]");
> +		i++;
> +	} while (dma_arg[i]);
> +
> +out:
> +	free(input);
> +	return ret;
> +}
> +

I think this is purely Intel specifics, so using generic "dma" name is
not a good idea.
Also, as this is HW specific, it should be moved to a dedicated file
which would only be compiled if all dependencies are met. (it does not
even build on X86:
http://mails.dpdk.org/archives/test-report/2020-September/151519.html)

>  /*
>   * Builds up the correct configuration for VMDQ VLAN pool map
>   * according to the pool & queue limits.
> @@ -485,6 +600,8 @@ us_vhost_parse_args(int argc, char **argv)
>  		{"client", no_argument, &client_mode, 1},
>  		{"dequeue-zero-copy", no_argument, &dequeue_zero_copy, 1},
>  		{"builtin-net-driver", no_argument, &builtin_net_driver, 1},
> +		{"async_vhost_driver", no_argument, &async_vhost_driver, 1},

Shouldn't it be in patch 2 where it is used?
Also, I wonder whether it is really necessary, as as soon as you pass
dmas parameter you know you'll want to use async mode, no?

> +		{"dmas", required_argument, NULL, 0},
>  		{NULL, 0, 0, 0},
>  	};
>  
> @@ -620,13 +737,25 @@ us_vhost_parse_args(int argc, char **argv)
>  						"socket-file", MAX_LONG_OPT_SZ)) {
>  				if (us_vhost_parse_socket_path(optarg) == -1) {
>  					RTE_LOG(INFO, VHOST_CONFIG,
> -					"Invalid argument for socket name (Max %d characters)\n",
> -					PATH_MAX);
> +						"Invalid argument for socket name (Max %d characters)\n",
> +						PATH_MAX);
>  					us_vhost_usage(prgname);
>  					return -1;
>  				}
>  			}
>  
> +			if (!strncmp(long_option[option_index].name,
> +						"dmas", MAX_LONG_OPT_SZ)) {
> +				if (open_dma(optarg, &dma_bind) == -1) {
> +					if (*optarg == -1) {
> +						RTE_LOG(INFO, VHOST_CONFIG,
> +							"Wrong DMA args\n");
> +						us_vhost_usage(prgname);

You need to update us_vhost_usage() to document the new arguments.

> +						return -1;
> +					}
> +				}
> +			}
> +
>  			break;
>  
>  			/* Invalid option - print options. */
> 


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

* Re: [dpdk-dev] [PATCH v1 1/4] example/vhost: add async vhost driver args parsing function
  2020-09-23  8:25   ` Maxime Coquelin
@ 2020-09-28  6:09     ` Jiang, Cheng1
  0 siblings, 0 replies; 71+ messages in thread
From: Jiang, Cheng1 @ 2020-09-28  6:09 UTC (permalink / raw)
  To: Maxime Coquelin, Xia, Chenbo, Wang, Zhihong, Mcnamara, John,
	Kovacevic, Marko
  Cc: dev, Fu, Patrick

Hi Maxime,

Thanks for your comments.
The replies are inline.

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, September 23, 2020 4:25 PM
> To: Jiang, Cheng1 <cheng1.jiang@intel.com>; Xia, Chenbo
> <chenbo.xia@intel.com>; Wang, Zhihong <zhihong.wang@intel.com>;
> Mcnamara, John <john.mcnamara@intel.com>; Kovacevic, Marko
> <marko.kovacevic@intel.com>
> Cc: dev@dpdk.org; Fu, Patrick <patrick.fu@intel.com>
> Subject: Re: [PATCH v1 1/4] example/vhost: add async vhost driver args
> parsing function
> 
> 
> 
> On 9/10/20 8:43 AM, Cheng Jiang wrote:
> > This patch is to add async vhost driver arguments parsing function for
> > CBDMA channel. With these arguments vhost sample can be set to use
> > CBDMA or CPU for enqueue operation and bind vhost device with specific
> > CBDMA channel to accelerate vhost data-path.
> >
> > Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
> > ---
> >  examples/vhost/main.c | 133
> > +++++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 131 insertions(+), 2 deletions(-)
> >
> > diff --git a/examples/vhost/main.c b/examples/vhost/main.c index
> > e1578e795..011e3da21 100644
> > --- a/examples/vhost/main.c
> > +++ b/examples/vhost/main.c
> > @@ -24,6 +24,9 @@
> >  #include <rte_ip.h>
> >  #include <rte_tcp.h>
> >  #include <rte_pause.h>
> > +#include <rte_rawdev.h>
> > +#include <rte_ioat_rawdev.h>
> > +#include <rte_pci.h>
> >
> >  #include "main.h"
> >
> > @@ -58,6 +61,12 @@
> >  /* Maximum long option length for option parsing. */  #define
> > MAX_LONG_OPT_SZ 64
> >
> > +#define IOAT_RING_SIZE 4096
> > +
> > +#define MAX_ENQUEUED_SIZE 2048
> > +
> > +#define MAX_VHOST_DEVICE 1024
> > +
> >  /* mask of enabled ports */
> >  static uint32_t enabled_port_mask = 0;
> >
> > @@ -96,6 +105,21 @@ static int dequeue_zero_copy;
> >
> >  static int builtin_net_driver;
> >
> > +static int async_vhost_driver;
> > +
> > +struct dma_info {
> > +	struct rte_pci_addr addr;
> > +	uint16_t dev_id;
> > +	bool is_valid;
> > +};
> > +
> > +struct dma_for_vhost {
> > +	struct dma_info dmas[RTE_MAX_QUEUES_PER_PORT * 2];
> > +	uint16_t nr;
> > +};
> > +
> > +static struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
> > +
> >  /* Specify timeout (in useconds) between retries on RX. */  static
> > uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
> >  /* Specify the number of retries on RX. */ @@ -182,6 +206,97 @@
> > struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];
> >  				 / US_PER_S * BURST_TX_DRAIN_US)
> >  #define VLAN_HLEN       4
> >
> > +static inline int
> > +open_dma(const char *value, void *dma_bind_info) {
> > +	struct dma_for_vhost *dma_info = dma_bind_info;
> > +	char *input = strndup(value, strlen(value) + 1);
> > +	char *addrs = input;
> > +	char *ptrs[2];
> > +	char *start, *end, *substr;
> > +	int64_t vid, vring_id;
> > +	struct rte_ioat_rawdev_config config;
> > +	struct rte_rawdev_info info = { .dev_private = &config };
> > +	char name[32];
> > +	int dev_id;
> > +	int ret = 0;
> > +	uint16_t i = 0;
> > +
> > +	while (isblank(*addrs))
> > +		addrs++;
> > +	if (*addrs == '\0') {
> > +		ret = -1;
> > +		goto out;
> > +	}
> > +
> > +	/* process DMA devices within bracket. */
> > +	addrs++;
> > +	substr = strtok(addrs, ";]");
> > +	if (!substr) {
> > +		ret = -1;
> > +		goto out;
> > +	}
> > +	char *dma_arg[MAX_VHOST_DEVICE];
> > +	rte_strsplit(substr, strlen(substr), dma_arg, MAX_VHOST_DEVICE, ',');
> > +	do {
> > +		char *arg_temp = dma_arg[i];
> > +		rte_strsplit(arg_temp, strlen(arg_temp), ptrs, 2, '@');
> > +
> > +		start = strstr(ptrs[0], "txd");
> > +		if (start == NULL) {
> > +			ret = -1;
> > +			goto out;
> > +		}
> > +
> > +		start += 3;
> > +		vid = strtol(start, &end, 0);
> > +		if (end == start) {
> > +			ret = -1;
> > +			goto out;
> > +		}
> > +
> > +		vring_id = 0 + VIRTIO_RXQ;
> > +		if (rte_pci_addr_parse(ptrs[1],
> > +				&(dma_info + vid)->dmas[vring_id].addr) < 0)
> {
> > +			ret = -1;
> > +			goto out;
> > +		}
> > +
> > +		rte_pci_device_name(&(dma_info + vid)-
> >dmas[vring_id].addr,
> > +				    name, sizeof(name));
> > +		dev_id = rte_rawdev_get_dev_id(name);
> > +		if (dev_id == (uint16_t)(-ENODEV) ||
> > +		    dev_id == (uint16_t)(-EINVAL)) {
> > +			ret = -1;
> > +			goto out;
> > +		}
> > +
> > +		if (rte_rawdev_info_get(dev_id, &info) < 0 ||
> > +		    strstr(info.driver_name, "ioat") == NULL) {
> > +			ret = -1;
> > +			goto out;
> > +		}
> > +
> > +		(dma_info + vid)->dmas[vring_id].dev_id = dev_id;
> > +		(dma_info + vid)->dmas[vring_id].is_valid = true;
> > +		config.ring_size = IOAT_RING_SIZE;
> > +		if (rte_rawdev_configure(dev_id, &info) < 0) {
> > +			ret = -1;
> > +			goto out;
> > +		}
> > +		rte_rawdev_start(dev_id);
> > +
> > +		dma_info->nr++;
> > +
> > +		arg_temp = strtok(NULL, ";]");
> > +		i++;
> > +	} while (dma_arg[i]);
> > +
> > +out:
> > +	free(input);
> > +	return ret;
> > +}
> > +
> 
> I think this is purely Intel specifics, so using generic "dma" name is not a good
> idea.
> Also, as this is HW specific, it should be moved to a dedicated file which
> would only be compiled if all dependencies are met. (it does not even build
> on X86:
> http://mails.dpdk.org/archives/test-report/2020-September/151519.html)
> 

I agreed. I'll add another layer of abstraction here, using open_dma function to call the specific DMA initiate function(such as open_ioat) which will be in a dedicated file(ioat.c). And the meson build file will be changed to fix the dependency problem.

> >  /*
> >   * Builds up the correct configuration for VMDQ VLAN pool map
> >   * according to the pool & queue limits.
> > @@ -485,6 +600,8 @@ us_vhost_parse_args(int argc, char **argv)
> >  		{"client", no_argument, &client_mode, 1},
> >  		{"dequeue-zero-copy", no_argument,
> &dequeue_zero_copy, 1},
> >  		{"builtin-net-driver", no_argument, &builtin_net_driver, 1},
> > +		{"async_vhost_driver", no_argument, &async_vhost_driver,
> 1},
> 
> Shouldn't it be in patch 2 where it is used?
> Also, I wonder whether it is really necessary, as as soon as you pass dmas
> parameter you know you'll want to use async mode, no?
> 

Sure I'll fix it in the next version. And as for the necessity of async_vhost_driver, I agree with you. So I'll change it to dma_type to indicate the app that I am going to use what kind of dma for vhost acceleration.

> > +		{"dmas", required_argument, NULL, 0},
> >  		{NULL, 0, 0, 0},
> >  	};
> >
> > @@ -620,13 +737,25 @@ us_vhost_parse_args(int argc, char **argv)
> >  						"socket-file",
> MAX_LONG_OPT_SZ)) {
> >  				if (us_vhost_parse_socket_path(optarg) == -
> 1) {
> >  					RTE_LOG(INFO, VHOST_CONFIG,
> > -					"Invalid argument for socket name
> (Max %d characters)\n",
> > -					PATH_MAX);
> > +						"Invalid argument for socket
> name (Max %d characters)\n",
> > +						PATH_MAX);
> >  					us_vhost_usage(prgname);
> >  					return -1;
> >  				}
> >  			}
> >
> > +			if (!strncmp(long_option[option_index].name,
> > +						"dmas",
> MAX_LONG_OPT_SZ)) {
> > +				if (open_dma(optarg, &dma_bind) == -1) {
> > +					if (*optarg == -1) {
> > +						RTE_LOG(INFO,
> VHOST_CONFIG,
> > +							"Wrong DMA args\n");
> > +						us_vhost_usage(prgname);
> 
> You need to update us_vhost_usage() to document the new arguments.

Sure, I'll do it in the next version.

Thanks,
Cheng

> 
> > +						return -1;
> > +					}
> > +				}
> > +			}
> > +
> >  			break;
> >
> >  			/* Invalid option - print options. */
> >


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

* [dpdk-dev] [PATCH v2 0/4] add async data path in vhost sample
  2020-09-10  6:43 [dpdk-dev] [PATCH v1 0/4] add async data path in vhost sample Cheng Jiang
                   ` (3 preceding siblings ...)
  2020-09-10  6:43 ` [dpdk-dev] [PATCH v1 4/4] doc: update release notes for vhost sample Cheng Jiang
@ 2020-09-29  6:42 ` Cheng Jiang
  2020-09-29  6:42   ` [dpdk-dev] [PATCH v2 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
                     ` (4 more replies)
  2020-10-22  8:59 ` [dpdk-dev] [PATCH v10 " Cheng Jiang
  5 siblings, 5 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-09-29  6:42 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

This patch set makes vhost-vswitch be able to use vhost async APIs
for enqueue operations. Demonstrated how the application
leverage IOAT DMA channel with vhost async APIs.

We introduce two parameters to enable DMA acceleration for Tx
operations of queues:
-dma_type This parameter is used to specify DMA type for async
vhost-user net driver.
-dmas This parameter is used to specify the assigned DMA device of a
vhost device and enable async vhost data path.

---
v2:
 * Changed meson build file to fix dependency problem
 * Added parameter description in usage function
 * Optimized parameter settings and parsing function
 * Optimized abstraction, moved some code to ioat.c

Cheng Jiang (4):
  example/vhost: add async vhost args parsing function
  example/vhost: add support for vhost async data path
  doc: update vhost sample doc for vhost async data path
  doc: update release notes for vhost sample

 doc/guides/rel_notes/release_20_11.rst |   6 +
 doc/guides/sample_app_ug/vhost.rst     |  11 ++
 examples/vhost/ioat.c                  | 209 +++++++++++++++++++++++++
 examples/vhost/main.c                  |  98 +++++++++++-
 examples/vhost/main.h                  |  14 ++
 examples/vhost/meson.build             |   4 +-
 6 files changed, 338 insertions(+), 4 deletions(-)
 create mode 100644 examples/vhost/ioat.c

--
2.27.0


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

* [dpdk-dev] [PATCH v2 1/4] example/vhost: add async vhost args parsing function
  2020-09-29  6:42 ` [dpdk-dev] [PATCH v2 0/4] add async data path in " Cheng Jiang
@ 2020-09-29  6:42   ` Cheng Jiang
  2020-09-29  6:42   ` [dpdk-dev] [PATCH v2 2/4] example/vhost: add support for vhost async data path Cheng Jiang
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-09-29  6:42 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

This patch is to add async vhost driver arguments parsing function
for CBDMA channel, DMA initiation function and args description.
The meson build file is changed to fix dependency problem. With
these arguments vhost device can be set to use CBDMA or CPU for
enqueue operation and bind vhost device with specific CBDMA channel
to accelerate data copy.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 examples/vhost/ioat.c      | 116 +++++++++++++++++++++++++++++++++++++
 examples/vhost/main.c      |  37 +++++++++++-
 examples/vhost/main.h      |   2 +
 examples/vhost/meson.build |   4 +-
 4 files changed, 156 insertions(+), 3 deletions(-)
 create mode 100644 examples/vhost/ioat.c

diff --git a/examples/vhost/ioat.c b/examples/vhost/ioat.c
new file mode 100644
index 000000000..ab8130d06
--- /dev/null
+++ b/examples/vhost/ioat.c
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2017 Intel Corporation
+ */
+
+#include <rte_vhost.h>
+#include <rte_rawdev.h>
+#include <rte_ioat_rawdev.h>
+#include <rte_pci.h>
+
+#include "main.h"
+
+#define MAX_VHOST_DEVICE 1024
+#define IOAT_RING_SIZE 4096
+
+struct dma_info {
+	struct rte_pci_addr addr;
+	uint16_t dev_id;
+	bool is_valid;
+};
+
+struct dma_for_vhost {
+	struct dma_info dmas[RTE_MAX_QUEUES_PER_PORT * 2];
+	uint16_t nr;
+};
+
+struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
+
+int
+open_ioat(const char *value)
+{
+	struct dma_for_vhost *dma_info = dma_bind;
+	char *input = strndup(value, strlen(value) + 1);
+	char *addrs = input;
+	char *ptrs[2];
+	char *start, *end, *substr;
+	int64_t vid, vring_id;
+	struct rte_ioat_rawdev_config config;
+	struct rte_rawdev_info info = { .dev_private = &config };
+	char name[32];
+	int dev_id;
+	int ret = 0;
+	uint16_t i = 0;
+	char *dma_arg[MAX_VHOST_DEVICE];
+	uint8_t args_nr;
+
+	while (isblank(*addrs))
+		addrs++;
+	if (*addrs == '\0') {
+		ret = -1;
+		goto out;
+	}
+
+	/* process DMA devices within bracket. */
+	addrs++;
+	substr = strtok(addrs, ";]");
+	if (!substr) {
+		ret = -1;
+		goto out;
+	}
+	args_nr = rte_strsplit(substr, strlen(substr),
+			dma_arg, MAX_VHOST_DEVICE, ',');
+	do {
+		char *arg_temp = dma_arg[i];
+		rte_strsplit(arg_temp, strlen(arg_temp), ptrs, 2, '@');
+
+		start = strstr(ptrs[0], "txd");
+		if (start == NULL) {
+			ret = -1;
+			goto out;
+		}
+
+		start += 3;
+		vid = strtol(start, &end, 0);
+		if (end == start) {
+			ret = -1;
+			goto out;
+		}
+
+		vring_id = 0 + VIRTIO_RXQ;
+		if (rte_pci_addr_parse(ptrs[1],
+				&(dma_info + vid)->dmas[vring_id].addr) < 0) {
+			ret = -1;
+			goto out;
+		}
+
+		rte_pci_device_name(&(dma_info + vid)->dmas[vring_id].addr,
+				name, sizeof(name));
+		dev_id = rte_rawdev_get_dev_id(name);
+		if (dev_id == (uint16_t)(-ENODEV) ||
+		dev_id == (uint16_t)(-EINVAL)) {
+			ret = -1;
+			goto out;
+		}
+
+		if (rte_rawdev_info_get(dev_id, &info, sizeof(config)) < 0 ||
+		strstr(info.driver_name, "ioat") == NULL) {
+			ret = -1;
+			goto out;
+		}
+
+		(dma_info + vid)->dmas[vring_id].dev_id = dev_id;
+		(dma_info + vid)->dmas[vring_id].is_valid = true;
+		config.ring_size = IOAT_RING_SIZE;
+		if (rte_rawdev_configure(dev_id, &info, sizeof(config)) < 0) {
+			ret = -1;
+			goto out;
+		}
+		rte_rawdev_start(dev_id);
+
+		dma_info->nr++;
+		i++;
+	} while (i < args_nr);
+out:
+	free(input);
+	return ret;
+}
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index e1578e795..9b1165a78 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -96,6 +96,10 @@ static int dequeue_zero_copy;
 
 static int builtin_net_driver;
 
+static int async_vhost_driver;
+
+static char dma_type[MAX_LONG_OPT_SZ];
+
 /* Specify timeout (in useconds) between retries on RX. */
 static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
 /* Specify the number of retries on RX. */
@@ -182,6 +186,15 @@ struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];
 				 / US_PER_S * BURST_TX_DRAIN_US)
 #define VLAN_HLEN       4
 
+static inline int
+open_dma(const char *value)
+{
+	if (strncmp(dma_type, "IOAT", 4) == 0)
+		return open_ioat(value);
+	else
+		return -1;
+}
+
 /*
  * Builds up the correct configuration for VMDQ VLAN pool map
  * according to the pool & queue limits.
@@ -458,7 +471,9 @@ us_vhost_usage(const char *prgname)
 	"		--tx-csum [0|1] disable/enable TX checksum offload.\n"
 	"		--tso [0|1] disable/enable TCP segment offload.\n"
 	"		--client register a vhost-user socket as client mode.\n"
-	"		--dequeue-zero-copy enables dequeue zero copy\n",
+	"		--dequeue-zero-copy enables dequeue zero copy\n"
+	"		--dma-type register dma type for your vhost async driver\n"
+	"		--dmas register dma channel for specific vhost device\n",
 	       prgname);
 }
 
@@ -485,6 +500,8 @@ us_vhost_parse_args(int argc, char **argv)
 		{"client", no_argument, &client_mode, 1},
 		{"dequeue-zero-copy", no_argument, &dequeue_zero_copy, 1},
 		{"builtin-net-driver", no_argument, &builtin_net_driver, 1},
+		{"dma-type", required_argument, NULL, 0},
+		{"dmas", required_argument, NULL, 0},
 		{NULL, 0, 0, 0},
 	};
 
@@ -627,6 +644,24 @@ us_vhost_parse_args(int argc, char **argv)
 				}
 			}
 
+			if (!strncmp(long_option[option_index].name,
+						"dma-type", MAX_LONG_OPT_SZ)) {
+				strcpy(dma_type, optarg);
+			}
+
+			if (!strncmp(long_option[option_index].name,
+						"dmas", MAX_LONG_OPT_SZ)) {
+				if (open_dma(optarg) == -1) {
+					if (*optarg == -1) {
+						RTE_LOG(INFO, VHOST_CONFIG,
+							"Wrong DMA args\n");
+						us_vhost_usage(prgname);
+					}
+					return -1;
+				}
+				async_vhost_driver = 1;
+			}
+
 			break;
 
 			/* Invalid option - print options. */
diff --git a/examples/vhost/main.h b/examples/vhost/main.h
index 7cba0edbf..eac18824b 100644
--- a/examples/vhost/main.h
+++ b/examples/vhost/main.h
@@ -90,3 +90,5 @@ uint16_t vs_dequeue_pkts(struct vhost_dev *dev, uint16_t queue_id,
 			 struct rte_mempool *mbuf_pool,
 			 struct rte_mbuf **pkts, uint16_t count);
 #endif /* _MAIN_H_ */
+
+int open_ioat(const char *value);
diff --git a/examples/vhost/meson.build b/examples/vhost/meson.build
index 872d51153..cb11edd78 100644
--- a/examples/vhost/meson.build
+++ b/examples/vhost/meson.build
@@ -9,8 +9,8 @@
 if not is_linux
 	build = false
 endif
-deps += 'vhost'
+deps += ['vhost', 'rawdev_ioat']
 allow_experimental_apis = true
 sources = files(
-	'main.c', 'virtio_net.c'
+	'main.c', 'virtio_net.c', 'ioat.c'
 )
-- 
2.27.0


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

* [dpdk-dev] [PATCH v2 2/4] example/vhost: add support for vhost async data path
  2020-09-29  6:42 ` [dpdk-dev] [PATCH v2 0/4] add async data path in " Cheng Jiang
  2020-09-29  6:42   ` [dpdk-dev] [PATCH v2 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
@ 2020-09-29  6:42   ` Cheng Jiang
  2020-09-29  6:42   ` [dpdk-dev] [PATCH v2 3/4] doc: update vhost sample doc " Cheng Jiang
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-09-29  6:42 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

This patch is to implement vhost DMA operation callbacks for CBDMA
PMD and add vhost async data-path in vhost sample. With providing
callback implementation for CBDMA, vswitch can leverage IOAT to
accelerate vhost async data-path.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 examples/vhost/ioat.c | 93 +++++++++++++++++++++++++++++++++++++++++++
 examples/vhost/main.c | 61 +++++++++++++++++++++++++++-
 examples/vhost/main.h | 12 ++++++
 3 files changed, 165 insertions(+), 1 deletion(-)

diff --git a/examples/vhost/ioat.c b/examples/vhost/ioat.c
index ab8130d06..063666aa2 100644
--- a/examples/vhost/ioat.c
+++ b/examples/vhost/ioat.c
@@ -6,11 +6,13 @@
 #include <rte_rawdev.h>
 #include <rte_ioat_rawdev.h>
 #include <rte_pci.h>
+#include <sys/uio.h>
 
 #include "main.h"
 
 #define MAX_VHOST_DEVICE 1024
 #define IOAT_RING_SIZE 4096
+#define MAX_ENQUEUED_SIZE 256
 
 struct dma_info {
 	struct rte_pci_addr addr;
@@ -25,6 +27,15 @@ struct dma_for_vhost {
 
 struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
 
+struct packet_tracker {
+	unsigned short size_track[MAX_ENQUEUED_SIZE];
+	unsigned short next_read;
+	unsigned short next_write;
+	unsigned short last_remain;
+};
+
+struct packet_tracker cb_tracker[MAX_VHOST_DEVICE];
+
 int
 open_ioat(const char *value)
 {
@@ -114,3 +125,85 @@ open_ioat(const char *value)
 	free(input);
 	return ret;
 }
+
+uint32_t
+ioat_transfer_data_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_desc *descs,
+		struct rte_vhost_async_status *opaque_data, uint16_t count)
+{
+	int ret;
+	uint32_t i_desc;
+	int dev_id = dma_bind[vid].dmas[queue_id * 2 + VIRTIO_RXQ].dev_id;
+	struct rte_vhost_iov_iter *src = NULL;
+	struct rte_vhost_iov_iter *dst = NULL;
+	unsigned long i_seg;
+	unsigned short mask = MAX_ENQUEUED_SIZE - 1;
+	unsigned short write = cb_tracker[dev_id].next_write;
+
+	if (likely(!opaque_data)) {
+		for (i_desc = 0; i_desc < count; i_desc++) {
+			src = descs[i_desc].src;
+			dst = descs[i_desc].dst;
+			i_seg = 0;
+			while (i_seg < src->nr_segs) {
+				ret = rte_ioat_enqueue_copy(dev_id,
+					(uintptr_t)(src->iov[i_seg].iov_base)
+						+ src->offset,
+					(uintptr_t)(dst->iov[i_seg].iov_base)
+						+ dst->offset,
+					src->iov[i_seg].iov_len,
+					0,
+					0,
+					0);
+				if (ret != 1)
+					break;
+				i_seg++;
+			}
+			write &= mask;
+			cb_tracker[dev_id].size_track[write] = i_seg;
+			write++;
+		}
+	} else {
+		/* Opaque data is not supported */
+		return -1;
+	}
+	/* ring the doorbell */
+	rte_ioat_do_copies(dev_id);
+	cb_tracker[dev_id].next_write = write;
+	return i_desc;
+}
+
+uint32_t
+ioat_check_completed_copies_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_status *opaque_data,
+		uint16_t max_packets)
+{
+	if (!opaque_data) {
+		uintptr_t dump[255];
+		unsigned short n_seg;
+		unsigned short read;
+		unsigned short nb_packet = 0;
+		unsigned short mask = MAX_ENQUEUED_SIZE - 1;
+		int dev_id = dma_bind[vid].dmas[queue_id * 2
+				+ VIRTIO_RXQ].dev_id;
+		n_seg = rte_ioat_completed_copies(dev_id, 255, dump, dump);
+		n_seg = n_seg + cb_tracker[dev_id].last_remain;
+		read = cb_tracker[dev_id].next_read;
+		for (unsigned short i = 0; i < max_packets; i++) {
+			read &= mask;
+			if (n_seg >= cb_tracker[dev_id].size_track[read]) {
+				n_seg -= cb_tracker[dev_id].size_track[read];
+				read++;
+				nb_packet++;
+			} else {
+				break;
+			}
+		}
+		cb_tracker[dev_id].next_read = read;
+		cb_tracker[dev_id].last_remain = n_seg;
+		return nb_packet;
+	} else {
+		/* Opaque data is not supported */
+		return -1;
+	}
+}
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 9b1165a78..893edbb78 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -817,9 +817,26 @@ virtio_xmit(struct vhost_dev *dst_vdev, struct vhost_dev *src_vdev,
 	    struct rte_mbuf *m)
 {
 	uint16_t ret;
+	struct rte_mbuf *m_cpl[1];
 
 	if (builtin_net_driver) {
 		ret = vs_enqueue_pkts(dst_vdev, VIRTIO_RXQ, &m, 1);
+	} else if (async_vhost_driver) {
+		ret = rte_vhost_submit_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ,
+						&m, 1);
+
+		if (likely(ret)) {
+			dst_vdev->nr_async_pkts++;
+			rte_mbuf_refcnt_update(m, 1);
+		}
+
+		while (likely(dst_vdev->nr_async_pkts)) {
+			if (rte_vhost_poll_enqueue_completed(dst_vdev->vid,
+					VIRTIO_RXQ, m_cpl, 1)) {
+				dst_vdev->nr_async_pkts--;
+				rte_pktmbuf_free(*m_cpl);
+			}
+		}
 	} else {
 		ret = rte_vhost_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ, &m, 1);
 	}
@@ -1068,6 +1085,19 @@ drain_mbuf_table(struct mbuf_table *tx_q)
 	}
 }
 
+static __rte_always_inline void
+complete_async_pkts(struct vhost_dev *vdev, uint16_t qid)
+{
+	struct rte_mbuf *p_cpl[MAX_PKT_BURST];
+	uint16_t complete_count;
+
+	complete_count = rte_vhost_poll_enqueue_completed(vdev->vid,
+						qid, p_cpl, MAX_PKT_BURST);
+	vdev->nr_async_pkts -= complete_count;
+	if (complete_count)
+		free_pkts(p_cpl, complete_count);
+}
+
 static __rte_always_inline void
 drain_eth_rx(struct vhost_dev *vdev)
 {
@@ -1076,6 +1106,10 @@ drain_eth_rx(struct vhost_dev *vdev)
 
 	rx_count = rte_eth_rx_burst(ports[0], vdev->vmdq_rx_q,
 				    pkts, MAX_PKT_BURST);
+
+	while (likely(vdev->nr_async_pkts))
+		complete_async_pkts(vdev, VIRTIO_RXQ);
+
 	if (!rx_count)
 		return;
 
@@ -1100,16 +1134,22 @@ drain_eth_rx(struct vhost_dev *vdev)
 	if (builtin_net_driver) {
 		enqueue_count = vs_enqueue_pkts(vdev, VIRTIO_RXQ,
 						pkts, rx_count);
+	} else if (async_vhost_driver) {
+		enqueue_count = rte_vhost_submit_enqueue_burst(vdev->vid,
+					VIRTIO_RXQ, pkts, rx_count);
+		vdev->nr_async_pkts += enqueue_count;
 	} else {
 		enqueue_count = rte_vhost_enqueue_burst(vdev->vid, VIRTIO_RXQ,
 						pkts, rx_count);
 	}
+
 	if (enable_stats) {
 		rte_atomic64_add(&vdev->stats.rx_total_atomic, rx_count);
 		rte_atomic64_add(&vdev->stats.rx_atomic, enqueue_count);
 	}
 
-	free_pkts(pkts, rx_count);
+	if (!async_vhost_driver)
+		free_pkts(pkts, rx_count);
 }
 
 static __rte_always_inline void
@@ -1256,6 +1296,9 @@ destroy_device(int vid)
 		"(%d) device has been removed from data core\n",
 		vdev->vid);
 
+	if (async_vhost_driver)
+		rte_vhost_async_channel_unregister(vid, VIRTIO_RXQ);
+
 	rte_free(vdev);
 }
 
@@ -1270,6 +1313,12 @@ new_device(int vid)
 	uint32_t device_num_min = num_devices;
 	struct vhost_dev *vdev;
 
+	struct rte_vhost_async_channel_ops channel_ops = {
+		.transfer_data = ioat_transfer_data_cb,
+		.check_completed_copies = ioat_check_completed_copies_cb
+	};
+	struct rte_vhost_async_features f;
+
 	vdev = rte_zmalloc("vhost device", sizeof(*vdev), RTE_CACHE_LINE_SIZE);
 	if (vdev == NULL) {
 		RTE_LOG(INFO, VHOST_DATA,
@@ -1310,6 +1359,13 @@ new_device(int vid)
 		"(%d) device has been added to data core %d\n",
 		vid, vdev->coreid);
 
+	if (async_vhost_driver) {
+		f.async_inorder = 1;
+		f.async_threshold = 256;
+		return rte_vhost_async_channel_register(vid, VIRTIO_RXQ,
+			f.intval, &channel_ops);
+	}
+
 	return 0;
 }
 
@@ -1551,6 +1607,9 @@ main(int argc, char *argv[])
 	/* Register vhost user driver to handle vhost messages. */
 	for (i = 0; i < nb_sockets; i++) {
 		char *file = socket_files + i * PATH_MAX;
+		if (async_vhost_driver)
+			flags = flags | RTE_VHOST_USER_ASYNC_COPY;
+
 		ret = rte_vhost_driver_register(file, flags);
 		if (ret != 0) {
 			unregister_drivers(i);
diff --git a/examples/vhost/main.h b/examples/vhost/main.h
index eac18824b..e4cf13190 100644
--- a/examples/vhost/main.h
+++ b/examples/vhost/main.h
@@ -8,6 +8,7 @@
 #include <sys/queue.h>
 
 #include <rte_ether.h>
+#include <rte_vhost_async.h>
 
 /* Macros for printing using RTE_LOG */
 #define RTE_LOGTYPE_VHOST_CONFIG RTE_LOGTYPE_USER1
@@ -51,6 +52,7 @@ struct vhost_dev {
 	uint64_t features;
 	size_t hdr_len;
 	uint16_t nr_vrings;
+	uint16_t nr_async_pkts;
 	struct rte_vhost_memory *mem;
 	struct device_statistics stats;
 	TAILQ_ENTRY(vhost_dev) global_vdev_entry;
@@ -92,3 +94,13 @@ uint16_t vs_dequeue_pkts(struct vhost_dev *dev, uint16_t queue_id,
 #endif /* _MAIN_H_ */
 
 int open_ioat(const char *value);
+
+uint32_t
+ioat_transfer_data_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_desc *descs,
+		struct rte_vhost_async_status *opaque_data, uint16_t count);
+
+uint32_t
+ioat_check_completed_copies_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_status *opaque_data,
+		uint16_t max_packets);
-- 
2.27.0


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

* [dpdk-dev] [PATCH v2 3/4] doc: update vhost sample doc for vhost async data path
  2020-09-29  6:42 ` [dpdk-dev] [PATCH v2 0/4] add async data path in " Cheng Jiang
  2020-09-29  6:42   ` [dpdk-dev] [PATCH v2 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
  2020-09-29  6:42   ` [dpdk-dev] [PATCH v2 2/4] example/vhost: add support for vhost async data path Cheng Jiang
@ 2020-09-29  6:42   ` Cheng Jiang
  2020-09-29  6:42   ` [dpdk-dev] [PATCH v2 4/4] doc: update release notes for vhost sample Cheng Jiang
  2020-09-30  3:08   ` [dpdk-dev] [PATCH v3 0/4] add async data path in " Cheng Jiang
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-09-29  6:42 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

Add vhost async driver arguments information for vhost async data
path in vhost sample application.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 doc/guides/sample_app_ug/vhost.rst | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/doc/guides/sample_app_ug/vhost.rst b/doc/guides/sample_app_ug/vhost.rst
index b7ed4f8bd..0f4f70945 100644
--- a/doc/guides/sample_app_ug/vhost.rst
+++ b/doc/guides/sample_app_ug/vhost.rst
@@ -162,6 +162,17 @@ enabled and cannot be disabled.
 A very simple vhost-user net driver which demonstrates how to use the generic
 vhost APIs will be used when this option is given. It is disabled by default.
 
+**--dma-type**
+This parameter is used to specify DMA type for async vhost-user net driver which
+demonstrates how to use the async vhost APIs. It's used in combination with dmas.
+
+**--dmas**
+This parameter is used to specify the assigned DMA device of a vhost device.
+Async vhost-user net driver will be used if --dmas is set. For example
+--dmas [txd0@00:04.0,txd1@00:04.1] means use DMA channel 00:04.0 for vhost
+device 0 enqueue operation and use DMA channel 00:04.1 for vhost device 1
+enqueue operation.
+
 Common Issues
 -------------
 
-- 
2.27.0


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

* [dpdk-dev] [PATCH v2 4/4] doc: update release notes for vhost sample
  2020-09-29  6:42 ` [dpdk-dev] [PATCH v2 0/4] add async data path in " Cheng Jiang
                     ` (2 preceding siblings ...)
  2020-09-29  6:42   ` [dpdk-dev] [PATCH v2 3/4] doc: update vhost sample doc " Cheng Jiang
@ 2020-09-29  6:42   ` Cheng Jiang
  2020-09-30  3:08   ` [dpdk-dev] [PATCH v3 0/4] add async data path in " Cheng Jiang
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-09-29  6:42 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

Add release notes for vhost async data path support in vhost sample.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 doc/guides/rel_notes/release_20_11.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst
index 92431cd52..6439146b2 100644
--- a/doc/guides/rel_notes/release_20_11.rst
+++ b/doc/guides/rel_notes/release_20_11.rst
@@ -55,6 +55,12 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Updated vhost sample application.**
+
+  Added vhost asynchronous APIs support, which demonstrated how the application
+  leverage IOAT DMA channel with vhost asynchronous APIs.
+  See the :doc:`../sample_app_ug/vhost` for more details.
+
 
 Removed Items
 -------------
-- 
2.27.0


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

* [dpdk-dev] [PATCH v3 0/4] add async data path in vhost sample
  2020-09-29  6:42 ` [dpdk-dev] [PATCH v2 0/4] add async data path in " Cheng Jiang
                     ` (3 preceding siblings ...)
  2020-09-29  6:42   ` [dpdk-dev] [PATCH v2 4/4] doc: update release notes for vhost sample Cheng Jiang
@ 2020-09-30  3:08   ` Cheng Jiang
  2020-09-30  3:08     ` [dpdk-dev] [PATCH v3 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
                       ` (4 more replies)
  4 siblings, 5 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-09-30  3:08 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

This patch set makes vhost-vswitch be able to use vhost async APIs
for enqueue operations. Demonstrated how the application
leverage IOAT DMA channel with vhost async APIs.

We introduce two parameters to enable DMA acceleration for Tx
operations of queues:
-dma_type This parameter is used to specify DMA type for async
vhost-user net driver.
-dmas This parameter is used to specify the assigned DMA device of a
vhost device and enable async vhost data path.

---
v3:
 * Fixed a coding style problem

v2:
 * Changed meson build file to fix dependency problem
 * Added parameter description in usage function
 * Optimized parameter settings and parsing function
 * Optimized abstraction, moved some code to ioat.c

Cheng Jiang (4):
  example/vhost: add async vhost args parsing function
  example/vhost: add support for vhost async data path
  doc: update vhost sample doc for vhost async data path
  doc: update release notes for vhost sample

 doc/guides/rel_notes/release_20_11.rst |   6 +
 doc/guides/sample_app_ug/vhost.rst     |  11 ++
 examples/vhost/ioat.c                  | 209 +++++++++++++++++++++++++
 examples/vhost/main.c                  |  98 +++++++++++-
 examples/vhost/main.h                  |  14 ++
 examples/vhost/meson.build             |   4 +-
 6 files changed, 338 insertions(+), 4 deletions(-)
 create mode 100644 examples/vhost/ioat.c

--
2.27.0


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

* [dpdk-dev] [PATCH v3 1/4] example/vhost: add async vhost args parsing function
  2020-09-30  3:08   ` [dpdk-dev] [PATCH v3 0/4] add async data path in " Cheng Jiang
@ 2020-09-30  3:08     ` Cheng Jiang
  2020-09-30  3:08     ` [dpdk-dev] [PATCH v3 2/4] example/vhost: add support for vhost async data path Cheng Jiang
                       ` (3 subsequent siblings)
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-09-30  3:08 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

This patch is to add async vhost driver arguments parsing function
for CBDMA channel, DMA initiation function and args description.
The meson build file is changed to fix dependency problem. With
these arguments vhost device can be set to use CBDMA or CPU for
enqueue operation and bind vhost device with specific CBDMA channel
to accelerate data copy.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 examples/vhost/ioat.c      | 116 +++++++++++++++++++++++++++++++++++++
 examples/vhost/main.c      |  37 +++++++++++-
 examples/vhost/main.h      |   2 +
 examples/vhost/meson.build |   4 +-
 4 files changed, 156 insertions(+), 3 deletions(-)
 create mode 100644 examples/vhost/ioat.c

diff --git a/examples/vhost/ioat.c b/examples/vhost/ioat.c
new file mode 100644
index 000000000..ab8130d06
--- /dev/null
+++ b/examples/vhost/ioat.c
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2017 Intel Corporation
+ */
+
+#include <rte_vhost.h>
+#include <rte_rawdev.h>
+#include <rte_ioat_rawdev.h>
+#include <rte_pci.h>
+
+#include "main.h"
+
+#define MAX_VHOST_DEVICE 1024
+#define IOAT_RING_SIZE 4096
+
+struct dma_info {
+	struct rte_pci_addr addr;
+	uint16_t dev_id;
+	bool is_valid;
+};
+
+struct dma_for_vhost {
+	struct dma_info dmas[RTE_MAX_QUEUES_PER_PORT * 2];
+	uint16_t nr;
+};
+
+struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
+
+int
+open_ioat(const char *value)
+{
+	struct dma_for_vhost *dma_info = dma_bind;
+	char *input = strndup(value, strlen(value) + 1);
+	char *addrs = input;
+	char *ptrs[2];
+	char *start, *end, *substr;
+	int64_t vid, vring_id;
+	struct rte_ioat_rawdev_config config;
+	struct rte_rawdev_info info = { .dev_private = &config };
+	char name[32];
+	int dev_id;
+	int ret = 0;
+	uint16_t i = 0;
+	char *dma_arg[MAX_VHOST_DEVICE];
+	uint8_t args_nr;
+
+	while (isblank(*addrs))
+		addrs++;
+	if (*addrs == '\0') {
+		ret = -1;
+		goto out;
+	}
+
+	/* process DMA devices within bracket. */
+	addrs++;
+	substr = strtok(addrs, ";]");
+	if (!substr) {
+		ret = -1;
+		goto out;
+	}
+	args_nr = rte_strsplit(substr, strlen(substr),
+			dma_arg, MAX_VHOST_DEVICE, ',');
+	do {
+		char *arg_temp = dma_arg[i];
+		rte_strsplit(arg_temp, strlen(arg_temp), ptrs, 2, '@');
+
+		start = strstr(ptrs[0], "txd");
+		if (start == NULL) {
+			ret = -1;
+			goto out;
+		}
+
+		start += 3;
+		vid = strtol(start, &end, 0);
+		if (end == start) {
+			ret = -1;
+			goto out;
+		}
+
+		vring_id = 0 + VIRTIO_RXQ;
+		if (rte_pci_addr_parse(ptrs[1],
+				&(dma_info + vid)->dmas[vring_id].addr) < 0) {
+			ret = -1;
+			goto out;
+		}
+
+		rte_pci_device_name(&(dma_info + vid)->dmas[vring_id].addr,
+				name, sizeof(name));
+		dev_id = rte_rawdev_get_dev_id(name);
+		if (dev_id == (uint16_t)(-ENODEV) ||
+		dev_id == (uint16_t)(-EINVAL)) {
+			ret = -1;
+			goto out;
+		}
+
+		if (rte_rawdev_info_get(dev_id, &info, sizeof(config)) < 0 ||
+		strstr(info.driver_name, "ioat") == NULL) {
+			ret = -1;
+			goto out;
+		}
+
+		(dma_info + vid)->dmas[vring_id].dev_id = dev_id;
+		(dma_info + vid)->dmas[vring_id].is_valid = true;
+		config.ring_size = IOAT_RING_SIZE;
+		if (rte_rawdev_configure(dev_id, &info, sizeof(config)) < 0) {
+			ret = -1;
+			goto out;
+		}
+		rte_rawdev_start(dev_id);
+
+		dma_info->nr++;
+		i++;
+	} while (i < args_nr);
+out:
+	free(input);
+	return ret;
+}
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index e1578e795..9b1165a78 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -96,6 +96,10 @@ static int dequeue_zero_copy;
 
 static int builtin_net_driver;
 
+static int async_vhost_driver;
+
+static char dma_type[MAX_LONG_OPT_SZ];
+
 /* Specify timeout (in useconds) between retries on RX. */
 static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
 /* Specify the number of retries on RX. */
@@ -182,6 +186,15 @@ struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];
 				 / US_PER_S * BURST_TX_DRAIN_US)
 #define VLAN_HLEN       4
 
+static inline int
+open_dma(const char *value)
+{
+	if (strncmp(dma_type, "IOAT", 4) == 0)
+		return open_ioat(value);
+	else
+		return -1;
+}
+
 /*
  * Builds up the correct configuration for VMDQ VLAN pool map
  * according to the pool & queue limits.
@@ -458,7 +471,9 @@ us_vhost_usage(const char *prgname)
 	"		--tx-csum [0|1] disable/enable TX checksum offload.\n"
 	"		--tso [0|1] disable/enable TCP segment offload.\n"
 	"		--client register a vhost-user socket as client mode.\n"
-	"		--dequeue-zero-copy enables dequeue zero copy\n",
+	"		--dequeue-zero-copy enables dequeue zero copy\n"
+	"		--dma-type register dma type for your vhost async driver\n"
+	"		--dmas register dma channel for specific vhost device\n",
 	       prgname);
 }
 
@@ -485,6 +500,8 @@ us_vhost_parse_args(int argc, char **argv)
 		{"client", no_argument, &client_mode, 1},
 		{"dequeue-zero-copy", no_argument, &dequeue_zero_copy, 1},
 		{"builtin-net-driver", no_argument, &builtin_net_driver, 1},
+		{"dma-type", required_argument, NULL, 0},
+		{"dmas", required_argument, NULL, 0},
 		{NULL, 0, 0, 0},
 	};
 
@@ -627,6 +644,24 @@ us_vhost_parse_args(int argc, char **argv)
 				}
 			}
 
+			if (!strncmp(long_option[option_index].name,
+						"dma-type", MAX_LONG_OPT_SZ)) {
+				strcpy(dma_type, optarg);
+			}
+
+			if (!strncmp(long_option[option_index].name,
+						"dmas", MAX_LONG_OPT_SZ)) {
+				if (open_dma(optarg) == -1) {
+					if (*optarg == -1) {
+						RTE_LOG(INFO, VHOST_CONFIG,
+							"Wrong DMA args\n");
+						us_vhost_usage(prgname);
+					}
+					return -1;
+				}
+				async_vhost_driver = 1;
+			}
+
 			break;
 
 			/* Invalid option - print options. */
diff --git a/examples/vhost/main.h b/examples/vhost/main.h
index 7cba0edbf..eac18824b 100644
--- a/examples/vhost/main.h
+++ b/examples/vhost/main.h
@@ -90,3 +90,5 @@ uint16_t vs_dequeue_pkts(struct vhost_dev *dev, uint16_t queue_id,
 			 struct rte_mempool *mbuf_pool,
 			 struct rte_mbuf **pkts, uint16_t count);
 #endif /* _MAIN_H_ */
+
+int open_ioat(const char *value);
diff --git a/examples/vhost/meson.build b/examples/vhost/meson.build
index 872d51153..cb11edd78 100644
--- a/examples/vhost/meson.build
+++ b/examples/vhost/meson.build
@@ -9,8 +9,8 @@
 if not is_linux
 	build = false
 endif
-deps += 'vhost'
+deps += ['vhost', 'rawdev_ioat']
 allow_experimental_apis = true
 sources = files(
-	'main.c', 'virtio_net.c'
+	'main.c', 'virtio_net.c', 'ioat.c'
 )
-- 
2.27.0


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

* [dpdk-dev] [PATCH v3 2/4] example/vhost: add support for vhost async data path
  2020-09-30  3:08   ` [dpdk-dev] [PATCH v3 0/4] add async data path in " Cheng Jiang
  2020-09-30  3:08     ` [dpdk-dev] [PATCH v3 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
@ 2020-09-30  3:08     ` Cheng Jiang
  2020-09-30  3:08     ` [dpdk-dev] [PATCH v3 3/4] doc: update vhost sample doc " Cheng Jiang
                       ` (2 subsequent siblings)
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-09-30  3:08 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

This patch is to implement vhost DMA operation callbacks for CBDMA
PMD and add vhost async data-path in vhost sample. With providing
callback implementation for CBDMA, vswitch can leverage IOAT to
accelerate vhost async data-path.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 examples/vhost/ioat.c | 93 +++++++++++++++++++++++++++++++++++++++++++
 examples/vhost/main.c | 61 +++++++++++++++++++++++++++-
 examples/vhost/main.h | 12 ++++++
 3 files changed, 165 insertions(+), 1 deletion(-)

diff --git a/examples/vhost/ioat.c b/examples/vhost/ioat.c
index ab8130d06..6acd11c49 100644
--- a/examples/vhost/ioat.c
+++ b/examples/vhost/ioat.c
@@ -6,11 +6,13 @@
 #include <rte_rawdev.h>
 #include <rte_ioat_rawdev.h>
 #include <rte_pci.h>
+#include <sys/uio.h>
 
 #include "main.h"
 
 #define MAX_VHOST_DEVICE 1024
 #define IOAT_RING_SIZE 4096
+#define MAX_ENQUEUED_SIZE 256
 
 struct dma_info {
 	struct rte_pci_addr addr;
@@ -25,6 +27,15 @@ struct dma_for_vhost {
 
 struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
 
+struct packet_tracker {
+	unsigned short size_track[MAX_ENQUEUED_SIZE];
+	unsigned short next_read;
+	unsigned short next_write;
+	unsigned short last_remain;
+};
+
+struct packet_tracker cb_tracker[MAX_VHOST_DEVICE];
+
 int
 open_ioat(const char *value)
 {
@@ -114,3 +125,85 @@ open_ioat(const char *value)
 	free(input);
 	return ret;
 }
+
+uint32_t
+ioat_transfer_data_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_desc *descs,
+		struct rte_vhost_async_status *opaque_data, uint16_t count)
+{
+	int ret;
+	uint32_t i_desc;
+	int dev_id = dma_bind[vid].dmas[queue_id * 2 + VIRTIO_RXQ].dev_id;
+	struct rte_vhost_iov_iter *src = NULL;
+	struct rte_vhost_iov_iter *dst = NULL;
+	unsigned long i_seg;
+	unsigned short mask = MAX_ENQUEUED_SIZE - 1;
+	unsigned short write = cb_tracker[dev_id].next_write;
+
+	if (likely(!opaque_data)) {
+		for (i_desc = 0; i_desc < count; i_desc++) {
+			src = descs[i_desc].src;
+			dst = descs[i_desc].dst;
+			i_seg = 0;
+			while (i_seg < src->nr_segs) {
+				ret = rte_ioat_enqueue_copy(dev_id,
+					(uintptr_t)(src->iov[i_seg].iov_base)
+						+ src->offset,
+					(uintptr_t)(dst->iov[i_seg].iov_base)
+						+ dst->offset,
+					src->iov[i_seg].iov_len,
+					0,
+					0,
+					0);
+				if (ret != 1)
+					break;
+				i_seg++;
+			}
+			write &= mask;
+			cb_tracker[dev_id].size_track[write] = i_seg;
+			write++;
+		}
+	} else {
+		/* Opaque data is not supported */
+		return -1;
+	}
+	/* ring the doorbell */
+	rte_ioat_do_copies(dev_id);
+	cb_tracker[dev_id].next_write = write;
+	return i_desc;
+}
+
+uint32_t
+ioat_check_completed_copies_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_status *opaque_data,
+		uint16_t max_packets)
+{
+	if (!opaque_data) {
+		uintptr_t dump[255];
+		unsigned short n_seg;
+		unsigned short read;
+		unsigned short nb_packet = 0;
+		unsigned short mask = MAX_ENQUEUED_SIZE - 1;
+		unsigned short i;
+		int dev_id = dma_bind[vid].dmas[queue_id * 2
+				+ VIRTIO_RXQ].dev_id;
+		n_seg = rte_ioat_completed_copies(dev_id, 255, dump, dump);
+		n_seg = n_seg + cb_tracker[dev_id].last_remain;
+		read = cb_tracker[dev_id].next_read;
+		for (i = 0; i < max_packets; i++) {
+			read &= mask;
+			if (n_seg >= cb_tracker[dev_id].size_track[read]) {
+				n_seg -= cb_tracker[dev_id].size_track[read];
+				read++;
+				nb_packet++;
+			} else {
+				break;
+			}
+		}
+		cb_tracker[dev_id].next_read = read;
+		cb_tracker[dev_id].last_remain = n_seg;
+		return nb_packet;
+	}
+	/* Opaque data is not supported */
+	return -1;
+}
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 9b1165a78..893edbb78 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -817,9 +817,26 @@ virtio_xmit(struct vhost_dev *dst_vdev, struct vhost_dev *src_vdev,
 	    struct rte_mbuf *m)
 {
 	uint16_t ret;
+	struct rte_mbuf *m_cpl[1];
 
 	if (builtin_net_driver) {
 		ret = vs_enqueue_pkts(dst_vdev, VIRTIO_RXQ, &m, 1);
+	} else if (async_vhost_driver) {
+		ret = rte_vhost_submit_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ,
+						&m, 1);
+
+		if (likely(ret)) {
+			dst_vdev->nr_async_pkts++;
+			rte_mbuf_refcnt_update(m, 1);
+		}
+
+		while (likely(dst_vdev->nr_async_pkts)) {
+			if (rte_vhost_poll_enqueue_completed(dst_vdev->vid,
+					VIRTIO_RXQ, m_cpl, 1)) {
+				dst_vdev->nr_async_pkts--;
+				rte_pktmbuf_free(*m_cpl);
+			}
+		}
 	} else {
 		ret = rte_vhost_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ, &m, 1);
 	}
@@ -1068,6 +1085,19 @@ drain_mbuf_table(struct mbuf_table *tx_q)
 	}
 }
 
+static __rte_always_inline void
+complete_async_pkts(struct vhost_dev *vdev, uint16_t qid)
+{
+	struct rte_mbuf *p_cpl[MAX_PKT_BURST];
+	uint16_t complete_count;
+
+	complete_count = rte_vhost_poll_enqueue_completed(vdev->vid,
+						qid, p_cpl, MAX_PKT_BURST);
+	vdev->nr_async_pkts -= complete_count;
+	if (complete_count)
+		free_pkts(p_cpl, complete_count);
+}
+
 static __rte_always_inline void
 drain_eth_rx(struct vhost_dev *vdev)
 {
@@ -1076,6 +1106,10 @@ drain_eth_rx(struct vhost_dev *vdev)
 
 	rx_count = rte_eth_rx_burst(ports[0], vdev->vmdq_rx_q,
 				    pkts, MAX_PKT_BURST);
+
+	while (likely(vdev->nr_async_pkts))
+		complete_async_pkts(vdev, VIRTIO_RXQ);
+
 	if (!rx_count)
 		return;
 
@@ -1100,16 +1134,22 @@ drain_eth_rx(struct vhost_dev *vdev)
 	if (builtin_net_driver) {
 		enqueue_count = vs_enqueue_pkts(vdev, VIRTIO_RXQ,
 						pkts, rx_count);
+	} else if (async_vhost_driver) {
+		enqueue_count = rte_vhost_submit_enqueue_burst(vdev->vid,
+					VIRTIO_RXQ, pkts, rx_count);
+		vdev->nr_async_pkts += enqueue_count;
 	} else {
 		enqueue_count = rte_vhost_enqueue_burst(vdev->vid, VIRTIO_RXQ,
 						pkts, rx_count);
 	}
+
 	if (enable_stats) {
 		rte_atomic64_add(&vdev->stats.rx_total_atomic, rx_count);
 		rte_atomic64_add(&vdev->stats.rx_atomic, enqueue_count);
 	}
 
-	free_pkts(pkts, rx_count);
+	if (!async_vhost_driver)
+		free_pkts(pkts, rx_count);
 }
 
 static __rte_always_inline void
@@ -1256,6 +1296,9 @@ destroy_device(int vid)
 		"(%d) device has been removed from data core\n",
 		vdev->vid);
 
+	if (async_vhost_driver)
+		rte_vhost_async_channel_unregister(vid, VIRTIO_RXQ);
+
 	rte_free(vdev);
 }
 
@@ -1270,6 +1313,12 @@ new_device(int vid)
 	uint32_t device_num_min = num_devices;
 	struct vhost_dev *vdev;
 
+	struct rte_vhost_async_channel_ops channel_ops = {
+		.transfer_data = ioat_transfer_data_cb,
+		.check_completed_copies = ioat_check_completed_copies_cb
+	};
+	struct rte_vhost_async_features f;
+
 	vdev = rte_zmalloc("vhost device", sizeof(*vdev), RTE_CACHE_LINE_SIZE);
 	if (vdev == NULL) {
 		RTE_LOG(INFO, VHOST_DATA,
@@ -1310,6 +1359,13 @@ new_device(int vid)
 		"(%d) device has been added to data core %d\n",
 		vid, vdev->coreid);
 
+	if (async_vhost_driver) {
+		f.async_inorder = 1;
+		f.async_threshold = 256;
+		return rte_vhost_async_channel_register(vid, VIRTIO_RXQ,
+			f.intval, &channel_ops);
+	}
+
 	return 0;
 }
 
@@ -1551,6 +1607,9 @@ main(int argc, char *argv[])
 	/* Register vhost user driver to handle vhost messages. */
 	for (i = 0; i < nb_sockets; i++) {
 		char *file = socket_files + i * PATH_MAX;
+		if (async_vhost_driver)
+			flags = flags | RTE_VHOST_USER_ASYNC_COPY;
+
 		ret = rte_vhost_driver_register(file, flags);
 		if (ret != 0) {
 			unregister_drivers(i);
diff --git a/examples/vhost/main.h b/examples/vhost/main.h
index eac18824b..e4cf13190 100644
--- a/examples/vhost/main.h
+++ b/examples/vhost/main.h
@@ -8,6 +8,7 @@
 #include <sys/queue.h>
 
 #include <rte_ether.h>
+#include <rte_vhost_async.h>
 
 /* Macros for printing using RTE_LOG */
 #define RTE_LOGTYPE_VHOST_CONFIG RTE_LOGTYPE_USER1
@@ -51,6 +52,7 @@ struct vhost_dev {
 	uint64_t features;
 	size_t hdr_len;
 	uint16_t nr_vrings;
+	uint16_t nr_async_pkts;
 	struct rte_vhost_memory *mem;
 	struct device_statistics stats;
 	TAILQ_ENTRY(vhost_dev) global_vdev_entry;
@@ -92,3 +94,13 @@ uint16_t vs_dequeue_pkts(struct vhost_dev *dev, uint16_t queue_id,
 #endif /* _MAIN_H_ */
 
 int open_ioat(const char *value);
+
+uint32_t
+ioat_transfer_data_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_desc *descs,
+		struct rte_vhost_async_status *opaque_data, uint16_t count);
+
+uint32_t
+ioat_check_completed_copies_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_status *opaque_data,
+		uint16_t max_packets);
-- 
2.27.0


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

* [dpdk-dev] [PATCH v3 3/4] doc: update vhost sample doc for vhost async data path
  2020-09-30  3:08   ` [dpdk-dev] [PATCH v3 0/4] add async data path in " Cheng Jiang
  2020-09-30  3:08     ` [dpdk-dev] [PATCH v3 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
  2020-09-30  3:08     ` [dpdk-dev] [PATCH v3 2/4] example/vhost: add support for vhost async data path Cheng Jiang
@ 2020-09-30  3:08     ` Cheng Jiang
  2020-09-30  3:08     ` [dpdk-dev] [PATCH v3 4/4] doc: update release notes for vhost sample Cheng Jiang
  2020-10-12  4:54     ` [dpdk-dev] [PATCH v4 0/4] add async data path in " Cheng Jiang
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-09-30  3:08 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

Add vhost async driver arguments information for vhost async data
path in vhost sample application.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 doc/guides/sample_app_ug/vhost.rst | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/doc/guides/sample_app_ug/vhost.rst b/doc/guides/sample_app_ug/vhost.rst
index b7ed4f8bd..0f4f70945 100644
--- a/doc/guides/sample_app_ug/vhost.rst
+++ b/doc/guides/sample_app_ug/vhost.rst
@@ -162,6 +162,17 @@ enabled and cannot be disabled.
 A very simple vhost-user net driver which demonstrates how to use the generic
 vhost APIs will be used when this option is given. It is disabled by default.
 
+**--dma-type**
+This parameter is used to specify DMA type for async vhost-user net driver which
+demonstrates how to use the async vhost APIs. It's used in combination with dmas.
+
+**--dmas**
+This parameter is used to specify the assigned DMA device of a vhost device.
+Async vhost-user net driver will be used if --dmas is set. For example
+--dmas [txd0@00:04.0,txd1@00:04.1] means use DMA channel 00:04.0 for vhost
+device 0 enqueue operation and use DMA channel 00:04.1 for vhost device 1
+enqueue operation.
+
 Common Issues
 -------------
 
-- 
2.27.0


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

* [dpdk-dev] [PATCH v3 4/4] doc: update release notes for vhost sample
  2020-09-30  3:08   ` [dpdk-dev] [PATCH v3 0/4] add async data path in " Cheng Jiang
                       ` (2 preceding siblings ...)
  2020-09-30  3:08     ` [dpdk-dev] [PATCH v3 3/4] doc: update vhost sample doc " Cheng Jiang
@ 2020-09-30  3:08     ` Cheng Jiang
  2020-10-12  4:54     ` [dpdk-dev] [PATCH v4 0/4] add async data path in " Cheng Jiang
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-09-30  3:08 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

Add release notes for vhost async data path support in vhost sample.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 doc/guides/rel_notes/release_20_11.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst
index 92431cd52..6439146b2 100644
--- a/doc/guides/rel_notes/release_20_11.rst
+++ b/doc/guides/rel_notes/release_20_11.rst
@@ -55,6 +55,12 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Updated vhost sample application.**
+
+  Added vhost asynchronous APIs support, which demonstrated how the application
+  leverage IOAT DMA channel with vhost asynchronous APIs.
+  See the :doc:`../sample_app_ug/vhost` for more details.
+
 
 Removed Items
 -------------
-- 
2.27.0


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

* [dpdk-dev] [PATCH v4 0/4] add async data path in vhost sample
  2020-09-30  3:08   ` [dpdk-dev] [PATCH v3 0/4] add async data path in " Cheng Jiang
                       ` (3 preceding siblings ...)
  2020-09-30  3:08     ` [dpdk-dev] [PATCH v3 4/4] doc: update release notes for vhost sample Cheng Jiang
@ 2020-10-12  4:54     ` Cheng Jiang
  2020-10-12  4:54       ` [dpdk-dev] [PATCH v4 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
                         ` (4 more replies)
  4 siblings, 5 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-12  4:54 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

This patch set makes vhost-vswitch be able to use vhost async APIs
for enqueue operations. Demonstrated how the application
leverage IOAT DMA channel with vhost async APIs.

We introduce two parameters to enable DMA acceleration for Tx
operations of queues:
-dma_type This parameter is used to specify DMA type for async
vhost-user net driver.
-dmas This parameter is used to specify the assigned DMA device of a
vhost device and enable async vhost data path.

---
v4:
 * Code rebased for latest IOAT driver

v3:
 * Fixed a coding style problem

v2:
 * Changed meson build file to fix dependency problem
 * Added parameter description in usage function
 * Optimized parameter settings and parsing function
 * Optimized abstraction, moved some code to ioat.c

Cheng Jiang (4):
  example/vhost: add async vhost args parsing function
  example/vhost: add support for vhost async data path
  doc: update vhost sample doc for vhost async data path
  doc: update release notes for vhost sample

 doc/guides/rel_notes/release_20_11.rst |   6 +
 doc/guides/sample_app_ug/vhost.rst     |  11 ++
 examples/vhost/ioat.c                  | 209 +++++++++++++++++++++++++
 examples/vhost/main.c                  |  98 +++++++++++-
 examples/vhost/main.h                  |  14 ++
 examples/vhost/meson.build             |   4 +-
 6 files changed, 338 insertions(+), 4 deletions(-)
 create mode 100644 examples/vhost/ioat.c

--
2.27.0


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

* [dpdk-dev] [PATCH v4 1/4] example/vhost: add async vhost args parsing function
  2020-10-12  4:54     ` [dpdk-dev] [PATCH v4 0/4] add async data path in " Cheng Jiang
@ 2020-10-12  4:54       ` Cheng Jiang
  2020-10-14  9:23         ` Maxime Coquelin
  2020-10-12  4:54       ` [dpdk-dev] [PATCH v4 2/4] example/vhost: add support for vhost async data path Cheng Jiang
                         ` (3 subsequent siblings)
  4 siblings, 1 reply; 71+ messages in thread
From: Cheng Jiang @ 2020-10-12  4:54 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

This patch is to add async vhost driver arguments parsing function
for CBDMA channel, DMA initiation function and args description.
The meson build file is changed to fix dependency problem. With
these arguments vhost device can be set to use CBDMA or CPU for
enqueue operation and bind vhost device with specific CBDMA channel
to accelerate data copy.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 examples/vhost/ioat.c      | 117 +++++++++++++++++++++++++++++++++++++
 examples/vhost/main.c      |  37 +++++++++++-
 examples/vhost/main.h      |   2 +
 examples/vhost/meson.build |   4 +-
 4 files changed, 157 insertions(+), 3 deletions(-)
 create mode 100644 examples/vhost/ioat.c

diff --git a/examples/vhost/ioat.c b/examples/vhost/ioat.c
new file mode 100644
index 000000000..c3158d3c3
--- /dev/null
+++ b/examples/vhost/ioat.c
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2017 Intel Corporation
+ */
+
+#include <rte_vhost.h>
+#include <rte_rawdev.h>
+#include <rte_ioat_rawdev.h>
+#include <rte_pci.h>
+
+#include "main.h"
+
+#define MAX_VHOST_DEVICE 1024
+#define IOAT_RING_SIZE 4096
+
+struct dma_info {
+	struct rte_pci_addr addr;
+	uint16_t dev_id;
+	bool is_valid;
+};
+
+struct dma_for_vhost {
+	struct dma_info dmas[RTE_MAX_QUEUES_PER_PORT * 2];
+	uint16_t nr;
+};
+
+struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
+
+int
+open_ioat(const char *value)
+{
+	struct dma_for_vhost *dma_info = dma_bind;
+	char *input = strndup(value, strlen(value) + 1);
+	char *addrs = input;
+	char *ptrs[2];
+	char *start, *end, *substr;
+	int64_t vid, vring_id;
+	struct rte_ioat_rawdev_config config;
+	struct rte_rawdev_info info = { .dev_private = &config };
+	char name[32];
+	int dev_id;
+	int ret = 0;
+	uint16_t i = 0;
+	char *dma_arg[MAX_VHOST_DEVICE];
+	uint8_t args_nr;
+
+	while (isblank(*addrs))
+		addrs++;
+	if (*addrs == '\0') {
+		ret = -1;
+		goto out;
+	}
+
+	/* process DMA devices within bracket. */
+	addrs++;
+	substr = strtok(addrs, ";]");
+	if (!substr) {
+		ret = -1;
+		goto out;
+	}
+	args_nr = rte_strsplit(substr, strlen(substr),
+			dma_arg, MAX_VHOST_DEVICE, ',');
+	do {
+		char *arg_temp = dma_arg[i];
+		rte_strsplit(arg_temp, strlen(arg_temp), ptrs, 2, '@');
+
+		start = strstr(ptrs[0], "txd");
+		if (start == NULL) {
+			ret = -1;
+			goto out;
+		}
+
+		start += 3;
+		vid = strtol(start, &end, 0);
+		if (end == start) {
+			ret = -1;
+			goto out;
+		}
+
+		vring_id = 0 + VIRTIO_RXQ;
+		if (rte_pci_addr_parse(ptrs[1],
+				&(dma_info + vid)->dmas[vring_id].addr) < 0) {
+			ret = -1;
+			goto out;
+		}
+
+		rte_pci_device_name(&(dma_info + vid)->dmas[vring_id].addr,
+				name, sizeof(name));
+		dev_id = rte_rawdev_get_dev_id(name);
+		if (dev_id == (uint16_t)(-ENODEV) ||
+		dev_id == (uint16_t)(-EINVAL)) {
+			ret = -1;
+			goto out;
+		}
+
+		if (rte_rawdev_info_get(dev_id, &info, sizeof(config)) < 0 ||
+		strstr(info.driver_name, "ioat") == NULL) {
+			ret = -1;
+			goto out;
+		}
+
+		(dma_info + vid)->dmas[vring_id].dev_id = dev_id;
+		(dma_info + vid)->dmas[vring_id].is_valid = true;
+		config.ring_size = IOAT_RING_SIZE;
+		config.hdls_disable = true;
+		if (rte_rawdev_configure(dev_id, &info, sizeof(config)) < 0) {
+			ret = -1;
+			goto out;
+		}
+		rte_rawdev_start(dev_id);
+
+		dma_info->nr++;
+		i++;
+	} while (i < args_nr);
+out:
+	free(input);
+	return ret;
+}
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 959c0c283..4806419d6 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -95,6 +95,10 @@ static int client_mode;
 
 static int builtin_net_driver;
 
+static int async_vhost_driver;
+
+static char dma_type[MAX_LONG_OPT_SZ];
+
 /* Specify timeout (in useconds) between retries on RX. */
 static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
 /* Specify the number of retries on RX. */
@@ -181,6 +185,15 @@ struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];
 				 / US_PER_S * BURST_TX_DRAIN_US)
 #define VLAN_HLEN       4
 
+static inline int
+open_dma(const char *value)
+{
+	if (strncmp(dma_type, "IOAT", 4) == 0)
+		return open_ioat(value);
+	else
+		return -1;
+}
+
 /*
  * Builds up the correct configuration for VMDQ VLAN pool map
  * according to the pool & queue limits.
@@ -446,7 +459,9 @@ us_vhost_usage(const char *prgname)
 	"		--socket-file: The path of the socket file.\n"
 	"		--tx-csum [0|1] disable/enable TX checksum offload.\n"
 	"		--tso [0|1] disable/enable TCP segment offload.\n"
-	"		--client register a vhost-user socket as client mode.\n",
+	"		--client register a vhost-user socket as client mode.\n"
+	"		--dma-type register dma type for your vhost async driver.\n"
+	"		--dmas register dma channel for specific vhost device.\n",
 	       prgname);
 }
 
@@ -472,6 +487,8 @@ us_vhost_parse_args(int argc, char **argv)
 		{"tso", required_argument, NULL, 0},
 		{"client", no_argument, &client_mode, 1},
 		{"builtin-net-driver", no_argument, &builtin_net_driver, 1},
+		{"dma-type", required_argument, NULL, 0},
+		{"dmas", required_argument, NULL, 0},
 		{NULL, 0, 0, 0},
 	};
 
@@ -614,6 +631,24 @@ us_vhost_parse_args(int argc, char **argv)
 				}
 			}
 
+			if (!strncmp(long_option[option_index].name,
+						"dma-type", MAX_LONG_OPT_SZ)) {
+				strcpy(dma_type, optarg);
+			}
+
+			if (!strncmp(long_option[option_index].name,
+						"dmas", MAX_LONG_OPT_SZ)) {
+				if (open_dma(optarg) == -1) {
+					if (*optarg == -1) {
+						RTE_LOG(INFO, VHOST_CONFIG,
+							"Wrong DMA args\n");
+						us_vhost_usage(prgname);
+					}
+					return -1;
+				}
+				async_vhost_driver = 1;
+			}
+
 			break;
 
 			/* Invalid option - print options. */
diff --git a/examples/vhost/main.h b/examples/vhost/main.h
index 7cba0edbf..eac18824b 100644
--- a/examples/vhost/main.h
+++ b/examples/vhost/main.h
@@ -90,3 +90,5 @@ uint16_t vs_dequeue_pkts(struct vhost_dev *dev, uint16_t queue_id,
 			 struct rte_mempool *mbuf_pool,
 			 struct rte_mbuf **pkts, uint16_t count);
 #endif /* _MAIN_H_ */
+
+int open_ioat(const char *value);
diff --git a/examples/vhost/meson.build b/examples/vhost/meson.build
index 872d51153..cb11edd78 100644
--- a/examples/vhost/meson.build
+++ b/examples/vhost/meson.build
@@ -9,8 +9,8 @@
 if not is_linux
 	build = false
 endif
-deps += 'vhost'
+deps += ['vhost', 'rawdev_ioat']
 allow_experimental_apis = true
 sources = files(
-	'main.c', 'virtio_net.c'
+	'main.c', 'virtio_net.c', 'ioat.c'
 )
-- 
2.27.0


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

* [dpdk-dev] [PATCH v4 2/4] example/vhost: add support for vhost async data path
  2020-10-12  4:54     ` [dpdk-dev] [PATCH v4 0/4] add async data path in " Cheng Jiang
  2020-10-12  4:54       ` [dpdk-dev] [PATCH v4 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
@ 2020-10-12  4:54       ` Cheng Jiang
  2020-10-12  4:54       ` [dpdk-dev] [PATCH v4 3/4] doc: update vhost sample doc " Cheng Jiang
                         ` (2 subsequent siblings)
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-12  4:54 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

This patch is to implement vhost DMA operation callbacks for CBDMA
PMD and add vhost async data-path in vhost sample. With providing
callback implementation for CBDMA, vswitch can leverage IOAT to
accelerate vhost async data-path.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 examples/vhost/ioat.c | 92 +++++++++++++++++++++++++++++++++++++++++++
 examples/vhost/main.c | 61 +++++++++++++++++++++++++++-
 examples/vhost/main.h | 12 ++++++
 3 files changed, 164 insertions(+), 1 deletion(-)

diff --git a/examples/vhost/ioat.c b/examples/vhost/ioat.c
index c3158d3c3..d7b7c59c1 100644
--- a/examples/vhost/ioat.c
+++ b/examples/vhost/ioat.c
@@ -6,11 +6,13 @@
 #include <rte_rawdev.h>
 #include <rte_ioat_rawdev.h>
 #include <rte_pci.h>
+#include <sys/uio.h>
 
 #include "main.h"
 
 #define MAX_VHOST_DEVICE 1024
 #define IOAT_RING_SIZE 4096
+#define MAX_ENQUEUED_SIZE 256
 
 struct dma_info {
 	struct rte_pci_addr addr;
@@ -25,6 +27,15 @@ struct dma_for_vhost {
 
 struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
 
+struct packet_tracker {
+	unsigned short size_track[MAX_ENQUEUED_SIZE];
+	unsigned short next_read;
+	unsigned short next_write;
+	unsigned short last_remain;
+};
+
+struct packet_tracker cb_tracker[MAX_VHOST_DEVICE];
+
 int
 open_ioat(const char *value)
 {
@@ -115,3 +126,84 @@ open_ioat(const char *value)
 	free(input);
 	return ret;
 }
+
+uint32_t
+ioat_transfer_data_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_desc *descs,
+		struct rte_vhost_async_status *opaque_data, uint16_t count)
+{
+	int ret;
+	uint32_t i_desc;
+	int dev_id = dma_bind[vid].dmas[queue_id * 2 + VIRTIO_RXQ].dev_id;
+	struct rte_vhost_iov_iter *src = NULL;
+	struct rte_vhost_iov_iter *dst = NULL;
+	unsigned long i_seg;
+	unsigned short mask = MAX_ENQUEUED_SIZE - 1;
+	unsigned short write = cb_tracker[dev_id].next_write;
+
+	if (likely(!opaque_data)) {
+		for (i_desc = 0; i_desc < count; i_desc++) {
+			src = descs[i_desc].src;
+			dst = descs[i_desc].dst;
+			i_seg = 0;
+			while (i_seg < src->nr_segs) {
+				ret = rte_ioat_enqueue_copy(dev_id,
+					(uintptr_t)(src->iov[i_seg].iov_base)
+						+ src->offset,
+					(uintptr_t)(dst->iov[i_seg].iov_base)
+						+ dst->offset,
+					src->iov[i_seg].iov_len,
+					0,
+					0);
+				if (ret != 1)
+					break;
+				i_seg++;
+			}
+			write &= mask;
+			cb_tracker[dev_id].size_track[write] = i_seg;
+			write++;
+		}
+	} else {
+		/* Opaque data is not supported */
+		return -1;
+	}
+	/* ring the doorbell */
+	rte_ioat_perform_ops(dev_id);
+	cb_tracker[dev_id].next_write = write;
+	return i_desc;
+}
+
+uint32_t
+ioat_check_completed_copies_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_status *opaque_data,
+		uint16_t max_packets)
+{
+	if (!opaque_data) {
+		uintptr_t dump[255];
+		unsigned short n_seg;
+		unsigned short read;
+		unsigned short nb_packet = 0;
+		unsigned short mask = MAX_ENQUEUED_SIZE - 1;
+		unsigned short i;
+		int dev_id = dma_bind[vid].dmas[queue_id * 2
+				+ VIRTIO_RXQ].dev_id;
+		n_seg = rte_ioat_completed_ops(dev_id, 255, dump, dump);
+		n_seg = n_seg + cb_tracker[dev_id].last_remain;
+		read = cb_tracker[dev_id].next_read;
+		for (i = 0; i < max_packets; i++) {
+			read &= mask;
+			if (n_seg >= cb_tracker[dev_id].size_track[read]) {
+				n_seg -= cb_tracker[dev_id].size_track[read];
+				read++;
+				nb_packet++;
+			} else {
+				break;
+			}
+		}
+		cb_tracker[dev_id].next_read = read;
+		cb_tracker[dev_id].last_remain = n_seg;
+		return nb_packet;
+	}
+	/* Opaque data is not supported */
+	return -1;
+}
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 4806419d6..f37d1f691 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -804,9 +804,26 @@ virtio_xmit(struct vhost_dev *dst_vdev, struct vhost_dev *src_vdev,
 	    struct rte_mbuf *m)
 {
 	uint16_t ret;
+	struct rte_mbuf *m_cpl[1];
 
 	if (builtin_net_driver) {
 		ret = vs_enqueue_pkts(dst_vdev, VIRTIO_RXQ, &m, 1);
+	} else if (async_vhost_driver) {
+		ret = rte_vhost_submit_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ,
+						&m, 1);
+
+		if (likely(ret)) {
+			dst_vdev->nr_async_pkts++;
+			rte_mbuf_refcnt_update(m, 1);
+		}
+
+		while (likely(dst_vdev->nr_async_pkts)) {
+			if (rte_vhost_poll_enqueue_completed(dst_vdev->vid,
+					VIRTIO_RXQ, m_cpl, 1)) {
+				dst_vdev->nr_async_pkts--;
+				rte_pktmbuf_free(*m_cpl);
+			}
+		}
 	} else {
 		ret = rte_vhost_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ, &m, 1);
 	}
@@ -1055,6 +1072,19 @@ drain_mbuf_table(struct mbuf_table *tx_q)
 	}
 }
 
+static __rte_always_inline void
+complete_async_pkts(struct vhost_dev *vdev, uint16_t qid)
+{
+	struct rte_mbuf *p_cpl[MAX_PKT_BURST];
+	uint16_t complete_count;
+
+	complete_count = rte_vhost_poll_enqueue_completed(vdev->vid,
+						qid, p_cpl, MAX_PKT_BURST);
+	vdev->nr_async_pkts -= complete_count;
+	if (complete_count)
+		free_pkts(p_cpl, complete_count);
+}
+
 static __rte_always_inline void
 drain_eth_rx(struct vhost_dev *vdev)
 {
@@ -1063,6 +1093,10 @@ drain_eth_rx(struct vhost_dev *vdev)
 
 	rx_count = rte_eth_rx_burst(ports[0], vdev->vmdq_rx_q,
 				    pkts, MAX_PKT_BURST);
+
+	while (likely(vdev->nr_async_pkts))
+		complete_async_pkts(vdev, VIRTIO_RXQ);
+
 	if (!rx_count)
 		return;
 
@@ -1087,16 +1121,22 @@ drain_eth_rx(struct vhost_dev *vdev)
 	if (builtin_net_driver) {
 		enqueue_count = vs_enqueue_pkts(vdev, VIRTIO_RXQ,
 						pkts, rx_count);
+	} else if (async_vhost_driver) {
+		enqueue_count = rte_vhost_submit_enqueue_burst(vdev->vid,
+					VIRTIO_RXQ, pkts, rx_count);
+		vdev->nr_async_pkts += enqueue_count;
 	} else {
 		enqueue_count = rte_vhost_enqueue_burst(vdev->vid, VIRTIO_RXQ,
 						pkts, rx_count);
 	}
+
 	if (enable_stats) {
 		rte_atomic64_add(&vdev->stats.rx_total_atomic, rx_count);
 		rte_atomic64_add(&vdev->stats.rx_atomic, enqueue_count);
 	}
 
-	free_pkts(pkts, rx_count);
+	if (!async_vhost_driver)
+		free_pkts(pkts, rx_count);
 }
 
 static __rte_always_inline void
@@ -1243,6 +1283,9 @@ destroy_device(int vid)
 		"(%d) device has been removed from data core\n",
 		vdev->vid);
 
+	if (async_vhost_driver)
+		rte_vhost_async_channel_unregister(vid, VIRTIO_RXQ);
+
 	rte_free(vdev);
 }
 
@@ -1257,6 +1300,12 @@ new_device(int vid)
 	uint32_t device_num_min = num_devices;
 	struct vhost_dev *vdev;
 
+	struct rte_vhost_async_channel_ops channel_ops = {
+		.transfer_data = ioat_transfer_data_cb,
+		.check_completed_copies = ioat_check_completed_copies_cb
+	};
+	struct rte_vhost_async_features f;
+
 	vdev = rte_zmalloc("vhost device", sizeof(*vdev), RTE_CACHE_LINE_SIZE);
 	if (vdev == NULL) {
 		RTE_LOG(INFO, VHOST_DATA,
@@ -1297,6 +1346,13 @@ new_device(int vid)
 		"(%d) device has been added to data core %d\n",
 		vid, vdev->coreid);
 
+	if (async_vhost_driver) {
+		f.async_inorder = 1;
+		f.async_threshold = 256;
+		return rte_vhost_async_channel_register(vid, VIRTIO_RXQ,
+			f.intval, &channel_ops);
+	}
+
 	return 0;
 }
 
@@ -1535,6 +1591,9 @@ main(int argc, char *argv[])
 	/* Register vhost user driver to handle vhost messages. */
 	for (i = 0; i < nb_sockets; i++) {
 		char *file = socket_files + i * PATH_MAX;
+		if (async_vhost_driver)
+			flags = flags | RTE_VHOST_USER_ASYNC_COPY;
+
 		ret = rte_vhost_driver_register(file, flags);
 		if (ret != 0) {
 			unregister_drivers(i);
diff --git a/examples/vhost/main.h b/examples/vhost/main.h
index eac18824b..e4cf13190 100644
--- a/examples/vhost/main.h
+++ b/examples/vhost/main.h
@@ -8,6 +8,7 @@
 #include <sys/queue.h>
 
 #include <rte_ether.h>
+#include <rte_vhost_async.h>
 
 /* Macros for printing using RTE_LOG */
 #define RTE_LOGTYPE_VHOST_CONFIG RTE_LOGTYPE_USER1
@@ -51,6 +52,7 @@ struct vhost_dev {
 	uint64_t features;
 	size_t hdr_len;
 	uint16_t nr_vrings;
+	uint16_t nr_async_pkts;
 	struct rte_vhost_memory *mem;
 	struct device_statistics stats;
 	TAILQ_ENTRY(vhost_dev) global_vdev_entry;
@@ -92,3 +94,13 @@ uint16_t vs_dequeue_pkts(struct vhost_dev *dev, uint16_t queue_id,
 #endif /* _MAIN_H_ */
 
 int open_ioat(const char *value);
+
+uint32_t
+ioat_transfer_data_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_desc *descs,
+		struct rte_vhost_async_status *opaque_data, uint16_t count);
+
+uint32_t
+ioat_check_completed_copies_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_status *opaque_data,
+		uint16_t max_packets);
-- 
2.27.0


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

* [dpdk-dev] [PATCH v4 3/4] doc: update vhost sample doc for vhost async data path
  2020-10-12  4:54     ` [dpdk-dev] [PATCH v4 0/4] add async data path in " Cheng Jiang
  2020-10-12  4:54       ` [dpdk-dev] [PATCH v4 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
  2020-10-12  4:54       ` [dpdk-dev] [PATCH v4 2/4] example/vhost: add support for vhost async data path Cheng Jiang
@ 2020-10-12  4:54       ` Cheng Jiang
  2020-10-12  4:54       ` [dpdk-dev] [PATCH v4 4/4] doc: update release notes for vhost sample Cheng Jiang
  2020-10-15  4:54       ` [dpdk-dev] [PATCH v5 0/4] add async data path in " Cheng Jiang
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-12  4:54 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

Add vhost async driver arguments information for vhost async data
path in vhost sample application.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 doc/guides/sample_app_ug/vhost.rst | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/doc/guides/sample_app_ug/vhost.rst b/doc/guides/sample_app_ug/vhost.rst
index b7ed4f8bd..0f4f70945 100644
--- a/doc/guides/sample_app_ug/vhost.rst
+++ b/doc/guides/sample_app_ug/vhost.rst
@@ -162,6 +162,17 @@ enabled and cannot be disabled.
 A very simple vhost-user net driver which demonstrates how to use the generic
 vhost APIs will be used when this option is given. It is disabled by default.
 
+**--dma-type**
+This parameter is used to specify DMA type for async vhost-user net driver which
+demonstrates how to use the async vhost APIs. It's used in combination with dmas.
+
+**--dmas**
+This parameter is used to specify the assigned DMA device of a vhost device.
+Async vhost-user net driver will be used if --dmas is set. For example
+--dmas [txd0@00:04.0,txd1@00:04.1] means use DMA channel 00:04.0 for vhost
+device 0 enqueue operation and use DMA channel 00:04.1 for vhost device 1
+enqueue operation.
+
 Common Issues
 -------------
 
-- 
2.27.0


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

* [dpdk-dev] [PATCH v4 4/4] doc: update release notes for vhost sample
  2020-10-12  4:54     ` [dpdk-dev] [PATCH v4 0/4] add async data path in " Cheng Jiang
                         ` (2 preceding siblings ...)
  2020-10-12  4:54       ` [dpdk-dev] [PATCH v4 3/4] doc: update vhost sample doc " Cheng Jiang
@ 2020-10-12  4:54       ` Cheng Jiang
  2020-10-15  4:54       ` [dpdk-dev] [PATCH v5 0/4] add async data path in " Cheng Jiang
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-12  4:54 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

Add release notes for vhost async data path support in vhost sample.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 doc/guides/rel_notes/release_20_11.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst
index 26cc0949a..aa69d6dca 100644
--- a/doc/guides/rel_notes/release_20_11.rst
+++ b/doc/guides/rel_notes/release_20_11.rst
@@ -148,6 +148,12 @@ New Features
   * Extern objects and functions can be plugged into the pipeline.
   * Transaction-oriented table updates.
 
+* **Updated vhost sample application.**
+
+  Added vhost asynchronous APIs support, which demonstrated how the application
+  leverage IOAT DMA channel with vhost asynchronous APIs.
+  See the :doc:`../sample_app_ug/vhost` for more details.
+
 
 Removed Items
 -------------
-- 
2.27.0


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

* Re: [dpdk-dev] [PATCH v4 1/4] example/vhost: add async vhost args parsing function
  2020-10-12  4:54       ` [dpdk-dev] [PATCH v4 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
@ 2020-10-14  9:23         ` Maxime Coquelin
  2020-10-15  5:11           ` Jiang, Cheng1
  0 siblings, 1 reply; 71+ messages in thread
From: Maxime Coquelin @ 2020-10-14  9:23 UTC (permalink / raw)
  To: Cheng Jiang, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu



On 10/12/20 6:54 AM, Cheng Jiang wrote:
> This patch is to add async vhost driver arguments parsing function
> for CBDMA channel, DMA initiation function and args description.
> The meson build file is changed to fix dependency problem. With
> these arguments vhost device can be set to use CBDMA or CPU for
> enqueue operation and bind vhost device with specific CBDMA channel
> to accelerate data copy.
> 
> Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
> ---
>  examples/vhost/ioat.c      | 117 +++++++++++++++++++++++++++++++++++++
>  examples/vhost/main.c      |  37 +++++++++++-
>  examples/vhost/main.h      |   2 +
>  examples/vhost/meson.build |   4 +-
>  4 files changed, 157 insertions(+), 3 deletions(-)
>  create mode 100644 examples/vhost/ioat.c
> 
> diff --git a/examples/vhost/ioat.c b/examples/vhost/ioat.c
> new file mode 100644
> index 000000000..c3158d3c3
> --- /dev/null
> +++ b/examples/vhost/ioat.c
> @@ -0,0 +1,117 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2010-2017 Intel Corporation
> + */
> +
> +#include <rte_vhost.h>
> +#include <rte_rawdev.h>
> +#include <rte_ioat_rawdev.h>
> +#include <rte_pci.h>
> +
> +#include "main.h"
> +
> +#define MAX_VHOST_DEVICE 1024
> +#define IOAT_RING_SIZE 4096
> +
> +struct dma_info {
> +	struct rte_pci_addr addr;
> +	uint16_t dev_id;
> +	bool is_valid;
> +};
> +
> +struct dma_for_vhost {
> +	struct dma_info dmas[RTE_MAX_QUEUES_PER_PORT * 2];
> +	uint16_t nr;
> +};
> +
> +struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
> +
> +int
> +open_ioat(const char *value)
> +{
> +	struct dma_for_vhost *dma_info = dma_bind;
> +	char *input = strndup(value, strlen(value) + 1);
> +	char *addrs = input;
> +	char *ptrs[2];
> +	char *start, *end, *substr;
> +	int64_t vid, vring_id;
> +	struct rte_ioat_rawdev_config config;
> +	struct rte_rawdev_info info = { .dev_private = &config };
> +	char name[32];
> +	int dev_id;
> +	int ret = 0;
> +	uint16_t i = 0;
> +	char *dma_arg[MAX_VHOST_DEVICE];
> +	uint8_t args_nr;
> +
> +	while (isblank(*addrs))
> +		addrs++;
> +	if (*addrs == '\0') {
> +		ret = -1;
> +		goto out;
> +	}
> +
> +	/* process DMA devices within bracket. */
> +	addrs++;
> +	substr = strtok(addrs, ";]");
> +	if (!substr) {
> +		ret = -1;
> +		goto out;
> +	}
> +	args_nr = rte_strsplit(substr, strlen(substr),
> +			dma_arg, MAX_VHOST_DEVICE, ',');
> +	do {
> +		char *arg_temp = dma_arg[i];
> +		rte_strsplit(arg_temp, strlen(arg_temp), ptrs, 2, '@');
> +
> +		start = strstr(ptrs[0], "txd");
> +		if (start == NULL) {
> +			ret = -1;
> +			goto out;
> +		}
> +
> +		start += 3;
> +		vid = strtol(start, &end, 0);
> +		if (end == start) {
> +			ret = -1;
> +			goto out;
> +		}
> +
> +		vring_id = 0 + VIRTIO_RXQ;
> +		if (rte_pci_addr_parse(ptrs[1],
> +				&(dma_info + vid)->dmas[vring_id].addr) < 0) {
> +			ret = -1;
> +			goto out;
> +		}
> +
> +		rte_pci_device_name(&(dma_info + vid)->dmas[vring_id].addr,
> +				name, sizeof(name));
> +		dev_id = rte_rawdev_get_dev_id(name);
> +		if (dev_id == (uint16_t)(-ENODEV) ||
> +		dev_id == (uint16_t)(-EINVAL)) {
> +			ret = -1;
> +			goto out;
> +		}
> +
> +		if (rte_rawdev_info_get(dev_id, &info, sizeof(config)) < 0 ||
> +		strstr(info.driver_name, "ioat") == NULL) {
> +			ret = -1;
> +			goto out;
> +		}
> +
> +		(dma_info + vid)->dmas[vring_id].dev_id = dev_id;
> +		(dma_info + vid)->dmas[vring_id].is_valid = true;
> +		config.ring_size = IOAT_RING_SIZE;
> +		config.hdls_disable = true;
> +		if (rte_rawdev_configure(dev_id, &info, sizeof(config)) < 0) {
> +			ret = -1;
> +			goto out;
> +		}
> +		rte_rawdev_start(dev_id);
> +
> +		dma_info->nr++;
> +		i++;
> +	} while (i < args_nr);
> +out:
> +	free(input);
> +	return ret;
> +}
> diff --git a/examples/vhost/main.c b/examples/vhost/main.c
> index 959c0c283..4806419d6 100644
> --- a/examples/vhost/main.c
> +++ b/examples/vhost/main.c
> @@ -95,6 +95,10 @@ static int client_mode;
>  
>  static int builtin_net_driver;
>  
> +static int async_vhost_driver;
> +
> +static char dma_type[MAX_LONG_OPT_SZ];
> +
>  /* Specify timeout (in useconds) between retries on RX. */
>  static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
>  /* Specify the number of retries on RX. */
> @@ -181,6 +185,15 @@ struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];
>  				 / US_PER_S * BURST_TX_DRAIN_US)
>  #define VLAN_HLEN       4
>  
> +static inline int
> +open_dma(const char *value)
> +{
> +	if (strncmp(dma_type, "IOAT", 4) == 0)

I think it is better to have it in lower case.

> +		return open_ioat(value);
> +	else
> +		return -1;
> +}
> +
>  /*
>   * Builds up the correct configuration for VMDQ VLAN pool map
>   * according to the pool & queue limits.
> @@ -446,7 +459,9 @@ us_vhost_usage(const char *prgname)
>  	"		--socket-file: The path of the socket file.\n"
>  	"		--tx-csum [0|1] disable/enable TX checksum offload.\n"
>  	"		--tso [0|1] disable/enable TCP segment offload.\n"
> -	"		--client register a vhost-user socket as client mode.\n",
> +	"		--client register a vhost-user socket as client mode.\n"
> +	"		--dma-type register dma type for your vhost async driver.\n"

I think you should mention possible DMA types, i.e. "ioat" for now.

> +	"		--dmas register dma channel for specific vhost device.\n",
>  	       prgname);
>  }
>  
> @@ -472,6 +487,8 @@ us_vhost_parse_args(int argc, char **argv)
>  		{"tso", required_argument, NULL, 0},
>  		{"client", no_argument, &client_mode, 1},
>  		{"builtin-net-driver", no_argument, &builtin_net_driver, 1},
> +		{"dma-type", required_argument, NULL, 0},
> +		{"dmas", required_argument, NULL, 0},
>  		{NULL, 0, 0, 0},
>  	};
>  
> @@ -614,6 +631,24 @@ us_vhost_parse_args(int argc, char **argv)
>  				}
>  			}
>  
> +			if (!strncmp(long_option[option_index].name,
> +						"dma-type", MAX_LONG_OPT_SZ)) {
> +				strcpy(dma_type, optarg);
> +			}
> +
> +			if (!strncmp(long_option[option_index].name,
> +						"dmas", MAX_LONG_OPT_SZ)) {
> +				if (open_dma(optarg) == -1) {
> +					if (*optarg == -1) {
> +						RTE_LOG(INFO, VHOST_CONFIG,
> +							"Wrong DMA args\n");
> +						us_vhost_usage(prgname);
> +					}
> +					return -1;
> +				}
> +				async_vhost_driver = 1;
> +			}
> +
>  			break;
>  
>  			/* Invalid option - print options. */
> diff --git a/examples/vhost/main.h b/examples/vhost/main.h
> index 7cba0edbf..eac18824b 100644
> --- a/examples/vhost/main.h
> +++ b/examples/vhost/main.h
> @@ -90,3 +90,5 @@ uint16_t vs_dequeue_pkts(struct vhost_dev *dev, uint16_t queue_id,
>  			 struct rte_mempool *mbuf_pool,
>  			 struct rte_mbuf **pkts, uint16_t count);
>  #endif /* _MAIN_H_ */
> +
> +int open_ioat(const char *value);
> diff --git a/examples/vhost/meson.build b/examples/vhost/meson.build
> index 872d51153..cb11edd78 100644
> --- a/examples/vhost/meson.build
> +++ b/examples/vhost/meson.build
> @@ -9,8 +9,8 @@
>  if not is_linux
>  	build = false
>  endif
> -deps += 'vhost'
> +deps += ['vhost', 'rawdev_ioat']

It is breaking build on other platforms than X86:
https://travis-ci.com/github/ovsrobot/dpdk/builds/189405820

It should be done the other way, which is to enable ioat support in this
example if rawdev_ioat is supported.

>  allow_experimental_apis = true
>  sources = files(
> -	'main.c', 'virtio_net.c'
> +	'main.c', 'virtio_net.c', 'ioat.c'
>  )
> 


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

* [dpdk-dev] [PATCH v5 0/4] add async data path in vhost sample
  2020-10-12  4:54     ` [dpdk-dev] [PATCH v4 0/4] add async data path in " Cheng Jiang
                         ` (3 preceding siblings ...)
  2020-10-12  4:54       ` [dpdk-dev] [PATCH v4 4/4] doc: update release notes for vhost sample Cheng Jiang
@ 2020-10-15  4:54       ` Cheng Jiang
  2020-10-15  4:54         ` [dpdk-dev] [PATCH v5 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
                           ` (4 more replies)
  4 siblings, 5 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-15  4:54 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

This patch set makes vhost-vswitch be able to use vhost async APIs
for enqueue operations. Demonstrated how the application
leverage IOAT DMA channel with vhost async APIs.

We introduce two parameters to enable DMA acceleration for Tx
operations of queues:
-dma_type This parameter is used to specify DMA type for async
vhost-user net driver.
-dmas This parameter is used to specify the assigned DMA device of a
vhost device and enable async vhost data path.

---
v5:
 * Improved meson build file and fixed dependency problem

v4:
 * Code rebased for latest IOAT driver

v3:
 * Fixed a coding style problem

v2:
 * Changed meson build file to fix dependency problem
 * Added parameter description in usage function
 * Optimized parameter settings and parsing function
 * Optimized abstraction, moved some code to ioat.c

Cheng Jiang (4):
  example/vhost: add async vhost args parsing function
  example/vhost: add support for vhost async data path
  doc: update vhost sample doc for vhost async data path
  doc: update release notes for vhost sample

 doc/guides/rel_notes/release_20_11.rst |   6 +
 doc/guides/sample_app_ug/vhost.rst     |  11 ++
 examples/vhost/ioat.c                  | 209 +++++++++++++++++++++++++
 examples/vhost/main.c                  | 104 +++++++++++-
 examples/vhost/main.h                  |  14 ++
 examples/vhost/meson.build             |   5 +
 6 files changed, 347 insertions(+), 2 deletions(-)
 create mode 100644 examples/vhost/ioat.c

--
2.27.0


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

* [dpdk-dev] [PATCH v5 1/4] example/vhost: add async vhost args parsing function
  2020-10-15  4:54       ` [dpdk-dev] [PATCH v5 0/4] add async data path in " Cheng Jiang
@ 2020-10-15  4:54         ` Cheng Jiang
  2020-10-15 15:13           ` Maxime Coquelin
  2020-10-15  4:54         ` [dpdk-dev] [PATCH v5 2/4] example/vhost: add support for vhost async data path Cheng Jiang
                           ` (3 subsequent siblings)
  4 siblings, 1 reply; 71+ messages in thread
From: Cheng Jiang @ 2020-10-15  4:54 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

This patch is to add async vhost driver arguments parsing function
for CBDMA channel, DMA initiation function and args description.
The meson build file is changed to fix dependency problem. With
these arguments vhost device can be set to use CBDMA or CPU for
enqueue operation and bind vhost device with specific CBDMA channel
to accelerate data copy.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 examples/vhost/ioat.c      | 117 +++++++++++++++++++++++++++++++++++++
 examples/vhost/main.c      |  43 +++++++++++++-
 examples/vhost/main.h      |   2 +
 examples/vhost/meson.build |   5 ++
 4 files changed, 166 insertions(+), 1 deletion(-)
 create mode 100644 examples/vhost/ioat.c

diff --git a/examples/vhost/ioat.c b/examples/vhost/ioat.c
new file mode 100644
index 000000000..c3158d3c3
--- /dev/null
+++ b/examples/vhost/ioat.c
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2017 Intel Corporation
+ */
+
+#include <rte_vhost.h>
+#include <rte_rawdev.h>
+#include <rte_ioat_rawdev.h>
+#include <rte_pci.h>
+
+#include "main.h"
+
+#define MAX_VHOST_DEVICE 1024
+#define IOAT_RING_SIZE 4096
+
+struct dma_info {
+	struct rte_pci_addr addr;
+	uint16_t dev_id;
+	bool is_valid;
+};
+
+struct dma_for_vhost {
+	struct dma_info dmas[RTE_MAX_QUEUES_PER_PORT * 2];
+	uint16_t nr;
+};
+
+struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
+
+int
+open_ioat(const char *value)
+{
+	struct dma_for_vhost *dma_info = dma_bind;
+	char *input = strndup(value, strlen(value) + 1);
+	char *addrs = input;
+	char *ptrs[2];
+	char *start, *end, *substr;
+	int64_t vid, vring_id;
+	struct rte_ioat_rawdev_config config;
+	struct rte_rawdev_info info = { .dev_private = &config };
+	char name[32];
+	int dev_id;
+	int ret = 0;
+	uint16_t i = 0;
+	char *dma_arg[MAX_VHOST_DEVICE];
+	uint8_t args_nr;
+
+	while (isblank(*addrs))
+		addrs++;
+	if (*addrs == '\0') {
+		ret = -1;
+		goto out;
+	}
+
+	/* process DMA devices within bracket. */
+	addrs++;
+	substr = strtok(addrs, ";]");
+	if (!substr) {
+		ret = -1;
+		goto out;
+	}
+	args_nr = rte_strsplit(substr, strlen(substr),
+			dma_arg, MAX_VHOST_DEVICE, ',');
+	do {
+		char *arg_temp = dma_arg[i];
+		rte_strsplit(arg_temp, strlen(arg_temp), ptrs, 2, '@');
+
+		start = strstr(ptrs[0], "txd");
+		if (start == NULL) {
+			ret = -1;
+			goto out;
+		}
+
+		start += 3;
+		vid = strtol(start, &end, 0);
+		if (end == start) {
+			ret = -1;
+			goto out;
+		}
+
+		vring_id = 0 + VIRTIO_RXQ;
+		if (rte_pci_addr_parse(ptrs[1],
+				&(dma_info + vid)->dmas[vring_id].addr) < 0) {
+			ret = -1;
+			goto out;
+		}
+
+		rte_pci_device_name(&(dma_info + vid)->dmas[vring_id].addr,
+				name, sizeof(name));
+		dev_id = rte_rawdev_get_dev_id(name);
+		if (dev_id == (uint16_t)(-ENODEV) ||
+		dev_id == (uint16_t)(-EINVAL)) {
+			ret = -1;
+			goto out;
+		}
+
+		if (rte_rawdev_info_get(dev_id, &info, sizeof(config)) < 0 ||
+		strstr(info.driver_name, "ioat") == NULL) {
+			ret = -1;
+			goto out;
+		}
+
+		(dma_info + vid)->dmas[vring_id].dev_id = dev_id;
+		(dma_info + vid)->dmas[vring_id].is_valid = true;
+		config.ring_size = IOAT_RING_SIZE;
+		config.hdls_disable = true;
+		if (rte_rawdev_configure(dev_id, &info, sizeof(config)) < 0) {
+			ret = -1;
+			goto out;
+		}
+		rte_rawdev_start(dev_id);
+
+		dma_info->nr++;
+		i++;
+	} while (i < args_nr);
+out:
+	free(input);
+	return ret;
+}
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 959c0c283..ab1b24409 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -95,6 +95,10 @@ static int client_mode;
 
 static int builtin_net_driver;
 
+static int async_vhost_driver;
+
+static char dma_type[MAX_LONG_OPT_SZ];
+
 /* Specify timeout (in useconds) between retries on RX. */
 static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
 /* Specify the number of retries on RX. */
@@ -181,6 +185,21 @@ struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];
 				 / US_PER_S * BURST_TX_DRAIN_US)
 #define VLAN_HLEN       4
 
+static inline int
+open_dma(const char *value)
+{
+#ifdef RTE_ARCH_X86
+	if (strncmp(dma_type, "ioat", 4) == 0)
+		return open_ioat(value);
+	else
+		return -1;
+#else
+	RTE_LOG(ERR, VHOST_PORT,
+			"Error during opening ioat info: %s\n", value);
+	return -1;
+#endif
+}
+
 /*
  * Builds up the correct configuration for VMDQ VLAN pool map
  * according to the pool & queue limits.
@@ -446,7 +465,9 @@ us_vhost_usage(const char *prgname)
 	"		--socket-file: The path of the socket file.\n"
 	"		--tx-csum [0|1] disable/enable TX checksum offload.\n"
 	"		--tso [0|1] disable/enable TCP segment offload.\n"
-	"		--client register a vhost-user socket as client mode.\n",
+	"		--client register a vhost-user socket as client mode.\n"
+	"		--dma-type register dma type for your vhost async driver. For example \"ioat\" for now.\n"
+	"		--dmas register dma channel for specific vhost device.\n",
 	       prgname);
 }
 
@@ -472,6 +493,8 @@ us_vhost_parse_args(int argc, char **argv)
 		{"tso", required_argument, NULL, 0},
 		{"client", no_argument, &client_mode, 1},
 		{"builtin-net-driver", no_argument, &builtin_net_driver, 1},
+		{"dma-type", required_argument, NULL, 0},
+		{"dmas", required_argument, NULL, 0},
 		{NULL, 0, 0, 0},
 	};
 
@@ -614,6 +637,24 @@ us_vhost_parse_args(int argc, char **argv)
 				}
 			}
 
+			if (!strncmp(long_option[option_index].name,
+						"dma-type", MAX_LONG_OPT_SZ)) {
+				strcpy(dma_type, optarg);
+			}
+
+			if (!strncmp(long_option[option_index].name,
+						"dmas", MAX_LONG_OPT_SZ)) {
+				if (open_dma(optarg) == -1) {
+					if (*optarg == -1) {
+						RTE_LOG(INFO, VHOST_CONFIG,
+							"Wrong DMA args\n");
+						us_vhost_usage(prgname);
+					}
+					return -1;
+				}
+				async_vhost_driver = 1;
+			}
+
 			break;
 
 			/* Invalid option - print options. */
diff --git a/examples/vhost/main.h b/examples/vhost/main.h
index 7cba0edbf..eac18824b 100644
--- a/examples/vhost/main.h
+++ b/examples/vhost/main.h
@@ -90,3 +90,5 @@ uint16_t vs_dequeue_pkts(struct vhost_dev *dev, uint16_t queue_id,
 			 struct rte_mempool *mbuf_pool,
 			 struct rte_mbuf **pkts, uint16_t count);
 #endif /* _MAIN_H_ */
+
+int open_ioat(const char *value);
diff --git a/examples/vhost/meson.build b/examples/vhost/meson.build
index 872d51153..2a03f9779 100644
--- a/examples/vhost/meson.build
+++ b/examples/vhost/meson.build
@@ -14,3 +14,8 @@ allow_experimental_apis = true
 sources = files(
 	'main.c', 'virtio_net.c'
 )
+
+if dpdk_conf.has('RTE_ARCH_X86')
+	deps += 'rawdev_ioat'
+	sources += files('ioat.c')
+endif
-- 
2.27.0


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

* [dpdk-dev] [PATCH v5 2/4] example/vhost: add support for vhost async data path
  2020-10-15  4:54       ` [dpdk-dev] [PATCH v5 0/4] add async data path in " Cheng Jiang
  2020-10-15  4:54         ` [dpdk-dev] [PATCH v5 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
@ 2020-10-15  4:54         ` Cheng Jiang
  2020-10-15  4:54         ` [dpdk-dev] [PATCH v5 3/4] doc: update vhost sample doc " Cheng Jiang
                           ` (2 subsequent siblings)
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-15  4:54 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

This patch is to implement vhost DMA operation callbacks for CBDMA
PMD and add vhost async data-path in vhost sample. With providing
callback implementation for CBDMA, vswitch can leverage IOAT to
accelerate vhost async data-path.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 examples/vhost/ioat.c | 92 +++++++++++++++++++++++++++++++++++++++++++
 examples/vhost/main.c | 61 +++++++++++++++++++++++++++-
 examples/vhost/main.h | 12 ++++++
 3 files changed, 164 insertions(+), 1 deletion(-)

diff --git a/examples/vhost/ioat.c b/examples/vhost/ioat.c
index c3158d3c3..d7b7c59c1 100644
--- a/examples/vhost/ioat.c
+++ b/examples/vhost/ioat.c
@@ -6,11 +6,13 @@
 #include <rte_rawdev.h>
 #include <rte_ioat_rawdev.h>
 #include <rte_pci.h>
+#include <sys/uio.h>
 
 #include "main.h"
 
 #define MAX_VHOST_DEVICE 1024
 #define IOAT_RING_SIZE 4096
+#define MAX_ENQUEUED_SIZE 256
 
 struct dma_info {
 	struct rte_pci_addr addr;
@@ -25,6 +27,15 @@ struct dma_for_vhost {
 
 struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
 
+struct packet_tracker {
+	unsigned short size_track[MAX_ENQUEUED_SIZE];
+	unsigned short next_read;
+	unsigned short next_write;
+	unsigned short last_remain;
+};
+
+struct packet_tracker cb_tracker[MAX_VHOST_DEVICE];
+
 int
 open_ioat(const char *value)
 {
@@ -115,3 +126,84 @@ open_ioat(const char *value)
 	free(input);
 	return ret;
 }
+
+uint32_t
+ioat_transfer_data_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_desc *descs,
+		struct rte_vhost_async_status *opaque_data, uint16_t count)
+{
+	int ret;
+	uint32_t i_desc;
+	int dev_id = dma_bind[vid].dmas[queue_id * 2 + VIRTIO_RXQ].dev_id;
+	struct rte_vhost_iov_iter *src = NULL;
+	struct rte_vhost_iov_iter *dst = NULL;
+	unsigned long i_seg;
+	unsigned short mask = MAX_ENQUEUED_SIZE - 1;
+	unsigned short write = cb_tracker[dev_id].next_write;
+
+	if (likely(!opaque_data)) {
+		for (i_desc = 0; i_desc < count; i_desc++) {
+			src = descs[i_desc].src;
+			dst = descs[i_desc].dst;
+			i_seg = 0;
+			while (i_seg < src->nr_segs) {
+				ret = rte_ioat_enqueue_copy(dev_id,
+					(uintptr_t)(src->iov[i_seg].iov_base)
+						+ src->offset,
+					(uintptr_t)(dst->iov[i_seg].iov_base)
+						+ dst->offset,
+					src->iov[i_seg].iov_len,
+					0,
+					0);
+				if (ret != 1)
+					break;
+				i_seg++;
+			}
+			write &= mask;
+			cb_tracker[dev_id].size_track[write] = i_seg;
+			write++;
+		}
+	} else {
+		/* Opaque data is not supported */
+		return -1;
+	}
+	/* ring the doorbell */
+	rte_ioat_perform_ops(dev_id);
+	cb_tracker[dev_id].next_write = write;
+	return i_desc;
+}
+
+uint32_t
+ioat_check_completed_copies_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_status *opaque_data,
+		uint16_t max_packets)
+{
+	if (!opaque_data) {
+		uintptr_t dump[255];
+		unsigned short n_seg;
+		unsigned short read;
+		unsigned short nb_packet = 0;
+		unsigned short mask = MAX_ENQUEUED_SIZE - 1;
+		unsigned short i;
+		int dev_id = dma_bind[vid].dmas[queue_id * 2
+				+ VIRTIO_RXQ].dev_id;
+		n_seg = rte_ioat_completed_ops(dev_id, 255, dump, dump);
+		n_seg = n_seg + cb_tracker[dev_id].last_remain;
+		read = cb_tracker[dev_id].next_read;
+		for (i = 0; i < max_packets; i++) {
+			read &= mask;
+			if (n_seg >= cb_tracker[dev_id].size_track[read]) {
+				n_seg -= cb_tracker[dev_id].size_track[read];
+				read++;
+				nb_packet++;
+			} else {
+				break;
+			}
+		}
+		cb_tracker[dev_id].next_read = read;
+		cb_tracker[dev_id].last_remain = n_seg;
+		return nb_packet;
+	}
+	/* Opaque data is not supported */
+	return -1;
+}
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index ab1b24409..fe8904384 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -810,9 +810,26 @@ virtio_xmit(struct vhost_dev *dst_vdev, struct vhost_dev *src_vdev,
 	    struct rte_mbuf *m)
 {
 	uint16_t ret;
+	struct rte_mbuf *m_cpl[1];
 
 	if (builtin_net_driver) {
 		ret = vs_enqueue_pkts(dst_vdev, VIRTIO_RXQ, &m, 1);
+	} else if (async_vhost_driver) {
+		ret = rte_vhost_submit_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ,
+						&m, 1);
+
+		if (likely(ret)) {
+			dst_vdev->nr_async_pkts++;
+			rte_mbuf_refcnt_update(m, 1);
+		}
+
+		while (likely(dst_vdev->nr_async_pkts)) {
+			if (rte_vhost_poll_enqueue_completed(dst_vdev->vid,
+					VIRTIO_RXQ, m_cpl, 1)) {
+				dst_vdev->nr_async_pkts--;
+				rte_pktmbuf_free(*m_cpl);
+			}
+		}
 	} else {
 		ret = rte_vhost_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ, &m, 1);
 	}
@@ -1061,6 +1078,19 @@ drain_mbuf_table(struct mbuf_table *tx_q)
 	}
 }
 
+static __rte_always_inline void
+complete_async_pkts(struct vhost_dev *vdev, uint16_t qid)
+{
+	struct rte_mbuf *p_cpl[MAX_PKT_BURST];
+	uint16_t complete_count;
+
+	complete_count = rte_vhost_poll_enqueue_completed(vdev->vid,
+						qid, p_cpl, MAX_PKT_BURST);
+	vdev->nr_async_pkts -= complete_count;
+	if (complete_count)
+		free_pkts(p_cpl, complete_count);
+}
+
 static __rte_always_inline void
 drain_eth_rx(struct vhost_dev *vdev)
 {
@@ -1069,6 +1099,10 @@ drain_eth_rx(struct vhost_dev *vdev)
 
 	rx_count = rte_eth_rx_burst(ports[0], vdev->vmdq_rx_q,
 				    pkts, MAX_PKT_BURST);
+
+	while (likely(vdev->nr_async_pkts))
+		complete_async_pkts(vdev, VIRTIO_RXQ);
+
 	if (!rx_count)
 		return;
 
@@ -1093,16 +1127,22 @@ drain_eth_rx(struct vhost_dev *vdev)
 	if (builtin_net_driver) {
 		enqueue_count = vs_enqueue_pkts(vdev, VIRTIO_RXQ,
 						pkts, rx_count);
+	} else if (async_vhost_driver) {
+		enqueue_count = rte_vhost_submit_enqueue_burst(vdev->vid,
+					VIRTIO_RXQ, pkts, rx_count);
+		vdev->nr_async_pkts += enqueue_count;
 	} else {
 		enqueue_count = rte_vhost_enqueue_burst(vdev->vid, VIRTIO_RXQ,
 						pkts, rx_count);
 	}
+
 	if (enable_stats) {
 		rte_atomic64_add(&vdev->stats.rx_total_atomic, rx_count);
 		rte_atomic64_add(&vdev->stats.rx_atomic, enqueue_count);
 	}
 
-	free_pkts(pkts, rx_count);
+	if (!async_vhost_driver)
+		free_pkts(pkts, rx_count);
 }
 
 static __rte_always_inline void
@@ -1249,6 +1289,9 @@ destroy_device(int vid)
 		"(%d) device has been removed from data core\n",
 		vdev->vid);
 
+	if (async_vhost_driver)
+		rte_vhost_async_channel_unregister(vid, VIRTIO_RXQ);
+
 	rte_free(vdev);
 }
 
@@ -1263,6 +1306,12 @@ new_device(int vid)
 	uint32_t device_num_min = num_devices;
 	struct vhost_dev *vdev;
 
+	struct rte_vhost_async_channel_ops channel_ops = {
+		.transfer_data = ioat_transfer_data_cb,
+		.check_completed_copies = ioat_check_completed_copies_cb
+	};
+	struct rte_vhost_async_features f;
+
 	vdev = rte_zmalloc("vhost device", sizeof(*vdev), RTE_CACHE_LINE_SIZE);
 	if (vdev == NULL) {
 		RTE_LOG(INFO, VHOST_DATA,
@@ -1303,6 +1352,13 @@ new_device(int vid)
 		"(%d) device has been added to data core %d\n",
 		vid, vdev->coreid);
 
+	if (async_vhost_driver) {
+		f.async_inorder = 1;
+		f.async_threshold = 256;
+		return rte_vhost_async_channel_register(vid, VIRTIO_RXQ,
+			f.intval, &channel_ops);
+	}
+
 	return 0;
 }
 
@@ -1541,6 +1597,9 @@ main(int argc, char *argv[])
 	/* Register vhost user driver to handle vhost messages. */
 	for (i = 0; i < nb_sockets; i++) {
 		char *file = socket_files + i * PATH_MAX;
+		if (async_vhost_driver)
+			flags = flags | RTE_VHOST_USER_ASYNC_COPY;
+
 		ret = rte_vhost_driver_register(file, flags);
 		if (ret != 0) {
 			unregister_drivers(i);
diff --git a/examples/vhost/main.h b/examples/vhost/main.h
index eac18824b..e4cf13190 100644
--- a/examples/vhost/main.h
+++ b/examples/vhost/main.h
@@ -8,6 +8,7 @@
 #include <sys/queue.h>
 
 #include <rte_ether.h>
+#include <rte_vhost_async.h>
 
 /* Macros for printing using RTE_LOG */
 #define RTE_LOGTYPE_VHOST_CONFIG RTE_LOGTYPE_USER1
@@ -51,6 +52,7 @@ struct vhost_dev {
 	uint64_t features;
 	size_t hdr_len;
 	uint16_t nr_vrings;
+	uint16_t nr_async_pkts;
 	struct rte_vhost_memory *mem;
 	struct device_statistics stats;
 	TAILQ_ENTRY(vhost_dev) global_vdev_entry;
@@ -92,3 +94,13 @@ uint16_t vs_dequeue_pkts(struct vhost_dev *dev, uint16_t queue_id,
 #endif /* _MAIN_H_ */
 
 int open_ioat(const char *value);
+
+uint32_t
+ioat_transfer_data_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_desc *descs,
+		struct rte_vhost_async_status *opaque_data, uint16_t count);
+
+uint32_t
+ioat_check_completed_copies_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_status *opaque_data,
+		uint16_t max_packets);
-- 
2.27.0


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

* [dpdk-dev] [PATCH v5 3/4] doc: update vhost sample doc for vhost async data path
  2020-10-15  4:54       ` [dpdk-dev] [PATCH v5 0/4] add async data path in " Cheng Jiang
  2020-10-15  4:54         ` [dpdk-dev] [PATCH v5 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
  2020-10-15  4:54         ` [dpdk-dev] [PATCH v5 2/4] example/vhost: add support for vhost async data path Cheng Jiang
@ 2020-10-15  4:54         ` Cheng Jiang
  2020-10-15  4:54         ` [dpdk-dev] [PATCH v5 4/4] doc: update release notes for vhost sample Cheng Jiang
  2020-10-16  4:29         ` [dpdk-dev] [PATCH v6 0/4] add async data path in " Cheng Jiang
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-15  4:54 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

Add vhost async driver arguments information for vhost async data
path in vhost sample application.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 doc/guides/sample_app_ug/vhost.rst | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/doc/guides/sample_app_ug/vhost.rst b/doc/guides/sample_app_ug/vhost.rst
index b7ed4f8bd..0f4f70945 100644
--- a/doc/guides/sample_app_ug/vhost.rst
+++ b/doc/guides/sample_app_ug/vhost.rst
@@ -162,6 +162,17 @@ enabled and cannot be disabled.
 A very simple vhost-user net driver which demonstrates how to use the generic
 vhost APIs will be used when this option is given. It is disabled by default.
 
+**--dma-type**
+This parameter is used to specify DMA type for async vhost-user net driver which
+demonstrates how to use the async vhost APIs. It's used in combination with dmas.
+
+**--dmas**
+This parameter is used to specify the assigned DMA device of a vhost device.
+Async vhost-user net driver will be used if --dmas is set. For example
+--dmas [txd0@00:04.0,txd1@00:04.1] means use DMA channel 00:04.0 for vhost
+device 0 enqueue operation and use DMA channel 00:04.1 for vhost device 1
+enqueue operation.
+
 Common Issues
 -------------
 
-- 
2.27.0


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

* [dpdk-dev] [PATCH v5 4/4] doc: update release notes for vhost sample
  2020-10-15  4:54       ` [dpdk-dev] [PATCH v5 0/4] add async data path in " Cheng Jiang
                           ` (2 preceding siblings ...)
  2020-10-15  4:54         ` [dpdk-dev] [PATCH v5 3/4] doc: update vhost sample doc " Cheng Jiang
@ 2020-10-15  4:54         ` Cheng Jiang
  2020-10-16  4:29         ` [dpdk-dev] [PATCH v6 0/4] add async data path in " Cheng Jiang
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-15  4:54 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

Add release notes for vhost async data path support in vhost sample.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 doc/guides/rel_notes/release_20_11.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst
index 26cc0949a..aa69d6dca 100644
--- a/doc/guides/rel_notes/release_20_11.rst
+++ b/doc/guides/rel_notes/release_20_11.rst
@@ -148,6 +148,12 @@ New Features
   * Extern objects and functions can be plugged into the pipeline.
   * Transaction-oriented table updates.
 
+* **Updated vhost sample application.**
+
+  Added vhost asynchronous APIs support, which demonstrated how the application
+  leverage IOAT DMA channel with vhost asynchronous APIs.
+  See the :doc:`../sample_app_ug/vhost` for more details.
+
 
 Removed Items
 -------------
-- 
2.27.0


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

* Re: [dpdk-dev] [PATCH v4 1/4] example/vhost: add async vhost args parsing function
  2020-10-14  9:23         ` Maxime Coquelin
@ 2020-10-15  5:11           ` Jiang, Cheng1
  0 siblings, 0 replies; 71+ messages in thread
From: Jiang, Cheng1 @ 2020-10-15  5:11 UTC (permalink / raw)
  To: Maxime Coquelin, Xia, Chenbo, Wang, Zhihong; +Cc: dev, Fu, Patrick

Hi Maxime,

The replies are inline.

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Wednesday, October 14, 2020 5:24 PM
> To: Jiang, Cheng1 <cheng1.jiang@intel.com>; Xia, Chenbo
> <chenbo.xia@intel.com>; Wang, Zhihong <zhihong.wang@intel.com>
> Cc: dev@dpdk.org; Fu, Patrick <patrick.fu@intel.com>
> Subject: Re: [PATCH v4 1/4] example/vhost: add async vhost args parsing
> function
> 
> 
> 
> On 10/12/20 6:54 AM, Cheng Jiang wrote:
> > This patch is to add async vhost driver arguments parsing function for
> > CBDMA channel, DMA initiation function and args description.
> > The meson build file is changed to fix dependency problem. With these
> > arguments vhost device can be set to use CBDMA or CPU for enqueue
> > operation and bind vhost device with specific CBDMA channel to
> > accelerate data copy.
> >
> > Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
> > ---
> >  examples/vhost/ioat.c      | 117
> +++++++++++++++++++++++++++++++++++++
> >  examples/vhost/main.c      |  37 +++++++++++-
> >  examples/vhost/main.h      |   2 +
> >  examples/vhost/meson.build |   4 +-
> >  4 files changed, 157 insertions(+), 3 deletions(-)  create mode
> > 100644 examples/vhost/ioat.c
> >
> > diff --git a/examples/vhost/ioat.c b/examples/vhost/ioat.c new file
> > mode 100644 index 000000000..c3158d3c3
> > --- /dev/null
> > +++ b/examples/vhost/ioat.c
> > @@ -0,0 +1,117 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright(c) 2010-2017 Intel Corporation  */
> > +
> > +#include <rte_vhost.h>
> > +#include <rte_rawdev.h>
> > +#include <rte_ioat_rawdev.h>
> > +#include <rte_pci.h>
> > +
> > +#include "main.h"
> > +
> > +#define MAX_VHOST_DEVICE 1024
> > +#define IOAT_RING_SIZE 4096
> > +
> > +struct dma_info {
> > +	struct rte_pci_addr addr;
> > +	uint16_t dev_id;
> > +	bool is_valid;
> > +};
> > +
> > +struct dma_for_vhost {
> > +	struct dma_info dmas[RTE_MAX_QUEUES_PER_PORT * 2];
> > +	uint16_t nr;
> > +};
> > +
> > +struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
> > +
> > +int
> > +open_ioat(const char *value)
> > +{
> > +	struct dma_for_vhost *dma_info = dma_bind;
> > +	char *input = strndup(value, strlen(value) + 1);
> > +	char *addrs = input;
> > +	char *ptrs[2];
> > +	char *start, *end, *substr;
> > +	int64_t vid, vring_id;
> > +	struct rte_ioat_rawdev_config config;
> > +	struct rte_rawdev_info info = { .dev_private = &config };
> > +	char name[32];
> > +	int dev_id;
> > +	int ret = 0;
> > +	uint16_t i = 0;
> > +	char *dma_arg[MAX_VHOST_DEVICE];
> > +	uint8_t args_nr;
> > +
> > +	while (isblank(*addrs))
> > +		addrs++;
> > +	if (*addrs == '\0') {
> > +		ret = -1;
> > +		goto out;
> > +	}
> > +
> > +	/* process DMA devices within bracket. */
> > +	addrs++;
> > +	substr = strtok(addrs, ";]");
> > +	if (!substr) {
> > +		ret = -1;
> > +		goto out;
> > +	}
> > +	args_nr = rte_strsplit(substr, strlen(substr),
> > +			dma_arg, MAX_VHOST_DEVICE, ',');
> > +	do {
> > +		char *arg_temp = dma_arg[i];
> > +		rte_strsplit(arg_temp, strlen(arg_temp), ptrs, 2, '@');
> > +
> > +		start = strstr(ptrs[0], "txd");
> > +		if (start == NULL) {
> > +			ret = -1;
> > +			goto out;
> > +		}
> > +
> > +		start += 3;
> > +		vid = strtol(start, &end, 0);
> > +		if (end == start) {
> > +			ret = -1;
> > +			goto out;
> > +		}
> > +
> > +		vring_id = 0 + VIRTIO_RXQ;
> > +		if (rte_pci_addr_parse(ptrs[1],
> > +				&(dma_info + vid)->dmas[vring_id].addr) < 0)
> {
> > +			ret = -1;
> > +			goto out;
> > +		}
> > +
> > +		rte_pci_device_name(&(dma_info + vid)-
> >dmas[vring_id].addr,
> > +				name, sizeof(name));
> > +		dev_id = rte_rawdev_get_dev_id(name);
> > +		if (dev_id == (uint16_t)(-ENODEV) ||
> > +		dev_id == (uint16_t)(-EINVAL)) {
> > +			ret = -1;
> > +			goto out;
> > +		}
> > +
> > +		if (rte_rawdev_info_get(dev_id, &info, sizeof(config)) < 0 ||
> > +		strstr(info.driver_name, "ioat") == NULL) {
> > +			ret = -1;
> > +			goto out;
> > +		}
> > +
> > +		(dma_info + vid)->dmas[vring_id].dev_id = dev_id;
> > +		(dma_info + vid)->dmas[vring_id].is_valid = true;
> > +		config.ring_size = IOAT_RING_SIZE;
> > +		config.hdls_disable = true;
> > +		if (rte_rawdev_configure(dev_id, &info, sizeof(config)) < 0) {
> > +			ret = -1;
> > +			goto out;
> > +		}
> > +		rte_rawdev_start(dev_id);
> > +
> > +		dma_info->nr++;
> > +		i++;
> > +	} while (i < args_nr);
> > +out:
> > +	free(input);
> > +	return ret;
> > +}
> > diff --git a/examples/vhost/main.c b/examples/vhost/main.c index
> > 959c0c283..4806419d6 100644
> > --- a/examples/vhost/main.c
> > +++ b/examples/vhost/main.c
> > @@ -95,6 +95,10 @@ static int client_mode;
> >
> >  static int builtin_net_driver;
> >
> > +static int async_vhost_driver;
> > +
> > +static char dma_type[MAX_LONG_OPT_SZ];
> > +
> >  /* Specify timeout (in useconds) between retries on RX. */  static
> > uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
> >  /* Specify the number of retries on RX. */ @@ -181,6 +185,15 @@
> > struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];
> >  				 / US_PER_S * BURST_TX_DRAIN_US)
> >  #define VLAN_HLEN       4
> >
> > +static inline int
> > +open_dma(const char *value)
> > +{
> > +	if (strncmp(dma_type, "IOAT", 4) == 0)
> 
> I think it is better to have it in lower case.

Sure, it will be changed in v5.

> 
> > +		return open_ioat(value);
> > +	else
> > +		return -1;
> > +}
> > +
> >  /*
> >   * Builds up the correct configuration for VMDQ VLAN pool map
> >   * according to the pool & queue limits.
> > @@ -446,7 +459,9 @@ us_vhost_usage(const char *prgname)
> >  	"		--socket-file: The path of the socket file.\n"
> >  	"		--tx-csum [0|1] disable/enable TX checksum
> offload.\n"
> >  	"		--tso [0|1] disable/enable TCP segment offload.\n"
> > -	"		--client register a vhost-user socket as client
> mode.\n",
> > +	"		--client register a vhost-user socket as client
> mode.\n"
> > +	"		--dma-type register dma type for your vhost async
> driver.\n"
> 
> I think you should mention possible DMA types, i.e. "ioat" for now.

it will be added in v5.

> 
> > +	"		--dmas register dma channel for specific vhost
> device.\n",
> >  	       prgname);
> >  }
> >
> > @@ -472,6 +487,8 @@ us_vhost_parse_args(int argc, char **argv)
> >  		{"tso", required_argument, NULL, 0},
> >  		{"client", no_argument, &client_mode, 1},
> >  		{"builtin-net-driver", no_argument, &builtin_net_driver, 1},
> > +		{"dma-type", required_argument, NULL, 0},
> > +		{"dmas", required_argument, NULL, 0},
> >  		{NULL, 0, 0, 0},
> >  	};
> >
> > @@ -614,6 +631,24 @@ us_vhost_parse_args(int argc, char **argv)
> >  				}
> >  			}
> >
> > +			if (!strncmp(long_option[option_index].name,
> > +						"dma-type",
> MAX_LONG_OPT_SZ)) {
> > +				strcpy(dma_type, optarg);
> > +			}
> > +
> > +			if (!strncmp(long_option[option_index].name,
> > +						"dmas",
> MAX_LONG_OPT_SZ)) {
> > +				if (open_dma(optarg) == -1) {
> > +					if (*optarg == -1) {
> > +						RTE_LOG(INFO,
> VHOST_CONFIG,
> > +							"Wrong DMA args\n");
> > +						us_vhost_usage(prgname);
> > +					}
> > +					return -1;
> > +				}
> > +				async_vhost_driver = 1;
> > +			}
> > +
> >  			break;
> >
> >  			/* Invalid option - print options. */ diff --git
> > a/examples/vhost/main.h b/examples/vhost/main.h index
> > 7cba0edbf..eac18824b 100644
> > --- a/examples/vhost/main.h
> > +++ b/examples/vhost/main.h
> > @@ -90,3 +90,5 @@ uint16_t vs_dequeue_pkts(struct vhost_dev *dev,
> uint16_t queue_id,
> >  			 struct rte_mempool *mbuf_pool,
> >  			 struct rte_mbuf **pkts, uint16_t count);  #endif /*
> _MAIN_H_ */
> > +
> > +int open_ioat(const char *value);
> > diff --git a/examples/vhost/meson.build b/examples/vhost/meson.build
> > index 872d51153..cb11edd78 100644
> > --- a/examples/vhost/meson.build
> > +++ b/examples/vhost/meson.build
> > @@ -9,8 +9,8 @@
> >  if not is_linux
> >  	build = false
> >  endif
> > -deps += 'vhost'
> > +deps += ['vhost', 'rawdev_ioat']
> 
> It is breaking build on other platforms than X86:
> https://travis-ci.com/github/ovsrobot/dpdk/builds/189405820
> 
> It should be done the other way, which is to enable ioat support in this
> example if rawdev_ioat is supported.

Agreed, it will be changed in v5.

Thanks,
Cheng

> 
> >  allow_experimental_apis = true
> >  sources = files(
> > -	'main.c', 'virtio_net.c'
> > +	'main.c', 'virtio_net.c', 'ioat.c'
> >  )
> >


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

* Re: [dpdk-dev] [PATCH v5 1/4] example/vhost: add async vhost args parsing function
  2020-10-15  4:54         ` [dpdk-dev] [PATCH v5 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
@ 2020-10-15 15:13           ` Maxime Coquelin
  0 siblings, 0 replies; 71+ messages in thread
From: Maxime Coquelin @ 2020-10-15 15:13 UTC (permalink / raw)
  To: Cheng Jiang, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu



On 10/15/20 6:54 AM, Cheng Jiang wrote:
> This patch is to add async vhost driver arguments parsing function
> for CBDMA channel, DMA initiation function and args description.
> The meson build file is changed to fix dependency problem. With
> these arguments vhost device can be set to use CBDMA or CPU for
> enqueue operation and bind vhost device with specific CBDMA channel
> to accelerate data copy.
> 
> Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
> ---
>  examples/vhost/ioat.c      | 117 +++++++++++++++++++++++++++++++++++++
>  examples/vhost/main.c      |  43 +++++++++++++-
>  examples/vhost/main.h      |   2 +
>  examples/vhost/meson.build |   5 ++
>  4 files changed, 166 insertions(+), 1 deletion(-)
>  create mode 100644 examples/vhost/ioat.c
> 
> diff --git a/examples/vhost/ioat.c b/examples/vhost/ioat.c
> new file mode 100644
> index 000000000..c3158d3c3
> --- /dev/null
> +++ b/examples/vhost/ioat.c
> @@ -0,0 +1,117 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2010-2017 Intel Corporation
> + */
> +
> +#include <rte_vhost.h>
> +#include <rte_rawdev.h>
> +#include <rte_ioat_rawdev.h>
> +#include <rte_pci.h>
> +
> +#include "main.h"
> +
> +#define MAX_VHOST_DEVICE 1024
> +#define IOAT_RING_SIZE 4096
> +
> +struct dma_info {
> +	struct rte_pci_addr addr;
> +	uint16_t dev_id;
> +	bool is_valid;
> +};
> +
> +struct dma_for_vhost {
> +	struct dma_info dmas[RTE_MAX_QUEUES_PER_PORT * 2];
> +	uint16_t nr;
> +};
> +
> +struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
> +
> +int
> +open_ioat(const char *value)
> +{
> +	struct dma_for_vhost *dma_info = dma_bind;
> +	char *input = strndup(value, strlen(value) + 1);
> +	char *addrs = input;
> +	char *ptrs[2];
> +	char *start, *end, *substr;
> +	int64_t vid, vring_id;
> +	struct rte_ioat_rawdev_config config;
> +	struct rte_rawdev_info info = { .dev_private = &config };
> +	char name[32];
> +	int dev_id;
> +	int ret = 0;
> +	uint16_t i = 0;
> +	char *dma_arg[MAX_VHOST_DEVICE];
> +	uint8_t args_nr;
> +
> +	while (isblank(*addrs))
> +		addrs++;
> +	if (*addrs == '\0') {
> +		ret = -1;
> +		goto out;
> +	}
> +
> +	/* process DMA devices within bracket. */
> +	addrs++;
> +	substr = strtok(addrs, ";]");
> +	if (!substr) {
> +		ret = -1;
> +		goto out;
> +	}
> +	args_nr = rte_strsplit(substr, strlen(substr),
> +			dma_arg, MAX_VHOST_DEVICE, ',');
> +	do {
> +		char *arg_temp = dma_arg[i];
> +		rte_strsplit(arg_temp, strlen(arg_temp), ptrs, 2, '@');
> +
> +		start = strstr(ptrs[0], "txd");
> +		if (start == NULL) {
> +			ret = -1;
> +			goto out;
> +		}
> +
> +		start += 3;
> +		vid = strtol(start, &end, 0);
> +		if (end == start) {
> +			ret = -1;
> +			goto out;
> +		}
> +
> +		vring_id = 0 + VIRTIO_RXQ;
> +		if (rte_pci_addr_parse(ptrs[1],
> +				&(dma_info + vid)->dmas[vring_id].addr) < 0) {
> +			ret = -1;
> +			goto out;
> +		}
> +
> +		rte_pci_device_name(&(dma_info + vid)->dmas[vring_id].addr,
> +				name, sizeof(name));
> +		dev_id = rte_rawdev_get_dev_id(name);
> +		if (dev_id == (uint16_t)(-ENODEV) ||
> +		dev_id == (uint16_t)(-EINVAL)) {
> +			ret = -1;
> +			goto out;
> +		}
> +
> +		if (rte_rawdev_info_get(dev_id, &info, sizeof(config)) < 0 ||
> +		strstr(info.driver_name, "ioat") == NULL) {
> +			ret = -1;
> +			goto out;
> +		}
> +
> +		(dma_info + vid)->dmas[vring_id].dev_id = dev_id;
> +		(dma_info + vid)->dmas[vring_id].is_valid = true;
> +		config.ring_size = IOAT_RING_SIZE;
> +		config.hdls_disable = true;
> +		if (rte_rawdev_configure(dev_id, &info, sizeof(config)) < 0) {
> +			ret = -1;
> +			goto out;
> +		}
> +		rte_rawdev_start(dev_id);
> +
> +		dma_info->nr++;
> +		i++;
> +	} while (i < args_nr);
> +out:
> +	free(input);
> +	return ret;
> +}
> diff --git a/examples/vhost/main.c b/examples/vhost/main.c
> index 959c0c283..ab1b24409 100644
> --- a/examples/vhost/main.c
> +++ b/examples/vhost/main.c
> @@ -95,6 +95,10 @@ static int client_mode;
>  
>  static int builtin_net_driver;
>  
> +static int async_vhost_driver;
> +
> +static char dma_type[MAX_LONG_OPT_SZ];
> +
>  /* Specify timeout (in useconds) between retries on RX. */
>  static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
>  /* Specify the number of retries on RX. */
> @@ -181,6 +185,21 @@ struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];
>  				 / US_PER_S * BURST_TX_DRAIN_US)
>  #define VLAN_HLEN       4
>  
> +static inline int
> +open_dma(const char *value)
> +{
> +#ifdef RTE_ARCH_X86
> +	if (strncmp(dma_type, "ioat", 4) == 0)
> +		return open_ioat(value);
> +	else
> +		return -1;
> +#else
> +	RTE_LOG(ERR, VHOST_PORT,
> +			"Error during opening ioat info: %s\n", value);
> +	return -1;
> +#endif

It would be cleaner to have something like:

static inline int
open_dma(const char *value)
{
	if (strncmp(dma_type, "ioat", 4) == 0)
		return open_ioat(value);

	return -1;
}

Then in main.h:

#ifdef RTE_ARCH_X86
int open_ioat(const char *value);
#else
static int open_ioat(const char *value)
{
	return -1;
}
#endif

> +}
> +
>  /*
>   * Builds up the correct configuration for VMDQ VLAN pool map
>   * according to the pool & queue limits.
> @@ -446,7 +465,9 @@ us_vhost_usage(const char *prgname)
>  	"		--socket-file: The path of the socket file.\n"
>  	"		--tx-csum [0|1] disable/enable TX checksum offload.\n"
>  	"		--tso [0|1] disable/enable TCP segment offload.\n"
> -	"		--client register a vhost-user socket as client mode.\n",
> +	"		--client register a vhost-user socket as client mode.\n"
> +	"		--dma-type register dma type for your vhost async driver. For example \"ioat\" for now.\n"
> +	"		--dmas register dma channel for specific vhost device.\n",
>  	       prgname);
>  }
>  
> @@ -472,6 +493,8 @@ us_vhost_parse_args(int argc, char **argv)
>  		{"tso", required_argument, NULL, 0},
>  		{"client", no_argument, &client_mode, 1},
>  		{"builtin-net-driver", no_argument, &builtin_net_driver, 1},
> +		{"dma-type", required_argument, NULL, 0},
> +		{"dmas", required_argument, NULL, 0},
>  		{NULL, 0, 0, 0},
>  	};
>  
> @@ -614,6 +637,24 @@ us_vhost_parse_args(int argc, char **argv)
>  				}
>  			}
>  
> +			if (!strncmp(long_option[option_index].name,
> +						"dma-type", MAX_LONG_OPT_SZ)) {
> +				strcpy(dma_type, optarg);
> +			}
> +
> +			if (!strncmp(long_option[option_index].name,
> +						"dmas", MAX_LONG_OPT_SZ)) {
> +				if (open_dma(optarg) == -1) {
> +					if (*optarg == -1) {
> +						RTE_LOG(INFO, VHOST_CONFIG,
> +							"Wrong DMA args\n");
> +						us_vhost_usage(prgname);
> +					}
> +					return -1;
> +				}
> +				async_vhost_driver = 1;
> +			}
> +
>  			break;
>  
>  			/* Invalid option - print options. */
> diff --git a/examples/vhost/main.h b/examples/vhost/main.h
> index 7cba0edbf..eac18824b 100644
> --- a/examples/vhost/main.h
> +++ b/examples/vhost/main.h
> @@ -90,3 +90,5 @@ uint16_t vs_dequeue_pkts(struct vhost_dev *dev, uint16_t queue_id,
>  			 struct rte_mempool *mbuf_pool,
>  			 struct rte_mbuf **pkts, uint16_t count);
>  #endif /* _MAIN_H_ */
> +
> +int open_ioat(const char *value);

It should be placed before the #endif /* _MAIN_H_ */

> diff --git a/examples/vhost/meson.build b/examples/vhost/meson.build
> index 872d51153..2a03f9779 100644
> --- a/examples/vhost/meson.build
> +++ b/examples/vhost/meson.build
> @@ -14,3 +14,8 @@ allow_experimental_apis = true
>  sources = files(
>  	'main.c', 'virtio_net.c'
>  )
> +
> +if dpdk_conf.has('RTE_ARCH_X86')
> +	deps += 'rawdev_ioat'
> +	sources += files('ioat.c')
> +endif
> 


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

* [dpdk-dev] [PATCH v6 0/4] add async data path in vhost sample
  2020-10-15  4:54       ` [dpdk-dev] [PATCH v5 0/4] add async data path in " Cheng Jiang
                           ` (3 preceding siblings ...)
  2020-10-15  4:54         ` [dpdk-dev] [PATCH v5 4/4] doc: update release notes for vhost sample Cheng Jiang
@ 2020-10-16  4:29         ` Cheng Jiang
  2020-10-16  4:29           ` [dpdk-dev] [PATCH v6 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
                             ` (4 more replies)
  4 siblings, 5 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-16  4:29 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

This patch set makes vhost-vswitch be able to use vhost async APIs
for enqueue operations. Demonstrated how the application
leverage IOAT DMA channel with vhost async APIs.

We introduce two parameters to enable DMA acceleration for Tx
operations of queues:
-dma_type This parameter is used to specify DMA type for async
vhost-user net driver.
-dmas This parameter is used to specify the assigned DMA device of a
vhost device and enable async vhost data path.

---
v6:
 * Cleaned code and rebased for latest code

v5:
 * Improved meson build file and fixed dependency problem

v4:
 * Code rebased for latest IOAT driver

v3:
 * Fixed a coding style problem

v2:
 * Changed meson build file to fix dependency problem
 * Added parameter description in usage function
 * Optimized parameter settings and parsing function
 * Optimized abstraction, moved some code to ioat.c

Cheng Jiang (4):
  example/vhost: add async vhost args parsing function
  example/vhost: add support for vhost async data path
  doc: update vhost sample doc for vhost async data path
  doc: update release notes for vhost sample

 doc/guides/rel_notes/release_20_11.rst |   6 +
 doc/guides/sample_app_ug/vhost.rst     |  11 ++
 examples/vhost/ioat.c                  | 214 +++++++++++++++++++++++++
 examples/vhost/main.c                  |  94 ++++++++++-
 examples/vhost/main.h                  |  26 +++
 examples/vhost/meson.build             |   5 +
 6 files changed, 354 insertions(+), 2 deletions(-)
 create mode 100644 examples/vhost/ioat.c

--
2.27.0


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

* [dpdk-dev] [PATCH v6 1/4] example/vhost: add async vhost args parsing function
  2020-10-16  4:29         ` [dpdk-dev] [PATCH v6 0/4] add async data path in " Cheng Jiang
@ 2020-10-16  4:29           ` Cheng Jiang
  2020-10-16  4:29           ` [dpdk-dev] [PATCH v6 2/4] example/vhost: add support for vhost async data path Cheng Jiang
                             ` (3 subsequent siblings)
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-16  4:29 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

This patch is to add async vhost driver arguments parsing function
for CBDMA channel, DMA initiation function and args description.
The meson build file is changed to fix dependency problem. With
these arguments vhost device can be set to use CBDMA or CPU for
enqueue operation and bind vhost device with specific CBDMA channel
to accelerate data copy.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 examples/vhost/ioat.c      | 117 +++++++++++++++++++++++++++++++++++++
 examples/vhost/main.c      |  37 +++++++++++-
 examples/vhost/main.h      |  14 +++++
 examples/vhost/meson.build |   5 ++
 4 files changed, 172 insertions(+), 1 deletion(-)
 create mode 100644 examples/vhost/ioat.c

diff --git a/examples/vhost/ioat.c b/examples/vhost/ioat.c
new file mode 100644
index 000000000..c3158d3c3
--- /dev/null
+++ b/examples/vhost/ioat.c
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2017 Intel Corporation
+ */
+
+#include <rte_vhost.h>
+#include <rte_rawdev.h>
+#include <rte_ioat_rawdev.h>
+#include <rte_pci.h>
+
+#include "main.h"
+
+#define MAX_VHOST_DEVICE 1024
+#define IOAT_RING_SIZE 4096
+
+struct dma_info {
+	struct rte_pci_addr addr;
+	uint16_t dev_id;
+	bool is_valid;
+};
+
+struct dma_for_vhost {
+	struct dma_info dmas[RTE_MAX_QUEUES_PER_PORT * 2];
+	uint16_t nr;
+};
+
+struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
+
+int
+open_ioat(const char *value)
+{
+	struct dma_for_vhost *dma_info = dma_bind;
+	char *input = strndup(value, strlen(value) + 1);
+	char *addrs = input;
+	char *ptrs[2];
+	char *start, *end, *substr;
+	int64_t vid, vring_id;
+	struct rte_ioat_rawdev_config config;
+	struct rte_rawdev_info info = { .dev_private = &config };
+	char name[32];
+	int dev_id;
+	int ret = 0;
+	uint16_t i = 0;
+	char *dma_arg[MAX_VHOST_DEVICE];
+	uint8_t args_nr;
+
+	while (isblank(*addrs))
+		addrs++;
+	if (*addrs == '\0') {
+		ret = -1;
+		goto out;
+	}
+
+	/* process DMA devices within bracket. */
+	addrs++;
+	substr = strtok(addrs, ";]");
+	if (!substr) {
+		ret = -1;
+		goto out;
+	}
+	args_nr = rte_strsplit(substr, strlen(substr),
+			dma_arg, MAX_VHOST_DEVICE, ',');
+	do {
+		char *arg_temp = dma_arg[i];
+		rte_strsplit(arg_temp, strlen(arg_temp), ptrs, 2, '@');
+
+		start = strstr(ptrs[0], "txd");
+		if (start == NULL) {
+			ret = -1;
+			goto out;
+		}
+
+		start += 3;
+		vid = strtol(start, &end, 0);
+		if (end == start) {
+			ret = -1;
+			goto out;
+		}
+
+		vring_id = 0 + VIRTIO_RXQ;
+		if (rte_pci_addr_parse(ptrs[1],
+				&(dma_info + vid)->dmas[vring_id].addr) < 0) {
+			ret = -1;
+			goto out;
+		}
+
+		rte_pci_device_name(&(dma_info + vid)->dmas[vring_id].addr,
+				name, sizeof(name));
+		dev_id = rte_rawdev_get_dev_id(name);
+		if (dev_id == (uint16_t)(-ENODEV) ||
+		dev_id == (uint16_t)(-EINVAL)) {
+			ret = -1;
+			goto out;
+		}
+
+		if (rte_rawdev_info_get(dev_id, &info, sizeof(config)) < 0 ||
+		strstr(info.driver_name, "ioat") == NULL) {
+			ret = -1;
+			goto out;
+		}
+
+		(dma_info + vid)->dmas[vring_id].dev_id = dev_id;
+		(dma_info + vid)->dmas[vring_id].is_valid = true;
+		config.ring_size = IOAT_RING_SIZE;
+		config.hdls_disable = true;
+		if (rte_rawdev_configure(dev_id, &info, sizeof(config)) < 0) {
+			ret = -1;
+			goto out;
+		}
+		rte_rawdev_start(dev_id);
+
+		dma_info->nr++;
+		i++;
+	} while (i < args_nr);
+out:
+	free(input);
+	return ret;
+}
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 959c0c283..76f5d76cb 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -95,6 +95,10 @@ static int client_mode;
 
 static int builtin_net_driver;
 
+static int async_vhost_driver;
+
+static char dma_type[MAX_LONG_OPT_SZ];
+
 /* Specify timeout (in useconds) between retries on RX. */
 static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
 /* Specify the number of retries on RX. */
@@ -181,6 +185,15 @@ struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];
 				 / US_PER_S * BURST_TX_DRAIN_US)
 #define VLAN_HLEN       4
 
+static inline int
+open_dma(const char *value)
+{
+	if (strncmp(dma_type, "ioat", 4) == 0)
+		return open_ioat(value);
+
+	return -1;
+}
+
 /*
  * Builds up the correct configuration for VMDQ VLAN pool map
  * according to the pool & queue limits.
@@ -446,7 +459,9 @@ us_vhost_usage(const char *prgname)
 	"		--socket-file: The path of the socket file.\n"
 	"		--tx-csum [0|1] disable/enable TX checksum offload.\n"
 	"		--tso [0|1] disable/enable TCP segment offload.\n"
-	"		--client register a vhost-user socket as client mode.\n",
+	"		--client register a vhost-user socket as client mode.\n"
+	"		--dma-type register dma type for your vhost async driver. For example \"ioat\" for now.\n"
+	"		--dmas register dma channel for specific vhost device.\n",
 	       prgname);
 }
 
@@ -472,6 +487,8 @@ us_vhost_parse_args(int argc, char **argv)
 		{"tso", required_argument, NULL, 0},
 		{"client", no_argument, &client_mode, 1},
 		{"builtin-net-driver", no_argument, &builtin_net_driver, 1},
+		{"dma-type", required_argument, NULL, 0},
+		{"dmas", required_argument, NULL, 0},
 		{NULL, 0, 0, 0},
 	};
 
@@ -614,6 +631,24 @@ us_vhost_parse_args(int argc, char **argv)
 				}
 			}
 
+			if (!strncmp(long_option[option_index].name,
+						"dma-type", MAX_LONG_OPT_SZ)) {
+				strcpy(dma_type, optarg);
+			}
+
+			if (!strncmp(long_option[option_index].name,
+						"dmas", MAX_LONG_OPT_SZ)) {
+				if (open_dma(optarg) == -1) {
+					if (*optarg == -1) {
+						RTE_LOG(INFO, VHOST_CONFIG,
+							"Wrong DMA args\n");
+						us_vhost_usage(prgname);
+					}
+					return -1;
+				}
+				async_vhost_driver = 1;
+			}
+
 			break;
 
 			/* Invalid option - print options. */
diff --git a/examples/vhost/main.h b/examples/vhost/main.h
index 7cba0edbf..fe83d255b 100644
--- a/examples/vhost/main.h
+++ b/examples/vhost/main.h
@@ -89,4 +89,18 @@ uint16_t vs_enqueue_pkts(struct vhost_dev *dev, uint16_t queue_id,
 uint16_t vs_dequeue_pkts(struct vhost_dev *dev, uint16_t queue_id,
 			 struct rte_mempool *mbuf_pool,
 			 struct rte_mbuf **pkts, uint16_t count);
+
+#ifdef RTE_ARCH_X86
+
+int open_ioat(const char *value);
+
+#else
+
+static int open_ioat(const char *value __rte_unused)
+{
+	return -1;
+}
+
+#endif
+
 #endif /* _MAIN_H_ */
diff --git a/examples/vhost/meson.build b/examples/vhost/meson.build
index 872d51153..2a03f9779 100644
--- a/examples/vhost/meson.build
+++ b/examples/vhost/meson.build
@@ -14,3 +14,8 @@ allow_experimental_apis = true
 sources = files(
 	'main.c', 'virtio_net.c'
 )
+
+if dpdk_conf.has('RTE_ARCH_X86')
+	deps += 'rawdev_ioat'
+	sources += files('ioat.c')
+endif
-- 
2.27.0


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

* [dpdk-dev] [PATCH v6 2/4] example/vhost: add support for vhost async data path
  2020-10-16  4:29         ` [dpdk-dev] [PATCH v6 0/4] add async data path in " Cheng Jiang
  2020-10-16  4:29           ` [dpdk-dev] [PATCH v6 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
@ 2020-10-16  4:29           ` Cheng Jiang
  2020-10-16  4:29           ` [dpdk-dev] [PATCH v6 3/4] doc: update vhost sample doc " Cheng Jiang
                             ` (2 subsequent siblings)
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-16  4:29 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

This patch is to implement vhost DMA operation callbacks for CBDMA
PMD and add vhost async data-path in vhost sample. With providing
callback implementation for CBDMA, vswitch can leverage IOAT to
accelerate vhost async data-path.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 examples/vhost/ioat.c | 97 +++++++++++++++++++++++++++++++++++++++++++
 examples/vhost/main.c | 57 ++++++++++++++++++++++++-
 examples/vhost/main.h | 12 ++++++
 3 files changed, 165 insertions(+), 1 deletion(-)

diff --git a/examples/vhost/ioat.c b/examples/vhost/ioat.c
index c3158d3c3..e764b2634 100644
--- a/examples/vhost/ioat.c
+++ b/examples/vhost/ioat.c
@@ -6,11 +6,13 @@
 #include <rte_rawdev.h>
 #include <rte_ioat_rawdev.h>
 #include <rte_pci.h>
+#include <sys/uio.h>
 
 #include "main.h"
 
 #define MAX_VHOST_DEVICE 1024
 #define IOAT_RING_SIZE 4096
+#define MAX_ENQUEUED_SIZE 256
 
 struct dma_info {
 	struct rte_pci_addr addr;
@@ -25,6 +27,15 @@ struct dma_for_vhost {
 
 struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
 
+struct packet_tracker {
+	unsigned short size_track[MAX_ENQUEUED_SIZE];
+	unsigned short next_read;
+	unsigned short next_write;
+	unsigned short last_remain;
+};
+
+struct packet_tracker cb_tracker[MAX_VHOST_DEVICE];
+
 int
 open_ioat(const char *value)
 {
@@ -115,3 +126,89 @@ open_ioat(const char *value)
 	free(input);
 	return ret;
 }
+
+uint32_t
+ioat_transfer_data_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_desc *descs,
+		struct rte_vhost_async_status *opaque_data, uint16_t count)
+{
+	int ret;
+	uint32_t i_desc;
+	int dev_id = dma_bind[vid].dmas[queue_id * 2 + VIRTIO_RXQ].dev_id;
+	struct rte_vhost_iov_iter *src = NULL;
+	struct rte_vhost_iov_iter *dst = NULL;
+	unsigned long i_seg;
+	unsigned short mask = MAX_ENQUEUED_SIZE - 1;
+	unsigned short write = cb_tracker[dev_id].next_write;
+
+	if (likely(!opaque_data)) {
+		for (i_desc = 0; i_desc < count; i_desc++) {
+			src = descs[i_desc].src;
+			dst = descs[i_desc].dst;
+			i_seg = 0;
+			while (i_seg < src->nr_segs) {
+				ret = rte_ioat_enqueue_copy(dev_id,
+					(uintptr_t)(src->iov[i_seg].iov_base)
+						+ src->offset,
+					(uintptr_t)(dst->iov[i_seg].iov_base)
+						+ dst->offset,
+					src->iov[i_seg].iov_len,
+					0,
+					0);
+				if (ret != 1)
+					break;
+				i_seg++;
+			}
+			write &= mask;
+			cb_tracker[dev_id].size_track[write] = i_seg;
+			write++;
+		}
+	} else {
+		/* Opaque data is not supported */
+		return -1;
+	}
+	/* ring the doorbell */
+	rte_ioat_perform_ops(dev_id);
+	cb_tracker[dev_id].next_write = write;
+	return i_desc;
+}
+
+uint32_t
+ioat_check_completed_copies_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_status *opaque_data,
+		uint16_t max_packets)
+{
+	if (!opaque_data) {
+		uintptr_t dump[255];
+		unsigned short n_seg;
+		unsigned short read, write;
+		unsigned short nb_packet = 0;
+		unsigned short mask = MAX_ENQUEUED_SIZE - 1;
+		unsigned short i;
+		int dev_id = dma_bind[vid].dmas[queue_id * 2
+				+ VIRTIO_RXQ].dev_id;
+		n_seg = rte_ioat_completed_ops(dev_id, 255, dump, dump);
+		n_seg += cb_tracker[dev_id].last_remain;
+		if (!n_seg)
+			return 0;
+		read = cb_tracker[dev_id].next_read;
+		write = cb_tracker[dev_id].next_write;
+		for (i = 0; i < max_packets; i++) {
+			read &= mask;
+			if (read == write)
+				break;
+			if (n_seg >= cb_tracker[dev_id].size_track[read]) {
+				n_seg -= cb_tracker[dev_id].size_track[read];
+				read++;
+				nb_packet++;
+			} else {
+				break;
+			}
+		}
+		cb_tracker[dev_id].next_read = read;
+		cb_tracker[dev_id].last_remain = n_seg;
+		return nb_packet;
+	}
+	/* Opaque data is not supported */
+	return -1;
+}
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 76f5d76cb..2469fcf21 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -804,9 +804,22 @@ virtio_xmit(struct vhost_dev *dst_vdev, struct vhost_dev *src_vdev,
 	    struct rte_mbuf *m)
 {
 	uint16_t ret;
+	struct rte_mbuf *m_cpl[1];
 
 	if (builtin_net_driver) {
 		ret = vs_enqueue_pkts(dst_vdev, VIRTIO_RXQ, &m, 1);
+	} else if (async_vhost_driver) {
+		ret = rte_vhost_submit_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ,
+						&m, 1);
+
+		if (likely(ret))
+			dst_vdev->nr_async_pkts++;
+
+		while (likely(dst_vdev->nr_async_pkts)) {
+			if (rte_vhost_poll_enqueue_completed(dst_vdev->vid,
+					VIRTIO_RXQ, m_cpl, 1))
+				dst_vdev->nr_async_pkts--;
+		}
 	} else {
 		ret = rte_vhost_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ, &m, 1);
 	}
@@ -1055,6 +1068,19 @@ drain_mbuf_table(struct mbuf_table *tx_q)
 	}
 }
 
+static __rte_always_inline void
+complete_async_pkts(struct vhost_dev *vdev, uint16_t qid)
+{
+	struct rte_mbuf *p_cpl[MAX_PKT_BURST];
+	uint16_t complete_count;
+
+	complete_count = rte_vhost_poll_enqueue_completed(vdev->vid,
+						qid, p_cpl, MAX_PKT_BURST);
+	vdev->nr_async_pkts -= complete_count;
+	if (complete_count)
+		free_pkts(p_cpl, complete_count);
+}
+
 static __rte_always_inline void
 drain_eth_rx(struct vhost_dev *vdev)
 {
@@ -1063,6 +1089,10 @@ drain_eth_rx(struct vhost_dev *vdev)
 
 	rx_count = rte_eth_rx_burst(ports[0], vdev->vmdq_rx_q,
 				    pkts, MAX_PKT_BURST);
+
+	while (likely(vdev->nr_async_pkts))
+		complete_async_pkts(vdev, VIRTIO_RXQ);
+
 	if (!rx_count)
 		return;
 
@@ -1087,16 +1117,22 @@ drain_eth_rx(struct vhost_dev *vdev)
 	if (builtin_net_driver) {
 		enqueue_count = vs_enqueue_pkts(vdev, VIRTIO_RXQ,
 						pkts, rx_count);
+	} else if (async_vhost_driver) {
+		enqueue_count = rte_vhost_submit_enqueue_burst(vdev->vid,
+					VIRTIO_RXQ, pkts, rx_count);
+		vdev->nr_async_pkts += enqueue_count;
 	} else {
 		enqueue_count = rte_vhost_enqueue_burst(vdev->vid, VIRTIO_RXQ,
 						pkts, rx_count);
 	}
+
 	if (enable_stats) {
 		rte_atomic64_add(&vdev->stats.rx_total_atomic, rx_count);
 		rte_atomic64_add(&vdev->stats.rx_atomic, enqueue_count);
 	}
 
-	free_pkts(pkts, rx_count);
+	if (!async_vhost_driver)
+		free_pkts(pkts, rx_count);
 }
 
 static __rte_always_inline void
@@ -1243,6 +1279,9 @@ destroy_device(int vid)
 		"(%d) device has been removed from data core\n",
 		vdev->vid);
 
+	if (async_vhost_driver)
+		rte_vhost_async_channel_unregister(vid, VIRTIO_RXQ);
+
 	rte_free(vdev);
 }
 
@@ -1257,6 +1296,12 @@ new_device(int vid)
 	uint32_t device_num_min = num_devices;
 	struct vhost_dev *vdev;
 
+	struct rte_vhost_async_channel_ops channel_ops = {
+		.transfer_data = ioat_transfer_data_cb,
+		.check_completed_copies = ioat_check_completed_copies_cb
+	};
+	struct rte_vhost_async_features f;
+
 	vdev = rte_zmalloc("vhost device", sizeof(*vdev), RTE_CACHE_LINE_SIZE);
 	if (vdev == NULL) {
 		RTE_LOG(INFO, VHOST_DATA,
@@ -1297,6 +1342,13 @@ new_device(int vid)
 		"(%d) device has been added to data core %d\n",
 		vid, vdev->coreid);
 
+	if (async_vhost_driver) {
+		f.async_inorder = 1;
+		f.async_threshold = 256;
+		return rte_vhost_async_channel_register(vid, VIRTIO_RXQ,
+			f.intval, &channel_ops);
+	}
+
 	return 0;
 }
 
@@ -1535,6 +1587,9 @@ main(int argc, char *argv[])
 	/* Register vhost user driver to handle vhost messages. */
 	for (i = 0; i < nb_sockets; i++) {
 		char *file = socket_files + i * PATH_MAX;
+		if (async_vhost_driver)
+			flags = flags | RTE_VHOST_USER_ASYNC_COPY;
+
 		ret = rte_vhost_driver_register(file, flags);
 		if (ret != 0) {
 			unregister_drivers(i);
diff --git a/examples/vhost/main.h b/examples/vhost/main.h
index fe83d255b..5a628473e 100644
--- a/examples/vhost/main.h
+++ b/examples/vhost/main.h
@@ -8,6 +8,7 @@
 #include <sys/queue.h>
 
 #include <rte_ether.h>
+#include <rte_vhost_async.h>
 
 /* Macros for printing using RTE_LOG */
 #define RTE_LOGTYPE_VHOST_CONFIG RTE_LOGTYPE_USER1
@@ -51,6 +52,7 @@ struct vhost_dev {
 	uint64_t features;
 	size_t hdr_len;
 	uint16_t nr_vrings;
+	uint16_t nr_async_pkts;
 	struct rte_vhost_memory *mem;
 	struct device_statistics stats;
 	TAILQ_ENTRY(vhost_dev) global_vdev_entry;
@@ -103,4 +105,14 @@ static int open_ioat(const char *value __rte_unused)
 
 #endif
 
+uint32_t
+ioat_transfer_data_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_desc *descs,
+		struct rte_vhost_async_status *opaque_data, uint16_t count);
+
+uint32_t
+ioat_check_completed_copies_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_status *opaque_data,
+		uint16_t max_packets);
+
 #endif /* _MAIN_H_ */
-- 
2.27.0


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

* [dpdk-dev] [PATCH v6 3/4] doc: update vhost sample doc for vhost async data path
  2020-10-16  4:29         ` [dpdk-dev] [PATCH v6 0/4] add async data path in " Cheng Jiang
  2020-10-16  4:29           ` [dpdk-dev] [PATCH v6 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
  2020-10-16  4:29           ` [dpdk-dev] [PATCH v6 2/4] example/vhost: add support for vhost async data path Cheng Jiang
@ 2020-10-16  4:29           ` Cheng Jiang
  2020-10-16  4:29           ` [dpdk-dev] [PATCH v6 4/4] doc: update release notes for vhost sample Cheng Jiang
  2020-10-20 11:20           ` [dpdk-dev] [PATCH v7 0/4] add async data path in " Cheng Jiang
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-16  4:29 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

Add vhost async driver arguments information for vhost async data
path in vhost sample application.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 doc/guides/sample_app_ug/vhost.rst | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/doc/guides/sample_app_ug/vhost.rst b/doc/guides/sample_app_ug/vhost.rst
index b7ed4f8bd..0f4f70945 100644
--- a/doc/guides/sample_app_ug/vhost.rst
+++ b/doc/guides/sample_app_ug/vhost.rst
@@ -162,6 +162,17 @@ enabled and cannot be disabled.
 A very simple vhost-user net driver which demonstrates how to use the generic
 vhost APIs will be used when this option is given. It is disabled by default.
 
+**--dma-type**
+This parameter is used to specify DMA type for async vhost-user net driver which
+demonstrates how to use the async vhost APIs. It's used in combination with dmas.
+
+**--dmas**
+This parameter is used to specify the assigned DMA device of a vhost device.
+Async vhost-user net driver will be used if --dmas is set. For example
+--dmas [txd0@00:04.0,txd1@00:04.1] means use DMA channel 00:04.0 for vhost
+device 0 enqueue operation and use DMA channel 00:04.1 for vhost device 1
+enqueue operation.
+
 Common Issues
 -------------
 
-- 
2.27.0


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

* [dpdk-dev] [PATCH v6 4/4] doc: update release notes for vhost sample
  2020-10-16  4:29         ` [dpdk-dev] [PATCH v6 0/4] add async data path in " Cheng Jiang
                             ` (2 preceding siblings ...)
  2020-10-16  4:29           ` [dpdk-dev] [PATCH v6 3/4] doc: update vhost sample doc " Cheng Jiang
@ 2020-10-16  4:29           ` Cheng Jiang
  2020-10-19  5:49             ` Jiang, Cheng1
  2020-10-20 11:20           ` [dpdk-dev] [PATCH v7 0/4] add async data path in " Cheng Jiang
  4 siblings, 1 reply; 71+ messages in thread
From: Cheng Jiang @ 2020-10-16  4:29 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia, zhihong.wang; +Cc: dev, patrick.fu, Cheng Jiang

Add release notes for vhost async data path support in vhost sample.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 doc/guides/rel_notes/release_20_11.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst
index f8686a50d..812ca8834 100644
--- a/doc/guides/rel_notes/release_20_11.rst
+++ b/doc/guides/rel_notes/release_20_11.rst
@@ -214,6 +214,12 @@ New Features
   * Added new ``RTE_ACL_CLASSIFY_AVX512X32`` vector implementation,
     which can process up to 32 flows in parallel. Requires AVX512 support.
 
+* **Updated vhost sample application.**
+
+  Added vhost asynchronous APIs support, which demonstrated how the application
+  leverage IOAT DMA channel with vhost asynchronous APIs.
+  See the :doc:`../sample_app_ug/vhost` for more details.
+
 
 Removed Items
 -------------
-- 
2.27.0


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

* Re: [dpdk-dev] [PATCH v6 4/4] doc: update release notes for vhost sample
  2020-10-16  4:29           ` [dpdk-dev] [PATCH v6 4/4] doc: update release notes for vhost sample Cheng Jiang
@ 2020-10-19  5:49             ` Jiang, Cheng1
  0 siblings, 0 replies; 71+ messages in thread
From: Jiang, Cheng1 @ 2020-10-19  5:49 UTC (permalink / raw)
  To: maxime.coquelin, Xia, Chenbo, Wang, Zhihong
  Cc: dev, Fu, Patrick, Yang, YvonneX

Hi Maxime,

I noticed there are two errors reported in the CI system. And we think it may have nothing to do with us.
Just for your information.

Thanks,
Cheng

> -----Original Message-----
> From: Jiang, Cheng1 <cheng1.jiang@intel.com>
> Sent: Friday, October 16, 2020 12:29 PM
> To: maxime.coquelin@redhat.com; Xia, Chenbo <chenbo.xia@intel.com>;
> Wang, Zhihong <zhihong.wang@intel.com>
> Cc: dev@dpdk.org; Fu, Patrick <patrick.fu@intel.com>; Jiang, Cheng1
> <cheng1.jiang@intel.com>
> Subject: [PATCH v6 4/4] doc: update release notes for vhost sample
> 
> Add release notes for vhost async data path support in vhost sample.
> 
> Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
> ---
>  doc/guides/rel_notes/release_20_11.rst | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/doc/guides/rel_notes/release_20_11.rst
> b/doc/guides/rel_notes/release_20_11.rst
> index f8686a50d..812ca8834 100644
> --- a/doc/guides/rel_notes/release_20_11.rst
> +++ b/doc/guides/rel_notes/release_20_11.rst
> @@ -214,6 +214,12 @@ New Features
>    * Added new ``RTE_ACL_CLASSIFY_AVX512X32`` vector implementation,
>      which can process up to 32 flows in parallel. Requires AVX512 support.
> 
> +* **Updated vhost sample application.**
> +
> +  Added vhost asynchronous APIs support, which demonstrated how the
> + application  leverage IOAT DMA channel with vhost asynchronous APIs.
> +  See the :doc:`../sample_app_ug/vhost` for more details.
> +
> 
>  Removed Items
>  -------------
> --
> 2.27.0


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

* [dpdk-dev] [PATCH v7 0/4] add async data path in vhost sample
  2020-10-16  4:29         ` [dpdk-dev] [PATCH v6 0/4] add async data path in " Cheng Jiang
                             ` (3 preceding siblings ...)
  2020-10-16  4:29           ` [dpdk-dev] [PATCH v6 4/4] doc: update release notes for vhost sample Cheng Jiang
@ 2020-10-20 11:20           ` Cheng Jiang
  2020-10-20 11:20             ` [dpdk-dev] [PATCH v7 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
                               ` (4 more replies)
  4 siblings, 5 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-20 11:20 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia; +Cc: dev, patrick.fu, Cheng Jiang

This patch set makes vhost-vswitch be able to use vhost async APIs
for enqueue operations. Demonstrated how the application
leverage IOAT DMA channel with vhost async APIs.

We introduce two parameters to enable DMA acceleration for Tx
operations of queues:
-dma_type This parameter is used to specify DMA type for async
vhost-user net driver.
-dmas This parameter is used to specify the assigned DMA device of a
vhost device and enable async vhost data path.

---
v7:
 * Improved IOAT callbacks and added some comments

v6:
 * Cleand code and rebased for latest code

v5:
 * Improved meson build file and fixed dependency problem

v4:
 * Code rebased for latest IOAT driver

v3:
 * Fixed a coding style problem

v2:
 * Changed meson build file to fix dependency problem
 * Added parameter description in usage function
 * Optimized parameter settings and parsing function
 * Optimized abstraction, moved some code to ioat.c

Cheng Jiang (4):
  example/vhost: add async vhost args parsing function
  example/vhost: add support for vhost async data path
  doc: update vhost sample doc for vhost async data path
  doc: update release notes for vhost sample

 doc/guides/rel_notes/release_20_11.rst |   6 +
 doc/guides/sample_app_ug/vhost.rst     |  11 ++
 examples/vhost/ioat.c                  | 217 +++++++++++++++++++++++++
 examples/vhost/main.c                  |  94 ++++++++++-
 examples/vhost/main.h                  |  26 +++
 examples/vhost/meson.build             |   5 +
 6 files changed, 357 insertions(+), 2 deletions(-)
 create mode 100644 examples/vhost/ioat.c

--
2.27.0


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

* [dpdk-dev] [PATCH v7 1/4] example/vhost: add async vhost args parsing function
  2020-10-20 11:20           ` [dpdk-dev] [PATCH v7 0/4] add async data path in " Cheng Jiang
@ 2020-10-20 11:20             ` Cheng Jiang
  2020-10-20 11:20             ` [dpdk-dev] [PATCH v7 2/4] example/vhost: add support for vhost async data path Cheng Jiang
                               ` (3 subsequent siblings)
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-20 11:20 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia; +Cc: dev, patrick.fu, Cheng Jiang

This patch is to add async vhost driver arguments parsing function
for CBDMA channel, DMA initiation function and args description.
The meson build file is changed to fix dependency problem. With
these arguments vhost device can be set to use CBDMA or CPU for
enqueue operation and bind vhost device with specific CBDMA channel
to accelerate data copy.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 examples/vhost/ioat.c      | 117 +++++++++++++++++++++++++++++++++++++
 examples/vhost/main.c      |  37 +++++++++++-
 examples/vhost/main.h      |  14 +++++
 examples/vhost/meson.build |   5 ++
 4 files changed, 172 insertions(+), 1 deletion(-)
 create mode 100644 examples/vhost/ioat.c

diff --git a/examples/vhost/ioat.c b/examples/vhost/ioat.c
new file mode 100644
index 000000000..c3158d3c3
--- /dev/null
+++ b/examples/vhost/ioat.c
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2017 Intel Corporation
+ */
+
+#include <rte_vhost.h>
+#include <rte_rawdev.h>
+#include <rte_ioat_rawdev.h>
+#include <rte_pci.h>
+
+#include "main.h"
+
+#define MAX_VHOST_DEVICE 1024
+#define IOAT_RING_SIZE 4096
+
+struct dma_info {
+	struct rte_pci_addr addr;
+	uint16_t dev_id;
+	bool is_valid;
+};
+
+struct dma_for_vhost {
+	struct dma_info dmas[RTE_MAX_QUEUES_PER_PORT * 2];
+	uint16_t nr;
+};
+
+struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
+
+int
+open_ioat(const char *value)
+{
+	struct dma_for_vhost *dma_info = dma_bind;
+	char *input = strndup(value, strlen(value) + 1);
+	char *addrs = input;
+	char *ptrs[2];
+	char *start, *end, *substr;
+	int64_t vid, vring_id;
+	struct rte_ioat_rawdev_config config;
+	struct rte_rawdev_info info = { .dev_private = &config };
+	char name[32];
+	int dev_id;
+	int ret = 0;
+	uint16_t i = 0;
+	char *dma_arg[MAX_VHOST_DEVICE];
+	uint8_t args_nr;
+
+	while (isblank(*addrs))
+		addrs++;
+	if (*addrs == '\0') {
+		ret = -1;
+		goto out;
+	}
+
+	/* process DMA devices within bracket. */
+	addrs++;
+	substr = strtok(addrs, ";]");
+	if (!substr) {
+		ret = -1;
+		goto out;
+	}
+	args_nr = rte_strsplit(substr, strlen(substr),
+			dma_arg, MAX_VHOST_DEVICE, ',');
+	do {
+		char *arg_temp = dma_arg[i];
+		rte_strsplit(arg_temp, strlen(arg_temp), ptrs, 2, '@');
+
+		start = strstr(ptrs[0], "txd");
+		if (start == NULL) {
+			ret = -1;
+			goto out;
+		}
+
+		start += 3;
+		vid = strtol(start, &end, 0);
+		if (end == start) {
+			ret = -1;
+			goto out;
+		}
+
+		vring_id = 0 + VIRTIO_RXQ;
+		if (rte_pci_addr_parse(ptrs[1],
+				&(dma_info + vid)->dmas[vring_id].addr) < 0) {
+			ret = -1;
+			goto out;
+		}
+
+		rte_pci_device_name(&(dma_info + vid)->dmas[vring_id].addr,
+				name, sizeof(name));
+		dev_id = rte_rawdev_get_dev_id(name);
+		if (dev_id == (uint16_t)(-ENODEV) ||
+		dev_id == (uint16_t)(-EINVAL)) {
+			ret = -1;
+			goto out;
+		}
+
+		if (rte_rawdev_info_get(dev_id, &info, sizeof(config)) < 0 ||
+		strstr(info.driver_name, "ioat") == NULL) {
+			ret = -1;
+			goto out;
+		}
+
+		(dma_info + vid)->dmas[vring_id].dev_id = dev_id;
+		(dma_info + vid)->dmas[vring_id].is_valid = true;
+		config.ring_size = IOAT_RING_SIZE;
+		config.hdls_disable = true;
+		if (rte_rawdev_configure(dev_id, &info, sizeof(config)) < 0) {
+			ret = -1;
+			goto out;
+		}
+		rte_rawdev_start(dev_id);
+
+		dma_info->nr++;
+		i++;
+	} while (i < args_nr);
+out:
+	free(input);
+	return ret;
+}
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 959c0c283..76f5d76cb 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -95,6 +95,10 @@ static int client_mode;
 
 static int builtin_net_driver;
 
+static int async_vhost_driver;
+
+static char dma_type[MAX_LONG_OPT_SZ];
+
 /* Specify timeout (in useconds) between retries on RX. */
 static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
 /* Specify the number of retries on RX. */
@@ -181,6 +185,15 @@ struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];
 				 / US_PER_S * BURST_TX_DRAIN_US)
 #define VLAN_HLEN       4
 
+static inline int
+open_dma(const char *value)
+{
+	if (strncmp(dma_type, "ioat", 4) == 0)
+		return open_ioat(value);
+
+	return -1;
+}
+
 /*
  * Builds up the correct configuration for VMDQ VLAN pool map
  * according to the pool & queue limits.
@@ -446,7 +459,9 @@ us_vhost_usage(const char *prgname)
 	"		--socket-file: The path of the socket file.\n"
 	"		--tx-csum [0|1] disable/enable TX checksum offload.\n"
 	"		--tso [0|1] disable/enable TCP segment offload.\n"
-	"		--client register a vhost-user socket as client mode.\n",
+	"		--client register a vhost-user socket as client mode.\n"
+	"		--dma-type register dma type for your vhost async driver. For example \"ioat\" for now.\n"
+	"		--dmas register dma channel for specific vhost device.\n",
 	       prgname);
 }
 
@@ -472,6 +487,8 @@ us_vhost_parse_args(int argc, char **argv)
 		{"tso", required_argument, NULL, 0},
 		{"client", no_argument, &client_mode, 1},
 		{"builtin-net-driver", no_argument, &builtin_net_driver, 1},
+		{"dma-type", required_argument, NULL, 0},
+		{"dmas", required_argument, NULL, 0},
 		{NULL, 0, 0, 0},
 	};
 
@@ -614,6 +631,24 @@ us_vhost_parse_args(int argc, char **argv)
 				}
 			}
 
+			if (!strncmp(long_option[option_index].name,
+						"dma-type", MAX_LONG_OPT_SZ)) {
+				strcpy(dma_type, optarg);
+			}
+
+			if (!strncmp(long_option[option_index].name,
+						"dmas", MAX_LONG_OPT_SZ)) {
+				if (open_dma(optarg) == -1) {
+					if (*optarg == -1) {
+						RTE_LOG(INFO, VHOST_CONFIG,
+							"Wrong DMA args\n");
+						us_vhost_usage(prgname);
+					}
+					return -1;
+				}
+				async_vhost_driver = 1;
+			}
+
 			break;
 
 			/* Invalid option - print options. */
diff --git a/examples/vhost/main.h b/examples/vhost/main.h
index 7cba0edbf..fe83d255b 100644
--- a/examples/vhost/main.h
+++ b/examples/vhost/main.h
@@ -89,4 +89,18 @@ uint16_t vs_enqueue_pkts(struct vhost_dev *dev, uint16_t queue_id,
 uint16_t vs_dequeue_pkts(struct vhost_dev *dev, uint16_t queue_id,
 			 struct rte_mempool *mbuf_pool,
 			 struct rte_mbuf **pkts, uint16_t count);
+
+#ifdef RTE_ARCH_X86
+
+int open_ioat(const char *value);
+
+#else
+
+static int open_ioat(const char *value __rte_unused)
+{
+	return -1;
+}
+
+#endif
+
 #endif /* _MAIN_H_ */
diff --git a/examples/vhost/meson.build b/examples/vhost/meson.build
index 872d51153..2a03f9779 100644
--- a/examples/vhost/meson.build
+++ b/examples/vhost/meson.build
@@ -14,3 +14,8 @@ allow_experimental_apis = true
 sources = files(
 	'main.c', 'virtio_net.c'
 )
+
+if dpdk_conf.has('RTE_ARCH_X86')
+	deps += 'rawdev_ioat'
+	sources += files('ioat.c')
+endif
-- 
2.27.0


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

* [dpdk-dev] [PATCH v7 2/4] example/vhost: add support for vhost async data path
  2020-10-20 11:20           ` [dpdk-dev] [PATCH v7 0/4] add async data path in " Cheng Jiang
  2020-10-20 11:20             ` [dpdk-dev] [PATCH v7 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
@ 2020-10-20 11:20             ` Cheng Jiang
  2020-10-20 11:20             ` [dpdk-dev] [PATCH v7 3/4] doc: update vhost sample doc " Cheng Jiang
                               ` (2 subsequent siblings)
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-20 11:20 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia; +Cc: dev, patrick.fu, Cheng Jiang

This patch is to implement vhost DMA operation callbacks for CBDMA
PMD and add vhost async data-path in vhost sample. With providing
callback implementation for CBDMA, vswitch can leverage IOAT to
accelerate vhost async data-path.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 examples/vhost/ioat.c | 100 ++++++++++++++++++++++++++++++++++++++++++
 examples/vhost/main.c |  57 +++++++++++++++++++++++-
 examples/vhost/main.h |  12 +++++
 3 files changed, 168 insertions(+), 1 deletion(-)

diff --git a/examples/vhost/ioat.c b/examples/vhost/ioat.c
index c3158d3c3..fa503c3db 100644
--- a/examples/vhost/ioat.c
+++ b/examples/vhost/ioat.c
@@ -6,11 +6,13 @@
 #include <rte_rawdev.h>
 #include <rte_ioat_rawdev.h>
 #include <rte_pci.h>
+#include <sys/uio.h>
 
 #include "main.h"
 
 #define MAX_VHOST_DEVICE 1024
 #define IOAT_RING_SIZE 4096
+#define MAX_ENQUEUED_SIZE 256
 
 struct dma_info {
 	struct rte_pci_addr addr;
@@ -25,6 +27,15 @@ struct dma_for_vhost {
 
 struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
 
+struct packet_tracker {
+	unsigned short size_track[MAX_ENQUEUED_SIZE];
+	unsigned short next_read;
+	unsigned short next_write;
+	unsigned short last_remain;
+};
+
+struct packet_tracker cb_tracker[MAX_VHOST_DEVICE];
+
 int
 open_ioat(const char *value)
 {
@@ -115,3 +126,92 @@ open_ioat(const char *value)
 	free(input);
 	return ret;
 }
+
+uint32_t
+ioat_transfer_data_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_desc *descs,
+		struct rte_vhost_async_status *opaque_data, uint16_t count)
+{
+	uint32_t i_desc;
+	int dev_id = dma_bind[vid].dmas[queue_id * 2 + VIRTIO_RXQ].dev_id;
+	struct rte_vhost_iov_iter *src = NULL;
+	struct rte_vhost_iov_iter *dst = NULL;
+	unsigned long i_seg;
+	unsigned short mask = MAX_ENQUEUED_SIZE - 1;
+	unsigned short write = cb_tracker[dev_id].next_write;
+
+	if (!opaque_data) {
+		for (i_desc = 0; i_desc < count; i_desc++) {
+			src = descs[i_desc].src;
+			dst = descs[i_desc].dst;
+			i_seg = 0;
+			while (i_seg < src->nr_segs) {
+				/*
+				 * TODO: Assuming that the ring space of the
+				 * IOAT device is large enough, so there is no
+				 * error here, and the actual error handling
+				 * will be added later.
+				 */
+				rte_ioat_enqueue_copy(dev_id,
+					(uintptr_t)(src->iov[i_seg].iov_base)
+						+ src->offset,
+					(uintptr_t)(dst->iov[i_seg].iov_base)
+						+ dst->offset,
+					src->iov[i_seg].iov_len,
+					0,
+					0);
+				i_seg++;
+			}
+			write &= mask;
+			cb_tracker[dev_id].size_track[write] = i_seg;
+			write++;
+		}
+	} else {
+		/* Opaque data is not supported */
+		return -1;
+	}
+	/* ring the doorbell */
+	rte_ioat_perform_ops(dev_id);
+	cb_tracker[dev_id].next_write = write;
+	return i_desc;
+}
+
+uint32_t
+ioat_check_completed_copies_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_status *opaque_data,
+		uint16_t max_packets)
+{
+	if (!opaque_data) {
+		uintptr_t dump[255];
+		unsigned short n_seg;
+		unsigned short read, write;
+		unsigned short nb_packet = 0;
+		unsigned short mask = MAX_ENQUEUED_SIZE - 1;
+		unsigned short i;
+		int dev_id = dma_bind[vid].dmas[queue_id * 2
+				+ VIRTIO_RXQ].dev_id;
+		n_seg = rte_ioat_completed_ops(dev_id, 255, dump, dump);
+		n_seg += cb_tracker[dev_id].last_remain;
+		if (!n_seg)
+			return 0;
+		read = cb_tracker[dev_id].next_read;
+		write = cb_tracker[dev_id].next_write;
+		for (i = 0; i < max_packets; i++) {
+			read &= mask;
+			if (read == write)
+				break;
+			if (n_seg >= cb_tracker[dev_id].size_track[read]) {
+				n_seg -= cb_tracker[dev_id].size_track[read];
+				read++;
+				nb_packet++;
+			} else {
+				break;
+			}
+		}
+		cb_tracker[dev_id].next_read = read;
+		cb_tracker[dev_id].last_remain = n_seg;
+		return nb_packet;
+	}
+	/* Opaque data is not supported */
+	return -1;
+}
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 76f5d76cb..2469fcf21 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -804,9 +804,22 @@ virtio_xmit(struct vhost_dev *dst_vdev, struct vhost_dev *src_vdev,
 	    struct rte_mbuf *m)
 {
 	uint16_t ret;
+	struct rte_mbuf *m_cpl[1];
 
 	if (builtin_net_driver) {
 		ret = vs_enqueue_pkts(dst_vdev, VIRTIO_RXQ, &m, 1);
+	} else if (async_vhost_driver) {
+		ret = rte_vhost_submit_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ,
+						&m, 1);
+
+		if (likely(ret))
+			dst_vdev->nr_async_pkts++;
+
+		while (likely(dst_vdev->nr_async_pkts)) {
+			if (rte_vhost_poll_enqueue_completed(dst_vdev->vid,
+					VIRTIO_RXQ, m_cpl, 1))
+				dst_vdev->nr_async_pkts--;
+		}
 	} else {
 		ret = rte_vhost_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ, &m, 1);
 	}
@@ -1055,6 +1068,19 @@ drain_mbuf_table(struct mbuf_table *tx_q)
 	}
 }
 
+static __rte_always_inline void
+complete_async_pkts(struct vhost_dev *vdev, uint16_t qid)
+{
+	struct rte_mbuf *p_cpl[MAX_PKT_BURST];
+	uint16_t complete_count;
+
+	complete_count = rte_vhost_poll_enqueue_completed(vdev->vid,
+						qid, p_cpl, MAX_PKT_BURST);
+	vdev->nr_async_pkts -= complete_count;
+	if (complete_count)
+		free_pkts(p_cpl, complete_count);
+}
+
 static __rte_always_inline void
 drain_eth_rx(struct vhost_dev *vdev)
 {
@@ -1063,6 +1089,10 @@ drain_eth_rx(struct vhost_dev *vdev)
 
 	rx_count = rte_eth_rx_burst(ports[0], vdev->vmdq_rx_q,
 				    pkts, MAX_PKT_BURST);
+
+	while (likely(vdev->nr_async_pkts))
+		complete_async_pkts(vdev, VIRTIO_RXQ);
+
 	if (!rx_count)
 		return;
 
@@ -1087,16 +1117,22 @@ drain_eth_rx(struct vhost_dev *vdev)
 	if (builtin_net_driver) {
 		enqueue_count = vs_enqueue_pkts(vdev, VIRTIO_RXQ,
 						pkts, rx_count);
+	} else if (async_vhost_driver) {
+		enqueue_count = rte_vhost_submit_enqueue_burst(vdev->vid,
+					VIRTIO_RXQ, pkts, rx_count);
+		vdev->nr_async_pkts += enqueue_count;
 	} else {
 		enqueue_count = rte_vhost_enqueue_burst(vdev->vid, VIRTIO_RXQ,
 						pkts, rx_count);
 	}
+
 	if (enable_stats) {
 		rte_atomic64_add(&vdev->stats.rx_total_atomic, rx_count);
 		rte_atomic64_add(&vdev->stats.rx_atomic, enqueue_count);
 	}
 
-	free_pkts(pkts, rx_count);
+	if (!async_vhost_driver)
+		free_pkts(pkts, rx_count);
 }
 
 static __rte_always_inline void
@@ -1243,6 +1279,9 @@ destroy_device(int vid)
 		"(%d) device has been removed from data core\n",
 		vdev->vid);
 
+	if (async_vhost_driver)
+		rte_vhost_async_channel_unregister(vid, VIRTIO_RXQ);
+
 	rte_free(vdev);
 }
 
@@ -1257,6 +1296,12 @@ new_device(int vid)
 	uint32_t device_num_min = num_devices;
 	struct vhost_dev *vdev;
 
+	struct rte_vhost_async_channel_ops channel_ops = {
+		.transfer_data = ioat_transfer_data_cb,
+		.check_completed_copies = ioat_check_completed_copies_cb
+	};
+	struct rte_vhost_async_features f;
+
 	vdev = rte_zmalloc("vhost device", sizeof(*vdev), RTE_CACHE_LINE_SIZE);
 	if (vdev == NULL) {
 		RTE_LOG(INFO, VHOST_DATA,
@@ -1297,6 +1342,13 @@ new_device(int vid)
 		"(%d) device has been added to data core %d\n",
 		vid, vdev->coreid);
 
+	if (async_vhost_driver) {
+		f.async_inorder = 1;
+		f.async_threshold = 256;
+		return rte_vhost_async_channel_register(vid, VIRTIO_RXQ,
+			f.intval, &channel_ops);
+	}
+
 	return 0;
 }
 
@@ -1535,6 +1587,9 @@ main(int argc, char *argv[])
 	/* Register vhost user driver to handle vhost messages. */
 	for (i = 0; i < nb_sockets; i++) {
 		char *file = socket_files + i * PATH_MAX;
+		if (async_vhost_driver)
+			flags = flags | RTE_VHOST_USER_ASYNC_COPY;
+
 		ret = rte_vhost_driver_register(file, flags);
 		if (ret != 0) {
 			unregister_drivers(i);
diff --git a/examples/vhost/main.h b/examples/vhost/main.h
index fe83d255b..5a628473e 100644
--- a/examples/vhost/main.h
+++ b/examples/vhost/main.h
@@ -8,6 +8,7 @@
 #include <sys/queue.h>
 
 #include <rte_ether.h>
+#include <rte_vhost_async.h>
 
 /* Macros for printing using RTE_LOG */
 #define RTE_LOGTYPE_VHOST_CONFIG RTE_LOGTYPE_USER1
@@ -51,6 +52,7 @@ struct vhost_dev {
 	uint64_t features;
 	size_t hdr_len;
 	uint16_t nr_vrings;
+	uint16_t nr_async_pkts;
 	struct rte_vhost_memory *mem;
 	struct device_statistics stats;
 	TAILQ_ENTRY(vhost_dev) global_vdev_entry;
@@ -103,4 +105,14 @@ static int open_ioat(const char *value __rte_unused)
 
 #endif
 
+uint32_t
+ioat_transfer_data_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_desc *descs,
+		struct rte_vhost_async_status *opaque_data, uint16_t count);
+
+uint32_t
+ioat_check_completed_copies_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_status *opaque_data,
+		uint16_t max_packets);
+
 #endif /* _MAIN_H_ */
-- 
2.27.0


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

* [dpdk-dev] [PATCH v7 3/4] doc: update vhost sample doc for vhost async data path
  2020-10-20 11:20           ` [dpdk-dev] [PATCH v7 0/4] add async data path in " Cheng Jiang
  2020-10-20 11:20             ` [dpdk-dev] [PATCH v7 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
  2020-10-20 11:20             ` [dpdk-dev] [PATCH v7 2/4] example/vhost: add support for vhost async data path Cheng Jiang
@ 2020-10-20 11:20             ` Cheng Jiang
  2020-10-20 11:20             ` [dpdk-dev] [PATCH v7 4/4] doc: update release notes for vhost sample Cheng Jiang
  2020-10-21  6:50             ` [dpdk-dev] [PATCH v8 0/4] add async data path in " Cheng Jiang
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-20 11:20 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia; +Cc: dev, patrick.fu, Cheng Jiang

Add vhost async driver arguments information for vhost async data
path in vhost sample application.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 doc/guides/sample_app_ug/vhost.rst | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/doc/guides/sample_app_ug/vhost.rst b/doc/guides/sample_app_ug/vhost.rst
index b7ed4f8bd..0f4f70945 100644
--- a/doc/guides/sample_app_ug/vhost.rst
+++ b/doc/guides/sample_app_ug/vhost.rst
@@ -162,6 +162,17 @@ enabled and cannot be disabled.
 A very simple vhost-user net driver which demonstrates how to use the generic
 vhost APIs will be used when this option is given. It is disabled by default.
 
+**--dma-type**
+This parameter is used to specify DMA type for async vhost-user net driver which
+demonstrates how to use the async vhost APIs. It's used in combination with dmas.
+
+**--dmas**
+This parameter is used to specify the assigned DMA device of a vhost device.
+Async vhost-user net driver will be used if --dmas is set. For example
+--dmas [txd0@00:04.0,txd1@00:04.1] means use DMA channel 00:04.0 for vhost
+device 0 enqueue operation and use DMA channel 00:04.1 for vhost device 1
+enqueue operation.
+
 Common Issues
 -------------
 
-- 
2.27.0


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

* [dpdk-dev] [PATCH v7 4/4] doc: update release notes for vhost sample
  2020-10-20 11:20           ` [dpdk-dev] [PATCH v7 0/4] add async data path in " Cheng Jiang
                               ` (2 preceding siblings ...)
  2020-10-20 11:20             ` [dpdk-dev] [PATCH v7 3/4] doc: update vhost sample doc " Cheng Jiang
@ 2020-10-20 11:20             ` Cheng Jiang
  2020-10-21  6:50             ` [dpdk-dev] [PATCH v8 0/4] add async data path in " Cheng Jiang
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-20 11:20 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia; +Cc: dev, patrick.fu, Cheng Jiang

Add release notes for vhost async data path support in vhost sample.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 doc/guides/rel_notes/release_20_11.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst
index f8686a50d..812ca8834 100644
--- a/doc/guides/rel_notes/release_20_11.rst
+++ b/doc/guides/rel_notes/release_20_11.rst
@@ -214,6 +214,12 @@ New Features
   * Added new ``RTE_ACL_CLASSIFY_AVX512X32`` vector implementation,
     which can process up to 32 flows in parallel. Requires AVX512 support.
 
+* **Updated vhost sample application.**
+
+  Added vhost asynchronous APIs support, which demonstrated how the application
+  leverage IOAT DMA channel with vhost asynchronous APIs.
+  See the :doc:`../sample_app_ug/vhost` for more details.
+
 
 Removed Items
 -------------
-- 
2.27.0


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

* [dpdk-dev] [PATCH v8 0/4] add async data path in vhost sample
  2020-10-20 11:20           ` [dpdk-dev] [PATCH v7 0/4] add async data path in " Cheng Jiang
                               ` (3 preceding siblings ...)
  2020-10-20 11:20             ` [dpdk-dev] [PATCH v7 4/4] doc: update release notes for vhost sample Cheng Jiang
@ 2020-10-21  6:50             ` Cheng Jiang
  2020-10-21  6:50               ` [dpdk-dev] [PATCH v8 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
                                 ` (4 more replies)
  4 siblings, 5 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-21  6:50 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang, Cheng Jiang

This patch set makes vhost-vswitch be able to use vhost async APIs
for enqueue operations. Demonstrated how the application
leverage IOAT DMA channel with vhost async APIs.

We introduce two parameters to enable DMA acceleration for Tx
operations of queues:
-dma_type This parameter is used to specify DMA type for async
vhost-user net driver.
-dmas This parameter is used to specify the assigned DMA device of a
vhost device and enable async vhost data path.

---
v8:
 * Changed meson build file due to the change of ioat component name

v7:
 * Improved IOAT callbacks and added some comments

v6:
 * Cleand code and rebased for latest code

v5:
 * Improved meson build file and fixed dependency problem

v4:
 * Code rebased for latest IOAT driver

v3:
 * Fixed a coding style problem

v2:
 * Changed meson build file to fix dependency problem
 * Added parameter description in usage function
 * Optimized parameter settings and parsing function
 * Optimized abstraction, moved some code to ioat.c

Cheng Jiang (4):
  example/vhost: add async vhost args parsing function
  example/vhost: add support for vhost async data path
  doc: update vhost sample doc for vhost async data path
  doc: update release notes for vhost sample

 doc/guides/rel_notes/release_20_11.rst |   6 +
 doc/guides/sample_app_ug/vhost.rst     |  11 ++
 examples/vhost/ioat.c                  | 217 +++++++++++++++++++++++++
 examples/vhost/main.c                  |  94 ++++++++++-
 examples/vhost/main.h                  |  26 +++
 examples/vhost/meson.build             |   5 +
 6 files changed, 357 insertions(+), 2 deletions(-)
 create mode 100644 examples/vhost/ioat.c

--
2.27.0


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

* [dpdk-dev] [PATCH v8 1/4] example/vhost: add async vhost args parsing function
  2020-10-21  6:50             ` [dpdk-dev] [PATCH v8 0/4] add async data path in " Cheng Jiang
@ 2020-10-21  6:50               ` Cheng Jiang
  2020-10-21  6:50               ` [dpdk-dev] [PATCH v8 2/4] example/vhost: add support for vhost async data path Cheng Jiang
                                 ` (3 subsequent siblings)
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-21  6:50 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang, Cheng Jiang

This patch is to add async vhost driver arguments parsing function
for CBDMA channel, DMA initiation function and args description.
The meson build file is changed to fix dependency problem. With
these arguments vhost device can be set to use CBDMA or CPU for
enqueue operation and bind vhost device with specific CBDMA channel
to accelerate data copy.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 examples/vhost/ioat.c      | 117 +++++++++++++++++++++++++++++++++++++
 examples/vhost/main.c      |  37 +++++++++++-
 examples/vhost/main.h      |  14 +++++
 examples/vhost/meson.build |   5 ++
 4 files changed, 172 insertions(+), 1 deletion(-)
 create mode 100644 examples/vhost/ioat.c

diff --git a/examples/vhost/ioat.c b/examples/vhost/ioat.c
new file mode 100644
index 000000000..c3158d3c3
--- /dev/null
+++ b/examples/vhost/ioat.c
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2017 Intel Corporation
+ */
+
+#include <rte_vhost.h>
+#include <rte_rawdev.h>
+#include <rte_ioat_rawdev.h>
+#include <rte_pci.h>
+
+#include "main.h"
+
+#define MAX_VHOST_DEVICE 1024
+#define IOAT_RING_SIZE 4096
+
+struct dma_info {
+	struct rte_pci_addr addr;
+	uint16_t dev_id;
+	bool is_valid;
+};
+
+struct dma_for_vhost {
+	struct dma_info dmas[RTE_MAX_QUEUES_PER_PORT * 2];
+	uint16_t nr;
+};
+
+struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
+
+int
+open_ioat(const char *value)
+{
+	struct dma_for_vhost *dma_info = dma_bind;
+	char *input = strndup(value, strlen(value) + 1);
+	char *addrs = input;
+	char *ptrs[2];
+	char *start, *end, *substr;
+	int64_t vid, vring_id;
+	struct rte_ioat_rawdev_config config;
+	struct rte_rawdev_info info = { .dev_private = &config };
+	char name[32];
+	int dev_id;
+	int ret = 0;
+	uint16_t i = 0;
+	char *dma_arg[MAX_VHOST_DEVICE];
+	uint8_t args_nr;
+
+	while (isblank(*addrs))
+		addrs++;
+	if (*addrs == '\0') {
+		ret = -1;
+		goto out;
+	}
+
+	/* process DMA devices within bracket. */
+	addrs++;
+	substr = strtok(addrs, ";]");
+	if (!substr) {
+		ret = -1;
+		goto out;
+	}
+	args_nr = rte_strsplit(substr, strlen(substr),
+			dma_arg, MAX_VHOST_DEVICE, ',');
+	do {
+		char *arg_temp = dma_arg[i];
+		rte_strsplit(arg_temp, strlen(arg_temp), ptrs, 2, '@');
+
+		start = strstr(ptrs[0], "txd");
+		if (start == NULL) {
+			ret = -1;
+			goto out;
+		}
+
+		start += 3;
+		vid = strtol(start, &end, 0);
+		if (end == start) {
+			ret = -1;
+			goto out;
+		}
+
+		vring_id = 0 + VIRTIO_RXQ;
+		if (rte_pci_addr_parse(ptrs[1],
+				&(dma_info + vid)->dmas[vring_id].addr) < 0) {
+			ret = -1;
+			goto out;
+		}
+
+		rte_pci_device_name(&(dma_info + vid)->dmas[vring_id].addr,
+				name, sizeof(name));
+		dev_id = rte_rawdev_get_dev_id(name);
+		if (dev_id == (uint16_t)(-ENODEV) ||
+		dev_id == (uint16_t)(-EINVAL)) {
+			ret = -1;
+			goto out;
+		}
+
+		if (rte_rawdev_info_get(dev_id, &info, sizeof(config)) < 0 ||
+		strstr(info.driver_name, "ioat") == NULL) {
+			ret = -1;
+			goto out;
+		}
+
+		(dma_info + vid)->dmas[vring_id].dev_id = dev_id;
+		(dma_info + vid)->dmas[vring_id].is_valid = true;
+		config.ring_size = IOAT_RING_SIZE;
+		config.hdls_disable = true;
+		if (rte_rawdev_configure(dev_id, &info, sizeof(config)) < 0) {
+			ret = -1;
+			goto out;
+		}
+		rte_rawdev_start(dev_id);
+
+		dma_info->nr++;
+		i++;
+	} while (i < args_nr);
+out:
+	free(input);
+	return ret;
+}
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index faa482245..d759cae2c 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -95,6 +95,10 @@ static int client_mode;
 
 static int builtin_net_driver;
 
+static int async_vhost_driver;
+
+static char dma_type[MAX_LONG_OPT_SZ];
+
 /* Specify timeout (in useconds) between retries on RX. */
 static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
 /* Specify the number of retries on RX. */
@@ -181,6 +185,15 @@ struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];
 				 / US_PER_S * BURST_TX_DRAIN_US)
 #define VLAN_HLEN       4
 
+static inline int
+open_dma(const char *value)
+{
+	if (strncmp(dma_type, "ioat", 4) == 0)
+		return open_ioat(value);
+
+	return -1;
+}
+
 /*
  * Builds up the correct configuration for VMDQ VLAN pool map
  * according to the pool & queue limits.
@@ -446,7 +459,9 @@ us_vhost_usage(const char *prgname)
 	"		--socket-file: The path of the socket file.\n"
 	"		--tx-csum [0|1] disable/enable TX checksum offload.\n"
 	"		--tso [0|1] disable/enable TCP segment offload.\n"
-	"		--client register a vhost-user socket as client mode.\n",
+	"		--client register a vhost-user socket as client mode.\n"
+	"		--dma-type register dma type for your vhost async driver. For example \"ioat\" for now.\n"
+	"		--dmas register dma channel for specific vhost device.\n",
 	       prgname);
 }
 
@@ -472,6 +487,8 @@ us_vhost_parse_args(int argc, char **argv)
 		{"tso", required_argument, NULL, 0},
 		{"client", no_argument, &client_mode, 1},
 		{"builtin-net-driver", no_argument, &builtin_net_driver, 1},
+		{"dma-type", required_argument, NULL, 0},
+		{"dmas", required_argument, NULL, 0},
 		{NULL, 0, 0, 0},
 	};
 
@@ -614,6 +631,24 @@ us_vhost_parse_args(int argc, char **argv)
 				}
 			}
 
+			if (!strncmp(long_option[option_index].name,
+						"dma-type", MAX_LONG_OPT_SZ)) {
+				strcpy(dma_type, optarg);
+			}
+
+			if (!strncmp(long_option[option_index].name,
+						"dmas", MAX_LONG_OPT_SZ)) {
+				if (open_dma(optarg) == -1) {
+					if (*optarg == -1) {
+						RTE_LOG(INFO, VHOST_CONFIG,
+							"Wrong DMA args\n");
+						us_vhost_usage(prgname);
+					}
+					return -1;
+				}
+				async_vhost_driver = 1;
+			}
+
 			break;
 
 			/* Invalid option - print options. */
diff --git a/examples/vhost/main.h b/examples/vhost/main.h
index 7cba0edbf..fe83d255b 100644
--- a/examples/vhost/main.h
+++ b/examples/vhost/main.h
@@ -89,4 +89,18 @@ uint16_t vs_enqueue_pkts(struct vhost_dev *dev, uint16_t queue_id,
 uint16_t vs_dequeue_pkts(struct vhost_dev *dev, uint16_t queue_id,
 			 struct rte_mempool *mbuf_pool,
 			 struct rte_mbuf **pkts, uint16_t count);
+
+#ifdef RTE_ARCH_X86
+
+int open_ioat(const char *value);
+
+#else
+
+static int open_ioat(const char *value __rte_unused)
+{
+	return -1;
+}
+
+#endif
+
 #endif /* _MAIN_H_ */
diff --git a/examples/vhost/meson.build b/examples/vhost/meson.build
index 872d51153..24f1f7131 100644
--- a/examples/vhost/meson.build
+++ b/examples/vhost/meson.build
@@ -14,3 +14,8 @@ allow_experimental_apis = true
 sources = files(
 	'main.c', 'virtio_net.c'
 )
+
+if dpdk_conf.has('RTE_ARCH_X86')
+	deps += 'raw_ioat'
+	sources += files('ioat.c')
+endif
-- 
2.27.0


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

* [dpdk-dev] [PATCH v8 2/4] example/vhost: add support for vhost async data path
  2020-10-21  6:50             ` [dpdk-dev] [PATCH v8 0/4] add async data path in " Cheng Jiang
  2020-10-21  6:50               ` [dpdk-dev] [PATCH v8 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
@ 2020-10-21  6:50               ` Cheng Jiang
  2020-10-21  6:50               ` [dpdk-dev] [PATCH v8 3/4] doc: update vhost sample doc " Cheng Jiang
                                 ` (2 subsequent siblings)
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-21  6:50 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang, Cheng Jiang

This patch is to implement vhost DMA operation callbacks for CBDMA
PMD and add vhost async data-path in vhost sample. With providing
callback implementation for CBDMA, vswitch can leverage IOAT to
accelerate vhost async data-path.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 examples/vhost/ioat.c | 100 ++++++++++++++++++++++++++++++++++++++++++
 examples/vhost/main.c |  57 +++++++++++++++++++++++-
 examples/vhost/main.h |  12 +++++
 3 files changed, 168 insertions(+), 1 deletion(-)

diff --git a/examples/vhost/ioat.c b/examples/vhost/ioat.c
index c3158d3c3..fa503c3db 100644
--- a/examples/vhost/ioat.c
+++ b/examples/vhost/ioat.c
@@ -6,11 +6,13 @@
 #include <rte_rawdev.h>
 #include <rte_ioat_rawdev.h>
 #include <rte_pci.h>
+#include <sys/uio.h>
 
 #include "main.h"
 
 #define MAX_VHOST_DEVICE 1024
 #define IOAT_RING_SIZE 4096
+#define MAX_ENQUEUED_SIZE 256
 
 struct dma_info {
 	struct rte_pci_addr addr;
@@ -25,6 +27,15 @@ struct dma_for_vhost {
 
 struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
 
+struct packet_tracker {
+	unsigned short size_track[MAX_ENQUEUED_SIZE];
+	unsigned short next_read;
+	unsigned short next_write;
+	unsigned short last_remain;
+};
+
+struct packet_tracker cb_tracker[MAX_VHOST_DEVICE];
+
 int
 open_ioat(const char *value)
 {
@@ -115,3 +126,92 @@ open_ioat(const char *value)
 	free(input);
 	return ret;
 }
+
+uint32_t
+ioat_transfer_data_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_desc *descs,
+		struct rte_vhost_async_status *opaque_data, uint16_t count)
+{
+	uint32_t i_desc;
+	int dev_id = dma_bind[vid].dmas[queue_id * 2 + VIRTIO_RXQ].dev_id;
+	struct rte_vhost_iov_iter *src = NULL;
+	struct rte_vhost_iov_iter *dst = NULL;
+	unsigned long i_seg;
+	unsigned short mask = MAX_ENQUEUED_SIZE - 1;
+	unsigned short write = cb_tracker[dev_id].next_write;
+
+	if (!opaque_data) {
+		for (i_desc = 0; i_desc < count; i_desc++) {
+			src = descs[i_desc].src;
+			dst = descs[i_desc].dst;
+			i_seg = 0;
+			while (i_seg < src->nr_segs) {
+				/*
+				 * TODO: Assuming that the ring space of the
+				 * IOAT device is large enough, so there is no
+				 * error here, and the actual error handling
+				 * will be added later.
+				 */
+				rte_ioat_enqueue_copy(dev_id,
+					(uintptr_t)(src->iov[i_seg].iov_base)
+						+ src->offset,
+					(uintptr_t)(dst->iov[i_seg].iov_base)
+						+ dst->offset,
+					src->iov[i_seg].iov_len,
+					0,
+					0);
+				i_seg++;
+			}
+			write &= mask;
+			cb_tracker[dev_id].size_track[write] = i_seg;
+			write++;
+		}
+	} else {
+		/* Opaque data is not supported */
+		return -1;
+	}
+	/* ring the doorbell */
+	rte_ioat_perform_ops(dev_id);
+	cb_tracker[dev_id].next_write = write;
+	return i_desc;
+}
+
+uint32_t
+ioat_check_completed_copies_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_status *opaque_data,
+		uint16_t max_packets)
+{
+	if (!opaque_data) {
+		uintptr_t dump[255];
+		unsigned short n_seg;
+		unsigned short read, write;
+		unsigned short nb_packet = 0;
+		unsigned short mask = MAX_ENQUEUED_SIZE - 1;
+		unsigned short i;
+		int dev_id = dma_bind[vid].dmas[queue_id * 2
+				+ VIRTIO_RXQ].dev_id;
+		n_seg = rte_ioat_completed_ops(dev_id, 255, dump, dump);
+		n_seg += cb_tracker[dev_id].last_remain;
+		if (!n_seg)
+			return 0;
+		read = cb_tracker[dev_id].next_read;
+		write = cb_tracker[dev_id].next_write;
+		for (i = 0; i < max_packets; i++) {
+			read &= mask;
+			if (read == write)
+				break;
+			if (n_seg >= cb_tracker[dev_id].size_track[read]) {
+				n_seg -= cb_tracker[dev_id].size_track[read];
+				read++;
+				nb_packet++;
+			} else {
+				break;
+			}
+		}
+		cb_tracker[dev_id].next_read = read;
+		cb_tracker[dev_id].last_remain = n_seg;
+		return nb_packet;
+	}
+	/* Opaque data is not supported */
+	return -1;
+}
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index d759cae2c..896f5f781 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -804,9 +804,22 @@ virtio_xmit(struct vhost_dev *dst_vdev, struct vhost_dev *src_vdev,
 	    struct rte_mbuf *m)
 {
 	uint16_t ret;
+	struct rte_mbuf *m_cpl[1];
 
 	if (builtin_net_driver) {
 		ret = vs_enqueue_pkts(dst_vdev, VIRTIO_RXQ, &m, 1);
+	} else if (async_vhost_driver) {
+		ret = rte_vhost_submit_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ,
+						&m, 1);
+
+		if (likely(ret))
+			dst_vdev->nr_async_pkts++;
+
+		while (likely(dst_vdev->nr_async_pkts)) {
+			if (rte_vhost_poll_enqueue_completed(dst_vdev->vid,
+					VIRTIO_RXQ, m_cpl, 1))
+				dst_vdev->nr_async_pkts--;
+		}
 	} else {
 		ret = rte_vhost_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ, &m, 1);
 	}
@@ -1055,6 +1068,19 @@ drain_mbuf_table(struct mbuf_table *tx_q)
 	}
 }
 
+static __rte_always_inline void
+complete_async_pkts(struct vhost_dev *vdev, uint16_t qid)
+{
+	struct rte_mbuf *p_cpl[MAX_PKT_BURST];
+	uint16_t complete_count;
+
+	complete_count = rte_vhost_poll_enqueue_completed(vdev->vid,
+						qid, p_cpl, MAX_PKT_BURST);
+	vdev->nr_async_pkts -= complete_count;
+	if (complete_count)
+		free_pkts(p_cpl, complete_count);
+}
+
 static __rte_always_inline void
 drain_eth_rx(struct vhost_dev *vdev)
 {
@@ -1063,6 +1089,10 @@ drain_eth_rx(struct vhost_dev *vdev)
 
 	rx_count = rte_eth_rx_burst(ports[0], vdev->vmdq_rx_q,
 				    pkts, MAX_PKT_BURST);
+
+	while (likely(vdev->nr_async_pkts))
+		complete_async_pkts(vdev, VIRTIO_RXQ);
+
 	if (!rx_count)
 		return;
 
@@ -1087,16 +1117,22 @@ drain_eth_rx(struct vhost_dev *vdev)
 	if (builtin_net_driver) {
 		enqueue_count = vs_enqueue_pkts(vdev, VIRTIO_RXQ,
 						pkts, rx_count);
+	} else if (async_vhost_driver) {
+		enqueue_count = rte_vhost_submit_enqueue_burst(vdev->vid,
+					VIRTIO_RXQ, pkts, rx_count);
+		vdev->nr_async_pkts += enqueue_count;
 	} else {
 		enqueue_count = rte_vhost_enqueue_burst(vdev->vid, VIRTIO_RXQ,
 						pkts, rx_count);
 	}
+
 	if (enable_stats) {
 		rte_atomic64_add(&vdev->stats.rx_total_atomic, rx_count);
 		rte_atomic64_add(&vdev->stats.rx_atomic, enqueue_count);
 	}
 
-	free_pkts(pkts, rx_count);
+	if (!async_vhost_driver)
+		free_pkts(pkts, rx_count);
 }
 
 static __rte_always_inline void
@@ -1243,6 +1279,9 @@ destroy_device(int vid)
 		"(%d) device has been removed from data core\n",
 		vdev->vid);
 
+	if (async_vhost_driver)
+		rte_vhost_async_channel_unregister(vid, VIRTIO_RXQ);
+
 	rte_free(vdev);
 }
 
@@ -1257,6 +1296,12 @@ new_device(int vid)
 	uint32_t device_num_min = num_devices;
 	struct vhost_dev *vdev;
 
+	struct rte_vhost_async_channel_ops channel_ops = {
+		.transfer_data = ioat_transfer_data_cb,
+		.check_completed_copies = ioat_check_completed_copies_cb
+	};
+	struct rte_vhost_async_features f;
+
 	vdev = rte_zmalloc("vhost device", sizeof(*vdev), RTE_CACHE_LINE_SIZE);
 	if (vdev == NULL) {
 		RTE_LOG(INFO, VHOST_DATA,
@@ -1297,6 +1342,13 @@ new_device(int vid)
 		"(%d) device has been added to data core %d\n",
 		vid, vdev->coreid);
 
+	if (async_vhost_driver) {
+		f.async_inorder = 1;
+		f.async_threshold = 256;
+		return rte_vhost_async_channel_register(vid, VIRTIO_RXQ,
+			f.intval, &channel_ops);
+	}
+
 	return 0;
 }
 
@@ -1535,6 +1587,9 @@ main(int argc, char *argv[])
 	/* Register vhost user driver to handle vhost messages. */
 	for (i = 0; i < nb_sockets; i++) {
 		char *file = socket_files + i * PATH_MAX;
+		if (async_vhost_driver)
+			flags = flags | RTE_VHOST_USER_ASYNC_COPY;
+
 		ret = rte_vhost_driver_register(file, flags);
 		if (ret != 0) {
 			unregister_drivers(i);
diff --git a/examples/vhost/main.h b/examples/vhost/main.h
index fe83d255b..5a628473e 100644
--- a/examples/vhost/main.h
+++ b/examples/vhost/main.h
@@ -8,6 +8,7 @@
 #include <sys/queue.h>
 
 #include <rte_ether.h>
+#include <rte_vhost_async.h>
 
 /* Macros for printing using RTE_LOG */
 #define RTE_LOGTYPE_VHOST_CONFIG RTE_LOGTYPE_USER1
@@ -51,6 +52,7 @@ struct vhost_dev {
 	uint64_t features;
 	size_t hdr_len;
 	uint16_t nr_vrings;
+	uint16_t nr_async_pkts;
 	struct rte_vhost_memory *mem;
 	struct device_statistics stats;
 	TAILQ_ENTRY(vhost_dev) global_vdev_entry;
@@ -103,4 +105,14 @@ static int open_ioat(const char *value __rte_unused)
 
 #endif
 
+uint32_t
+ioat_transfer_data_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_desc *descs,
+		struct rte_vhost_async_status *opaque_data, uint16_t count);
+
+uint32_t
+ioat_check_completed_copies_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_status *opaque_data,
+		uint16_t max_packets);
+
 #endif /* _MAIN_H_ */
-- 
2.27.0


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

* [dpdk-dev] [PATCH v8 3/4] doc: update vhost sample doc for vhost async data path
  2020-10-21  6:50             ` [dpdk-dev] [PATCH v8 0/4] add async data path in " Cheng Jiang
  2020-10-21  6:50               ` [dpdk-dev] [PATCH v8 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
  2020-10-21  6:50               ` [dpdk-dev] [PATCH v8 2/4] example/vhost: add support for vhost async data path Cheng Jiang
@ 2020-10-21  6:50               ` Cheng Jiang
  2020-10-21  6:50               ` [dpdk-dev] [PATCH v8 4/4] doc: update release notes for vhost sample Cheng Jiang
  2020-10-22  6:46               ` [dpdk-dev] [PATCH v9 0/4] add async data path in " Cheng Jiang
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-21  6:50 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang, Cheng Jiang

Add vhost async driver arguments information for vhost async data
path in vhost sample application.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 doc/guides/sample_app_ug/vhost.rst | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/doc/guides/sample_app_ug/vhost.rst b/doc/guides/sample_app_ug/vhost.rst
index b7ed4f8bd..0f4f70945 100644
--- a/doc/guides/sample_app_ug/vhost.rst
+++ b/doc/guides/sample_app_ug/vhost.rst
@@ -162,6 +162,17 @@ enabled and cannot be disabled.
 A very simple vhost-user net driver which demonstrates how to use the generic
 vhost APIs will be used when this option is given. It is disabled by default.
 
+**--dma-type**
+This parameter is used to specify DMA type for async vhost-user net driver which
+demonstrates how to use the async vhost APIs. It's used in combination with dmas.
+
+**--dmas**
+This parameter is used to specify the assigned DMA device of a vhost device.
+Async vhost-user net driver will be used if --dmas is set. For example
+--dmas [txd0@00:04.0,txd1@00:04.1] means use DMA channel 00:04.0 for vhost
+device 0 enqueue operation and use DMA channel 00:04.1 for vhost device 1
+enqueue operation.
+
 Common Issues
 -------------
 
-- 
2.27.0


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

* [dpdk-dev] [PATCH v8 4/4] doc: update release notes for vhost sample
  2020-10-21  6:50             ` [dpdk-dev] [PATCH v8 0/4] add async data path in " Cheng Jiang
                                 ` (2 preceding siblings ...)
  2020-10-21  6:50               ` [dpdk-dev] [PATCH v8 3/4] doc: update vhost sample doc " Cheng Jiang
@ 2020-10-21  6:50               ` Cheng Jiang
  2020-10-22  6:46               ` [dpdk-dev] [PATCH v9 0/4] add async data path in " Cheng Jiang
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-21  6:50 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang, Cheng Jiang

Add release notes for vhost async data path support in vhost sample.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 doc/guides/rel_notes/release_20_11.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst
index 0d45b5003..f2db063e0 100644
--- a/doc/guides/rel_notes/release_20_11.rst
+++ b/doc/guides/rel_notes/release_20_11.rst
@@ -345,6 +345,12 @@ New Features
   * Replaced ``--scalar`` command-line option with ``--alg=<value>``, to allow
     the user to select the desired classify method.
 
+* **Updated vhost sample application.**
+
+  Added vhost asynchronous APIs support, which demonstrated how the application
+  leverage IOAT DMA channel with vhost asynchronous APIs.
+  See the :doc:`../sample_app_ug/vhost` for more details.
+
 
 Removed Items
 -------------
-- 
2.27.0


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

* [dpdk-dev] [PATCH v9 0/4] add async data path in vhost sample
  2020-10-21  6:50             ` [dpdk-dev] [PATCH v8 0/4] add async data path in " Cheng Jiang
                                 ` (3 preceding siblings ...)
  2020-10-21  6:50               ` [dpdk-dev] [PATCH v8 4/4] doc: update release notes for vhost sample Cheng Jiang
@ 2020-10-22  6:46               ` Cheng Jiang
  2020-10-22  6:46                 ` [dpdk-dev] [PATCH v9 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
                                   ` (4 more replies)
  4 siblings, 5 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-22  6:46 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang, Cheng Jiang

This patch set makes vhost-vswitch be able to use vhost async APIs
for enqueue operations. Demonstrated how the application
leverage IOAT DMA channel with vhost async APIs.

We introduce two parameters to enable DMA acceleration for Tx
operations of queues:
-dma_type This parameter is used to specify DMA type for async
vhost-user net driver.
-dmas This parameter is used to specify the assigned DMA device of a
vhost device and enable async vhost data path.

---
v9:
 * Optimized code structure to solve compilation issue on non-x86 platforms

v8:
 * Changed meson build file due to the change of ioat component name

v7:
 * Improved IOAT callbacks and added some comments

v6:
 * Cleand code and rebased for latest code

v5:
 * Improved meson build file and fixed dependency problem

v4:
 * Code rebased for latest IOAT driver

v3:
 * Fixed a coding style problem

v2:
 * Changed meson build file to fix dependency problem
 * Added parameter description in usage function
 * Optimized parameter settings and parsing function
 * Optimized abstraction, moved some code to ioat.c

Cheng Jiang (4):
  example/vhost: add async vhost args parsing function
  example/vhost: add support for vhost async data path
  doc: update vhost sample doc for vhost async data path
  doc: update release notes for vhost sample

 doc/guides/rel_notes/release_20_11.rst |   6 +
 doc/guides/sample_app_ug/vhost.rst     |  11 ++
 examples/vhost/ioat.c                  | 198 +++++++++++++++++++++++++
 examples/vhost/ioat.h                  |  47 ++++++
 examples/vhost/main.c                  |  93 +++++++++++-
 examples/vhost/main.h                  |   1 +
 examples/vhost/meson.build             |   5 +
 7 files changed, 359 insertions(+), 2 deletions(-)
 create mode 100644 examples/vhost/ioat.c
 create mode 100644 examples/vhost/ioat.h

--
2.27.0


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

* [dpdk-dev] [PATCH v9 1/4] example/vhost: add async vhost args parsing function
  2020-10-22  6:46               ` [dpdk-dev] [PATCH v9 0/4] add async data path in " Cheng Jiang
@ 2020-10-22  6:46                 ` Cheng Jiang
  2020-10-22  6:46                 ` [dpdk-dev] [PATCH v9 2/4] example/vhost: add support for vhost async data path Cheng Jiang
                                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-22  6:46 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang, Cheng Jiang

This patch is to add async vhost driver arguments parsing function
for CBDMA channel, DMA initiation function and args description.
The meson build file is changed to fix dependency problem. With
these arguments vhost device can be set to use CBDMA or CPU for
enqueue operation and bind vhost device with specific CBDMA channel
to accelerate data copy.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 examples/vhost/ioat.c      | 99 ++++++++++++++++++++++++++++++++++++++
 examples/vhost/ioat.h      | 35 ++++++++++++++
 examples/vhost/main.c      | 36 +++++++++++++-
 examples/vhost/meson.build |  5 ++
 4 files changed, 174 insertions(+), 1 deletion(-)
 create mode 100644 examples/vhost/ioat.c
 create mode 100644 examples/vhost/ioat.h

diff --git a/examples/vhost/ioat.c b/examples/vhost/ioat.c
new file mode 100644
index 000000000..52767d599
--- /dev/null
+++ b/examples/vhost/ioat.c
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2020 Intel Corporation
+ */
+#include <rte_rawdev.h>
+#include <rte_ioat_rawdev.h>
+
+#include "ioat.h"
+#include "main.h"
+
+int
+open_ioat(const char *value)
+{
+	struct dma_for_vhost *dma_info = dma_bind;
+	char *input = strndup(value, strlen(value) + 1);
+	char *addrs = input;
+	char *ptrs[2];
+	char *start, *end, *substr;
+	int64_t vid, vring_id;
+	struct rte_ioat_rawdev_config config;
+	struct rte_rawdev_info info = { .dev_private = &config };
+	char name[32];
+	int dev_id;
+	int ret = 0;
+	uint16_t i = 0;
+	char *dma_arg[MAX_VHOST_DEVICE];
+	uint8_t args_nr;
+
+	while (isblank(*addrs))
+		addrs++;
+	if (*addrs == '\0') {
+		ret = -1;
+		goto out;
+	}
+
+	/* process DMA devices within bracket. */
+	addrs++;
+	substr = strtok(addrs, ";]");
+	if (!substr) {
+		ret = -1;
+		goto out;
+	}
+	args_nr = rte_strsplit(substr, strlen(substr),
+			dma_arg, MAX_VHOST_DEVICE, ',');
+	do {
+		char *arg_temp = dma_arg[i];
+		rte_strsplit(arg_temp, strlen(arg_temp), ptrs, 2, '@');
+
+		start = strstr(ptrs[0], "txd");
+		if (start == NULL) {
+			ret = -1;
+			goto out;
+		}
+
+		start += 3;
+		vid = strtol(start, &end, 0);
+		if (end == start) {
+			ret = -1;
+			goto out;
+		}
+
+		vring_id = 0 + VIRTIO_RXQ;
+		if (rte_pci_addr_parse(ptrs[1],
+				&(dma_info + vid)->dmas[vring_id].addr) < 0) {
+			ret = -1;
+			goto out;
+		}
+
+		rte_pci_device_name(&(dma_info + vid)->dmas[vring_id].addr,
+				name, sizeof(name));
+		dev_id = rte_rawdev_get_dev_id(name);
+		if (dev_id == (uint16_t)(-ENODEV) ||
+		dev_id == (uint16_t)(-EINVAL)) {
+			ret = -1;
+			goto out;
+		}
+
+		if (rte_rawdev_info_get(dev_id, &info, sizeof(config)) < 0 ||
+		strstr(info.driver_name, "ioat") == NULL) {
+			ret = -1;
+			goto out;
+		}
+
+		(dma_info + vid)->dmas[vring_id].dev_id = dev_id;
+		(dma_info + vid)->dmas[vring_id].is_valid = true;
+		config.ring_size = IOAT_RING_SIZE;
+		config.hdls_disable = true;
+		if (rte_rawdev_configure(dev_id, &info, sizeof(config)) < 0) {
+			ret = -1;
+			goto out;
+		}
+		rte_rawdev_start(dev_id);
+
+		dma_info->nr++;
+		i++;
+	} while (i < args_nr);
+out:
+	free(input);
+	return ret;
+}
diff --git a/examples/vhost/ioat.h b/examples/vhost/ioat.h
new file mode 100644
index 000000000..02c1a8d35
--- /dev/null
+++ b/examples/vhost/ioat.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2020 Intel Corporation
+ */
+
+#ifndef _IOAT_H_
+#define _IOAT_H_
+
+#include <rte_vhost.h>
+#include <rte_pci.h>
+
+#define MAX_VHOST_DEVICE 1024
+#define IOAT_RING_SIZE 4096
+
+struct dma_info {
+	struct rte_pci_addr addr;
+	uint16_t dev_id;
+	bool is_valid;
+};
+
+struct dma_for_vhost {
+	struct dma_info dmas[RTE_MAX_QUEUES_PER_PORT * 2];
+	uint16_t nr;
+};
+
+struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
+
+#ifdef RTE_ARCH_X86
+int open_ioat(const char *value);
+#else
+static int open_ioat(const char *value __rte_unused)
+{
+	return -1;
+}
+#endif
+#endif /* _IOAT_H_ */
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index faa482245..08182ff01 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -25,6 +25,7 @@
 #include <rte_tcp.h>
 #include <rte_pause.h>
 
+#include "ioat.h"
 #include "main.h"
 
 #ifndef MAX_QUEUES
@@ -95,6 +96,10 @@ static int client_mode;
 
 static int builtin_net_driver;
 
+static int async_vhost_driver;
+
+static char dma_type[MAX_LONG_OPT_SZ];
+
 /* Specify timeout (in useconds) between retries on RX. */
 static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
 /* Specify the number of retries on RX. */
@@ -181,6 +186,15 @@ struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];
 				 / US_PER_S * BURST_TX_DRAIN_US)
 #define VLAN_HLEN       4
 
+static inline int
+open_dma(const char *value)
+{
+	if (strncmp(dma_type, "ioat", 4) == 0)
+		return open_ioat(value);
+
+	return -1;
+}
+
 /*
  * Builds up the correct configuration for VMDQ VLAN pool map
  * according to the pool & queue limits.
@@ -446,7 +460,9 @@ us_vhost_usage(const char *prgname)
 	"		--socket-file: The path of the socket file.\n"
 	"		--tx-csum [0|1] disable/enable TX checksum offload.\n"
 	"		--tso [0|1] disable/enable TCP segment offload.\n"
-	"		--client register a vhost-user socket as client mode.\n",
+	"		--client register a vhost-user socket as client mode.\n"
+	"		--dma-type register dma type for your vhost async driver. For example \"ioat\" for now.\n"
+	"		--dmas register dma channel for specific vhost device.\n",
 	       prgname);
 }
 
@@ -472,6 +488,8 @@ us_vhost_parse_args(int argc, char **argv)
 		{"tso", required_argument, NULL, 0},
 		{"client", no_argument, &client_mode, 1},
 		{"builtin-net-driver", no_argument, &builtin_net_driver, 1},
+		{"dma-type", required_argument, NULL, 0},
+		{"dmas", required_argument, NULL, 0},
 		{NULL, 0, 0, 0},
 	};
 
@@ -614,6 +632,22 @@ us_vhost_parse_args(int argc, char **argv)
 				}
 			}
 
+			if (!strncmp(long_option[option_index].name,
+						"dma-type", MAX_LONG_OPT_SZ)) {
+				strcpy(dma_type, optarg);
+			}
+
+			if (!strncmp(long_option[option_index].name,
+						"dmas", MAX_LONG_OPT_SZ)) {
+				if (open_dma(optarg) == -1) {
+					RTE_LOG(INFO, VHOST_CONFIG,
+						"Wrong DMA args\n");
+					us_vhost_usage(prgname);
+					return -1;
+				}
+				async_vhost_driver = 1;
+			}
+
 			break;
 
 			/* Invalid option - print options. */
diff --git a/examples/vhost/meson.build b/examples/vhost/meson.build
index 872d51153..24f1f7131 100644
--- a/examples/vhost/meson.build
+++ b/examples/vhost/meson.build
@@ -14,3 +14,8 @@ allow_experimental_apis = true
 sources = files(
 	'main.c', 'virtio_net.c'
 )
+
+if dpdk_conf.has('RTE_ARCH_X86')
+	deps += 'raw_ioat'
+	sources += files('ioat.c')
+endif
-- 
2.27.0


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

* [dpdk-dev] [PATCH v9 2/4] example/vhost: add support for vhost async data path
  2020-10-22  6:46               ` [dpdk-dev] [PATCH v9 0/4] add async data path in " Cheng Jiang
  2020-10-22  6:46                 ` [dpdk-dev] [PATCH v9 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
@ 2020-10-22  6:46                 ` Cheng Jiang
  2020-10-22  6:46                 ` [dpdk-dev] [PATCH v9 3/4] doc: update vhost sample doc " Cheng Jiang
                                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-22  6:46 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang, Cheng Jiang

This patch is to implement vhost DMA operation callbacks for CBDMA
PMD and add vhost async data-path in vhost sample. With providing
callback implementation for CBDMA, vswitch can leverage IOAT to
accelerate vhost async data-path.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 examples/vhost/ioat.c | 99 +++++++++++++++++++++++++++++++++++++++++++
 examples/vhost/ioat.h | 12 ++++++
 examples/vhost/main.c | 57 ++++++++++++++++++++++++-
 examples/vhost/main.h |  1 +
 4 files changed, 168 insertions(+), 1 deletion(-)

diff --git a/examples/vhost/ioat.c b/examples/vhost/ioat.c
index 52767d599..4c3ceb990 100644
--- a/examples/vhost/ioat.c
+++ b/examples/vhost/ioat.c
@@ -3,10 +3,20 @@
  */
 #include <rte_rawdev.h>
 #include <rte_ioat_rawdev.h>
+#include <sys/uio.h>
 
 #include "ioat.h"
 #include "main.h"
 
+struct packet_tracker {
+	unsigned short size_track[MAX_ENQUEUED_SIZE];
+	unsigned short next_read;
+	unsigned short next_write;
+	unsigned short last_remain;
+};
+
+struct packet_tracker cb_tracker[MAX_VHOST_DEVICE];
+
 int
 open_ioat(const char *value)
 {
@@ -97,3 +107,92 @@ open_ioat(const char *value)
 	free(input);
 	return ret;
 }
+
+uint32_t
+ioat_transfer_data_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_desc *descs,
+		struct rte_vhost_async_status *opaque_data, uint16_t count)
+{
+	uint32_t i_desc;
+	int dev_id = dma_bind[vid].dmas[queue_id * 2 + VIRTIO_RXQ].dev_id;
+	struct rte_vhost_iov_iter *src = NULL;
+	struct rte_vhost_iov_iter *dst = NULL;
+	unsigned long i_seg;
+	unsigned short mask = MAX_ENQUEUED_SIZE - 1;
+	unsigned short write = cb_tracker[dev_id].next_write;
+
+	if (!opaque_data) {
+		for (i_desc = 0; i_desc < count; i_desc++) {
+			src = descs[i_desc].src;
+			dst = descs[i_desc].dst;
+			i_seg = 0;
+			while (i_seg < src->nr_segs) {
+				/*
+				 * TODO: Assuming that the ring space of the
+				 * IOAT device is large enough, so there is no
+				 * error here, and the actual error handling
+				 * will be added later.
+				 */
+				rte_ioat_enqueue_copy(dev_id,
+					(uintptr_t)(src->iov[i_seg].iov_base)
+						+ src->offset,
+					(uintptr_t)(dst->iov[i_seg].iov_base)
+						+ dst->offset,
+					src->iov[i_seg].iov_len,
+					0,
+					0);
+				i_seg++;
+			}
+			write &= mask;
+			cb_tracker[dev_id].size_track[write] = i_seg;
+			write++;
+		}
+	} else {
+		/* Opaque data is not supported */
+		return -1;
+	}
+	/* ring the doorbell */
+	rte_ioat_perform_ops(dev_id);
+	cb_tracker[dev_id].next_write = write;
+	return i_desc;
+}
+
+uint32_t
+ioat_check_completed_copies_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_status *opaque_data,
+		uint16_t max_packets)
+{
+	if (!opaque_data) {
+		uintptr_t dump[255];
+		unsigned short n_seg;
+		unsigned short read, write;
+		unsigned short nb_packet = 0;
+		unsigned short mask = MAX_ENQUEUED_SIZE - 1;
+		unsigned short i;
+		int dev_id = dma_bind[vid].dmas[queue_id * 2
+				+ VIRTIO_RXQ].dev_id;
+		n_seg = rte_ioat_completed_ops(dev_id, 255, dump, dump);
+		n_seg += cb_tracker[dev_id].last_remain;
+		if (!n_seg)
+			return 0;
+		read = cb_tracker[dev_id].next_read;
+		write = cb_tracker[dev_id].next_write;
+		for (i = 0; i < max_packets; i++) {
+			read &= mask;
+			if (read == write)
+				break;
+			if (n_seg >= cb_tracker[dev_id].size_track[read]) {
+				n_seg -= cb_tracker[dev_id].size_track[read];
+				read++;
+				nb_packet++;
+			} else {
+				break;
+			}
+		}
+		cb_tracker[dev_id].next_read = read;
+		cb_tracker[dev_id].last_remain = n_seg;
+		return nb_packet;
+	}
+	/* Opaque data is not supported */
+	return -1;
+}
diff --git a/examples/vhost/ioat.h b/examples/vhost/ioat.h
index 02c1a8d35..c3bb8145a 100644
--- a/examples/vhost/ioat.h
+++ b/examples/vhost/ioat.h
@@ -7,9 +7,11 @@
 
 #include <rte_vhost.h>
 #include <rte_pci.h>
+#include <rte_vhost_async.h>
 
 #define MAX_VHOST_DEVICE 1024
 #define IOAT_RING_SIZE 4096
+#define MAX_ENQUEUED_SIZE 256
 
 struct dma_info {
 	struct rte_pci_addr addr;
@@ -32,4 +34,14 @@ static int open_ioat(const char *value __rte_unused)
 	return -1;
 }
 #endif
+
+uint32_t
+ioat_transfer_data_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_desc *descs,
+		struct rte_vhost_async_status *opaque_data, uint16_t count);
+
+uint32_t
+ioat_check_completed_copies_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_status *opaque_data,
+		uint16_t max_packets);
 #endif /* _IOAT_H_ */
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 08182ff01..59a1aff07 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -803,9 +803,22 @@ virtio_xmit(struct vhost_dev *dst_vdev, struct vhost_dev *src_vdev,
 	    struct rte_mbuf *m)
 {
 	uint16_t ret;
+	struct rte_mbuf *m_cpl[1];
 
 	if (builtin_net_driver) {
 		ret = vs_enqueue_pkts(dst_vdev, VIRTIO_RXQ, &m, 1);
+	} else if (async_vhost_driver) {
+		ret = rte_vhost_submit_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ,
+						&m, 1);
+
+		if (likely(ret))
+			dst_vdev->nr_async_pkts++;
+
+		while (likely(dst_vdev->nr_async_pkts)) {
+			if (rte_vhost_poll_enqueue_completed(dst_vdev->vid,
+					VIRTIO_RXQ, m_cpl, 1))
+				dst_vdev->nr_async_pkts--;
+		}
 	} else {
 		ret = rte_vhost_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ, &m, 1);
 	}
@@ -1054,6 +1067,19 @@ drain_mbuf_table(struct mbuf_table *tx_q)
 	}
 }
 
+static __rte_always_inline void
+complete_async_pkts(struct vhost_dev *vdev, uint16_t qid)
+{
+	struct rte_mbuf *p_cpl[MAX_PKT_BURST];
+	uint16_t complete_count;
+
+	complete_count = rte_vhost_poll_enqueue_completed(vdev->vid,
+						qid, p_cpl, MAX_PKT_BURST);
+	vdev->nr_async_pkts -= complete_count;
+	if (complete_count)
+		free_pkts(p_cpl, complete_count);
+}
+
 static __rte_always_inline void
 drain_eth_rx(struct vhost_dev *vdev)
 {
@@ -1062,6 +1088,10 @@ drain_eth_rx(struct vhost_dev *vdev)
 
 	rx_count = rte_eth_rx_burst(ports[0], vdev->vmdq_rx_q,
 				    pkts, MAX_PKT_BURST);
+
+	while (likely(vdev->nr_async_pkts))
+		complete_async_pkts(vdev, VIRTIO_RXQ);
+
 	if (!rx_count)
 		return;
 
@@ -1086,16 +1116,22 @@ drain_eth_rx(struct vhost_dev *vdev)
 	if (builtin_net_driver) {
 		enqueue_count = vs_enqueue_pkts(vdev, VIRTIO_RXQ,
 						pkts, rx_count);
+	} else if (async_vhost_driver) {
+		enqueue_count = rte_vhost_submit_enqueue_burst(vdev->vid,
+					VIRTIO_RXQ, pkts, rx_count);
+		vdev->nr_async_pkts += enqueue_count;
 	} else {
 		enqueue_count = rte_vhost_enqueue_burst(vdev->vid, VIRTIO_RXQ,
 						pkts, rx_count);
 	}
+
 	if (enable_stats) {
 		rte_atomic64_add(&vdev->stats.rx_total_atomic, rx_count);
 		rte_atomic64_add(&vdev->stats.rx_atomic, enqueue_count);
 	}
 
-	free_pkts(pkts, rx_count);
+	if (!async_vhost_driver)
+		free_pkts(pkts, rx_count);
 }
 
 static __rte_always_inline void
@@ -1242,6 +1278,9 @@ destroy_device(int vid)
 		"(%d) device has been removed from data core\n",
 		vdev->vid);
 
+	if (async_vhost_driver)
+		rte_vhost_async_channel_unregister(vid, VIRTIO_RXQ);
+
 	rte_free(vdev);
 }
 
@@ -1256,6 +1295,12 @@ new_device(int vid)
 	uint32_t device_num_min = num_devices;
 	struct vhost_dev *vdev;
 
+	struct rte_vhost_async_channel_ops channel_ops = {
+		.transfer_data = ioat_transfer_data_cb,
+		.check_completed_copies = ioat_check_completed_copies_cb
+	};
+	struct rte_vhost_async_features f;
+
 	vdev = rte_zmalloc("vhost device", sizeof(*vdev), RTE_CACHE_LINE_SIZE);
 	if (vdev == NULL) {
 		RTE_LOG(INFO, VHOST_DATA,
@@ -1296,6 +1341,13 @@ new_device(int vid)
 		"(%d) device has been added to data core %d\n",
 		vid, vdev->coreid);
 
+	if (async_vhost_driver) {
+		f.async_inorder = 1;
+		f.async_threshold = 256;
+		return rte_vhost_async_channel_register(vid, VIRTIO_RXQ,
+			f.intval, &channel_ops);
+	}
+
 	return 0;
 }
 
@@ -1534,6 +1586,9 @@ main(int argc, char *argv[])
 	/* Register vhost user driver to handle vhost messages. */
 	for (i = 0; i < nb_sockets; i++) {
 		char *file = socket_files + i * PATH_MAX;
+		if (async_vhost_driver)
+			flags = flags | RTE_VHOST_USER_ASYNC_COPY;
+
 		ret = rte_vhost_driver_register(file, flags);
 		if (ret != 0) {
 			unregister_drivers(i);
diff --git a/examples/vhost/main.h b/examples/vhost/main.h
index 7cba0edbf..4317b6ae8 100644
--- a/examples/vhost/main.h
+++ b/examples/vhost/main.h
@@ -51,6 +51,7 @@ struct vhost_dev {
 	uint64_t features;
 	size_t hdr_len;
 	uint16_t nr_vrings;
+	uint16_t nr_async_pkts;
 	struct rte_vhost_memory *mem;
 	struct device_statistics stats;
 	TAILQ_ENTRY(vhost_dev) global_vdev_entry;
-- 
2.27.0


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

* [dpdk-dev] [PATCH v9 3/4] doc: update vhost sample doc for vhost async data path
  2020-10-22  6:46               ` [dpdk-dev] [PATCH v9 0/4] add async data path in " Cheng Jiang
  2020-10-22  6:46                 ` [dpdk-dev] [PATCH v9 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
  2020-10-22  6:46                 ` [dpdk-dev] [PATCH v9 2/4] example/vhost: add support for vhost async data path Cheng Jiang
@ 2020-10-22  6:46                 ` Cheng Jiang
  2020-10-22  6:46                 ` [dpdk-dev] [PATCH v9 4/4] doc: update release notes for vhost sample Cheng Jiang
  2020-10-22  9:10                 ` [dpdk-dev] [PATCH v9 0/4] add async data path in " Maxime Coquelin
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-22  6:46 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang, Cheng Jiang

Add vhost async driver arguments information for vhost async data
path in vhost sample application.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 doc/guides/sample_app_ug/vhost.rst | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/doc/guides/sample_app_ug/vhost.rst b/doc/guides/sample_app_ug/vhost.rst
index b7ed4f8bd..0f4f70945 100644
--- a/doc/guides/sample_app_ug/vhost.rst
+++ b/doc/guides/sample_app_ug/vhost.rst
@@ -162,6 +162,17 @@ enabled and cannot be disabled.
 A very simple vhost-user net driver which demonstrates how to use the generic
 vhost APIs will be used when this option is given. It is disabled by default.
 
+**--dma-type**
+This parameter is used to specify DMA type for async vhost-user net driver which
+demonstrates how to use the async vhost APIs. It's used in combination with dmas.
+
+**--dmas**
+This parameter is used to specify the assigned DMA device of a vhost device.
+Async vhost-user net driver will be used if --dmas is set. For example
+--dmas [txd0@00:04.0,txd1@00:04.1] means use DMA channel 00:04.0 for vhost
+device 0 enqueue operation and use DMA channel 00:04.1 for vhost device 1
+enqueue operation.
+
 Common Issues
 -------------
 
-- 
2.27.0


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

* [dpdk-dev] [PATCH v9 4/4] doc: update release notes for vhost sample
  2020-10-22  6:46               ` [dpdk-dev] [PATCH v9 0/4] add async data path in " Cheng Jiang
                                   ` (2 preceding siblings ...)
  2020-10-22  6:46                 ` [dpdk-dev] [PATCH v9 3/4] doc: update vhost sample doc " Cheng Jiang
@ 2020-10-22  6:46                 ` Cheng Jiang
  2020-10-22  9:10                 ` [dpdk-dev] [PATCH v9 0/4] add async data path in " Maxime Coquelin
  4 siblings, 0 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-22  6:46 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang, Cheng Jiang

Add release notes for vhost async data path support in vhost sample.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 doc/guides/rel_notes/release_20_11.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst
index 0d45b5003..f2db063e0 100644
--- a/doc/guides/rel_notes/release_20_11.rst
+++ b/doc/guides/rel_notes/release_20_11.rst
@@ -345,6 +345,12 @@ New Features
   * Replaced ``--scalar`` command-line option with ``--alg=<value>``, to allow
     the user to select the desired classify method.
 
+* **Updated vhost sample application.**
+
+  Added vhost asynchronous APIs support, which demonstrated how the application
+  leverage IOAT DMA channel with vhost asynchronous APIs.
+  See the :doc:`../sample_app_ug/vhost` for more details.
+
 
 Removed Items
 -------------
-- 
2.27.0


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

* [dpdk-dev] [PATCH v10 0/4] add async data path in vhost sample
  2020-09-10  6:43 [dpdk-dev] [PATCH v1 0/4] add async data path in vhost sample Cheng Jiang
                   ` (4 preceding siblings ...)
  2020-09-29  6:42 ` [dpdk-dev] [PATCH v2 0/4] add async data path in " Cheng Jiang
@ 2020-10-22  8:59 ` Cheng Jiang
  2020-10-22  8:59   ` [dpdk-dev] [PATCH v10 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
                     ` (4 more replies)
  5 siblings, 5 replies; 71+ messages in thread
From: Cheng Jiang @ 2020-10-22  8:59 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang, Cheng Jiang

This patch set makes vhost-vswitch be able to use vhost async APIs
for enqueue operations. Demonstrated how the application
leverage IOAT DMA channel with vhost async APIs.

We introduce two parameters to enable DMA acceleration for Tx
operations of queues:
-dma_type This parameter is used to specify DMA type for async
vhost-user net driver.
-dmas This parameter is used to specify the assigned DMA device of a
vhost device and enable async vhost data path.

---
v10:
 * Fixed compilation issue on specific environment

v9:
 * Optimized code structure to solve compilation issue on non-x86 platforms

v8:
 * Changed meson build file due to the change of ioat component name

v7:
 * Improved IOAT callbacks and added some comments

v6:
 * Cleand code and rebased for latest code

v5:
 * Improved meson build file and fixed dependency problem

v4:
 * Code rebased for latest IOAT driver

v3:
 * Fixed a coding style problem

v2:
 * Changed meson build file to fix dependency problem
 * Added parameter description in usage function
 * Optimized parameter settings and parsing function
 * Optimized abstraction, moved some code to ioat.c

Cheng Jiang (4):
  example/vhost: add async vhost args parsing function
  example/vhost: add support for vhost async data path
  doc: update vhost sample doc for vhost async data path
  doc: update release notes for vhost sample

 doc/guides/rel_notes/release_20_11.rst |   6 +
 doc/guides/sample_app_ug/vhost.rst     |  11 ++
 examples/vhost/ioat.c                  | 201 +++++++++++++++++++++++++
 examples/vhost/ioat.h                  |  45 ++++++
 examples/vhost/main.c                  |  93 +++++++++++-
 examples/vhost/main.h                  |   1 +
 examples/vhost/meson.build             |   5 +
 7 files changed, 360 insertions(+), 2 deletions(-)
 create mode 100644 examples/vhost/ioat.c
 create mode 100644 examples/vhost/ioat.h

--
2.27.0


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

* [dpdk-dev] [PATCH v10 1/4] example/vhost: add async vhost args parsing function
  2020-10-22  8:59 ` [dpdk-dev] [PATCH v10 " Cheng Jiang
@ 2020-10-22  8:59   ` Cheng Jiang
  2020-10-23 11:08     ` Maxime Coquelin
  2020-10-22  8:59   ` [dpdk-dev] [PATCH v10 2/4] example/vhost: add support for vhost async data path Cheng Jiang
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 71+ messages in thread
From: Cheng Jiang @ 2020-10-22  8:59 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang, Cheng Jiang

This patch is to add async vhost driver arguments parsing function
for CBDMA channel, DMA initiation function and args description.
The meson build file is changed to fix dependency problem. With
these arguments vhost device can be set to use CBDMA or CPU for
enqueue operation and bind vhost device with specific CBDMA channel
to accelerate data copy.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 examples/vhost/ioat.c      | 101 +++++++++++++++++++++++++++++++++++++
 examples/vhost/ioat.h      |  33 ++++++++++++
 examples/vhost/main.c      |  36 ++++++++++++-
 examples/vhost/meson.build |   5 ++
 4 files changed, 174 insertions(+), 1 deletion(-)
 create mode 100644 examples/vhost/ioat.c
 create mode 100644 examples/vhost/ioat.h

diff --git a/examples/vhost/ioat.c b/examples/vhost/ioat.c
new file mode 100644
index 000000000..8cf44cb54
--- /dev/null
+++ b/examples/vhost/ioat.c
@@ -0,0 +1,101 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2020 Intel Corporation
+ */
+#include <rte_rawdev.h>
+#include <rte_ioat_rawdev.h>
+
+#include "ioat.h"
+#include "main.h"
+
+struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
+
+int
+open_ioat(const char *value)
+{
+	struct dma_for_vhost *dma_info = dma_bind;
+	char *input = strndup(value, strlen(value) + 1);
+	char *addrs = input;
+	char *ptrs[2];
+	char *start, *end, *substr;
+	int64_t vid, vring_id;
+	struct rte_ioat_rawdev_config config;
+	struct rte_rawdev_info info = { .dev_private = &config };
+	char name[32];
+	int dev_id;
+	int ret = 0;
+	uint16_t i = 0;
+	char *dma_arg[MAX_VHOST_DEVICE];
+	uint8_t args_nr;
+
+	while (isblank(*addrs))
+		addrs++;
+	if (*addrs == '\0') {
+		ret = -1;
+		goto out;
+	}
+
+	/* process DMA devices within bracket. */
+	addrs++;
+	substr = strtok(addrs, ";]");
+	if (!substr) {
+		ret = -1;
+		goto out;
+	}
+	args_nr = rte_strsplit(substr, strlen(substr),
+			dma_arg, MAX_VHOST_DEVICE, ',');
+	do {
+		char *arg_temp = dma_arg[i];
+		rte_strsplit(arg_temp, strlen(arg_temp), ptrs, 2, '@');
+
+		start = strstr(ptrs[0], "txd");
+		if (start == NULL) {
+			ret = -1;
+			goto out;
+		}
+
+		start += 3;
+		vid = strtol(start, &end, 0);
+		if (end == start) {
+			ret = -1;
+			goto out;
+		}
+
+		vring_id = 0 + VIRTIO_RXQ;
+		if (rte_pci_addr_parse(ptrs[1],
+				&(dma_info + vid)->dmas[vring_id].addr) < 0) {
+			ret = -1;
+			goto out;
+		}
+
+		rte_pci_device_name(&(dma_info + vid)->dmas[vring_id].addr,
+				name, sizeof(name));
+		dev_id = rte_rawdev_get_dev_id(name);
+		if (dev_id == (uint16_t)(-ENODEV) ||
+		dev_id == (uint16_t)(-EINVAL)) {
+			ret = -1;
+			goto out;
+		}
+
+		if (rte_rawdev_info_get(dev_id, &info, sizeof(config)) < 0 ||
+		strstr(info.driver_name, "ioat") == NULL) {
+			ret = -1;
+			goto out;
+		}
+
+		(dma_info + vid)->dmas[vring_id].dev_id = dev_id;
+		(dma_info + vid)->dmas[vring_id].is_valid = true;
+		config.ring_size = IOAT_RING_SIZE;
+		config.hdls_disable = true;
+		if (rte_rawdev_configure(dev_id, &info, sizeof(config)) < 0) {
+			ret = -1;
+			goto out;
+		}
+		rte_rawdev_start(dev_id);
+
+		dma_info->nr++;
+		i++;
+	} while (i < args_nr);
+out:
+	free(input);
+	return ret;
+}
diff --git a/examples/vhost/ioat.h b/examples/vhost/ioat.h
new file mode 100644
index 000000000..9641286a9
--- /dev/null
+++ b/examples/vhost/ioat.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2020 Intel Corporation
+ */
+
+#ifndef _IOAT_H_
+#define _IOAT_H_
+
+#include <rte_vhost.h>
+#include <rte_pci.h>
+
+#define MAX_VHOST_DEVICE 1024
+#define IOAT_RING_SIZE 4096
+
+struct dma_info {
+	struct rte_pci_addr addr;
+	uint16_t dev_id;
+	bool is_valid;
+};
+
+struct dma_for_vhost {
+	struct dma_info dmas[RTE_MAX_QUEUES_PER_PORT * 2];
+	uint16_t nr;
+};
+
+#ifdef RTE_ARCH_X86
+int open_ioat(const char *value);
+#else
+static int open_ioat(const char *value __rte_unused)
+{
+	return -1;
+}
+#endif
+#endif /* _IOAT_H_ */
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index faa482245..08182ff01 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -25,6 +25,7 @@
 #include <rte_tcp.h>
 #include <rte_pause.h>
 
+#include "ioat.h"
 #include "main.h"
 
 #ifndef MAX_QUEUES
@@ -95,6 +96,10 @@ static int client_mode;
 
 static int builtin_net_driver;
 
+static int async_vhost_driver;
+
+static char dma_type[MAX_LONG_OPT_SZ];
+
 /* Specify timeout (in useconds) between retries on RX. */
 static uint32_t burst_rx_delay_time = BURST_RX_WAIT_US;
 /* Specify the number of retries on RX. */
@@ -181,6 +186,15 @@ struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];
 				 / US_PER_S * BURST_TX_DRAIN_US)
 #define VLAN_HLEN       4
 
+static inline int
+open_dma(const char *value)
+{
+	if (strncmp(dma_type, "ioat", 4) == 0)
+		return open_ioat(value);
+
+	return -1;
+}
+
 /*
  * Builds up the correct configuration for VMDQ VLAN pool map
  * according to the pool & queue limits.
@@ -446,7 +460,9 @@ us_vhost_usage(const char *prgname)
 	"		--socket-file: The path of the socket file.\n"
 	"		--tx-csum [0|1] disable/enable TX checksum offload.\n"
 	"		--tso [0|1] disable/enable TCP segment offload.\n"
-	"		--client register a vhost-user socket as client mode.\n",
+	"		--client register a vhost-user socket as client mode.\n"
+	"		--dma-type register dma type for your vhost async driver. For example \"ioat\" for now.\n"
+	"		--dmas register dma channel for specific vhost device.\n",
 	       prgname);
 }
 
@@ -472,6 +488,8 @@ us_vhost_parse_args(int argc, char **argv)
 		{"tso", required_argument, NULL, 0},
 		{"client", no_argument, &client_mode, 1},
 		{"builtin-net-driver", no_argument, &builtin_net_driver, 1},
+		{"dma-type", required_argument, NULL, 0},
+		{"dmas", required_argument, NULL, 0},
 		{NULL, 0, 0, 0},
 	};
 
@@ -614,6 +632,22 @@ us_vhost_parse_args(int argc, char **argv)
 				}
 			}
 
+			if (!strncmp(long_option[option_index].name,
+						"dma-type", MAX_LONG_OPT_SZ)) {
+				strcpy(dma_type, optarg);
+			}
+
+			if (!strncmp(long_option[option_index].name,
+						"dmas", MAX_LONG_OPT_SZ)) {
+				if (open_dma(optarg) == -1) {
+					RTE_LOG(INFO, VHOST_CONFIG,
+						"Wrong DMA args\n");
+					us_vhost_usage(prgname);
+					return -1;
+				}
+				async_vhost_driver = 1;
+			}
+
 			break;
 
 			/* Invalid option - print options. */
diff --git a/examples/vhost/meson.build b/examples/vhost/meson.build
index 872d51153..24f1f7131 100644
--- a/examples/vhost/meson.build
+++ b/examples/vhost/meson.build
@@ -14,3 +14,8 @@ allow_experimental_apis = true
 sources = files(
 	'main.c', 'virtio_net.c'
 )
+
+if dpdk_conf.has('RTE_ARCH_X86')
+	deps += 'raw_ioat'
+	sources += files('ioat.c')
+endif
-- 
2.27.0


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

* [dpdk-dev] [PATCH v10 2/4] example/vhost: add support for vhost async data path
  2020-10-22  8:59 ` [dpdk-dev] [PATCH v10 " Cheng Jiang
  2020-10-22  8:59   ` [dpdk-dev] [PATCH v10 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
@ 2020-10-22  8:59   ` Cheng Jiang
  2020-10-23 11:12     ` Maxime Coquelin
  2020-10-22  8:59   ` [dpdk-dev] [PATCH v10 3/4] doc: update vhost sample doc " Cheng Jiang
                     ` (2 subsequent siblings)
  4 siblings, 1 reply; 71+ messages in thread
From: Cheng Jiang @ 2020-10-22  8:59 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang, Cheng Jiang

This patch is to implement vhost DMA operation callbacks for CBDMA
PMD and add vhost async data-path in vhost sample. With providing
callback implementation for CBDMA, vswitch can leverage IOAT to
accelerate vhost async data-path.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 examples/vhost/ioat.c | 100 ++++++++++++++++++++++++++++++++++++++++++
 examples/vhost/ioat.h |  12 +++++
 examples/vhost/main.c |  57 +++++++++++++++++++++++-
 examples/vhost/main.h |   1 +
 4 files changed, 169 insertions(+), 1 deletion(-)

diff --git a/examples/vhost/ioat.c b/examples/vhost/ioat.c
index 8cf44cb54..b2c74f653 100644
--- a/examples/vhost/ioat.c
+++ b/examples/vhost/ioat.c
@@ -3,12 +3,23 @@
  */
 #include <rte_rawdev.h>
 #include <rte_ioat_rawdev.h>
+#include <sys/uio.h>
 
 #include "ioat.h"
 #include "main.h"
 
 struct dma_for_vhost dma_bind[MAX_VHOST_DEVICE];
 
+struct packet_tracker {
+	unsigned short size_track[MAX_ENQUEUED_SIZE];
+	unsigned short next_read;
+	unsigned short next_write;
+	unsigned short last_remain;
+};
+
+struct packet_tracker cb_tracker[MAX_VHOST_DEVICE];
+
+
 int
 open_ioat(const char *value)
 {
@@ -99,3 +110,92 @@ open_ioat(const char *value)
 	free(input);
 	return ret;
 }
+
+uint32_t
+ioat_transfer_data_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_desc *descs,
+		struct rte_vhost_async_status *opaque_data, uint16_t count)
+{
+	uint32_t i_desc;
+	int dev_id = dma_bind[vid].dmas[queue_id * 2 + VIRTIO_RXQ].dev_id;
+	struct rte_vhost_iov_iter *src = NULL;
+	struct rte_vhost_iov_iter *dst = NULL;
+	unsigned long i_seg;
+	unsigned short mask = MAX_ENQUEUED_SIZE - 1;
+	unsigned short write = cb_tracker[dev_id].next_write;
+
+	if (!opaque_data) {
+		for (i_desc = 0; i_desc < count; i_desc++) {
+			src = descs[i_desc].src;
+			dst = descs[i_desc].dst;
+			i_seg = 0;
+			while (i_seg < src->nr_segs) {
+				/*
+				 * TODO: Assuming that the ring space of the
+				 * IOAT device is large enough, so there is no
+				 * error here, and the actual error handling
+				 * will be added later.
+				 */
+				rte_ioat_enqueue_copy(dev_id,
+					(uintptr_t)(src->iov[i_seg].iov_base)
+						+ src->offset,
+					(uintptr_t)(dst->iov[i_seg].iov_base)
+						+ dst->offset,
+					src->iov[i_seg].iov_len,
+					0,
+					0);
+				i_seg++;
+			}
+			write &= mask;
+			cb_tracker[dev_id].size_track[write] = i_seg;
+			write++;
+		}
+	} else {
+		/* Opaque data is not supported */
+		return -1;
+	}
+	/* ring the doorbell */
+	rte_ioat_perform_ops(dev_id);
+	cb_tracker[dev_id].next_write = write;
+	return i_desc;
+}
+
+uint32_t
+ioat_check_completed_copies_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_status *opaque_data,
+		uint16_t max_packets)
+{
+	if (!opaque_data) {
+		uintptr_t dump[255];
+		unsigned short n_seg;
+		unsigned short read, write;
+		unsigned short nb_packet = 0;
+		unsigned short mask = MAX_ENQUEUED_SIZE - 1;
+		unsigned short i;
+		int dev_id = dma_bind[vid].dmas[queue_id * 2
+				+ VIRTIO_RXQ].dev_id;
+		n_seg = rte_ioat_completed_ops(dev_id, 255, dump, dump);
+		n_seg += cb_tracker[dev_id].last_remain;
+		if (!n_seg)
+			return 0;
+		read = cb_tracker[dev_id].next_read;
+		write = cb_tracker[dev_id].next_write;
+		for (i = 0; i < max_packets; i++) {
+			read &= mask;
+			if (read == write)
+				break;
+			if (n_seg >= cb_tracker[dev_id].size_track[read]) {
+				n_seg -= cb_tracker[dev_id].size_track[read];
+				read++;
+				nb_packet++;
+			} else {
+				break;
+			}
+		}
+		cb_tracker[dev_id].next_read = read;
+		cb_tracker[dev_id].last_remain = n_seg;
+		return nb_packet;
+	}
+	/* Opaque data is not supported */
+	return -1;
+}
diff --git a/examples/vhost/ioat.h b/examples/vhost/ioat.h
index 9641286a9..9664fcc3a 100644
--- a/examples/vhost/ioat.h
+++ b/examples/vhost/ioat.h
@@ -7,9 +7,11 @@
 
 #include <rte_vhost.h>
 #include <rte_pci.h>
+#include <rte_vhost_async.h>
 
 #define MAX_VHOST_DEVICE 1024
 #define IOAT_RING_SIZE 4096
+#define MAX_ENQUEUED_SIZE 256
 
 struct dma_info {
 	struct rte_pci_addr addr;
@@ -30,4 +32,14 @@ static int open_ioat(const char *value __rte_unused)
 	return -1;
 }
 #endif
+
+uint32_t
+ioat_transfer_data_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_desc *descs,
+		struct rte_vhost_async_status *opaque_data, uint16_t count);
+
+uint32_t
+ioat_check_completed_copies_cb(int vid, uint16_t queue_id,
+		struct rte_vhost_async_status *opaque_data,
+		uint16_t max_packets);
 #endif /* _IOAT_H_ */
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 08182ff01..59a1aff07 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -803,9 +803,22 @@ virtio_xmit(struct vhost_dev *dst_vdev, struct vhost_dev *src_vdev,
 	    struct rte_mbuf *m)
 {
 	uint16_t ret;
+	struct rte_mbuf *m_cpl[1];
 
 	if (builtin_net_driver) {
 		ret = vs_enqueue_pkts(dst_vdev, VIRTIO_RXQ, &m, 1);
+	} else if (async_vhost_driver) {
+		ret = rte_vhost_submit_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ,
+						&m, 1);
+
+		if (likely(ret))
+			dst_vdev->nr_async_pkts++;
+
+		while (likely(dst_vdev->nr_async_pkts)) {
+			if (rte_vhost_poll_enqueue_completed(dst_vdev->vid,
+					VIRTIO_RXQ, m_cpl, 1))
+				dst_vdev->nr_async_pkts--;
+		}
 	} else {
 		ret = rte_vhost_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ, &m, 1);
 	}
@@ -1054,6 +1067,19 @@ drain_mbuf_table(struct mbuf_table *tx_q)
 	}
 }
 
+static __rte_always_inline void
+complete_async_pkts(struct vhost_dev *vdev, uint16_t qid)
+{
+	struct rte_mbuf *p_cpl[MAX_PKT_BURST];
+	uint16_t complete_count;
+
+	complete_count = rte_vhost_poll_enqueue_completed(vdev->vid,
+						qid, p_cpl, MAX_PKT_BURST);
+	vdev->nr_async_pkts -= complete_count;
+	if (complete_count)
+		free_pkts(p_cpl, complete_count);
+}
+
 static __rte_always_inline void
 drain_eth_rx(struct vhost_dev *vdev)
 {
@@ -1062,6 +1088,10 @@ drain_eth_rx(struct vhost_dev *vdev)
 
 	rx_count = rte_eth_rx_burst(ports[0], vdev->vmdq_rx_q,
 				    pkts, MAX_PKT_BURST);
+
+	while (likely(vdev->nr_async_pkts))
+		complete_async_pkts(vdev, VIRTIO_RXQ);
+
 	if (!rx_count)
 		return;
 
@@ -1086,16 +1116,22 @@ drain_eth_rx(struct vhost_dev *vdev)
 	if (builtin_net_driver) {
 		enqueue_count = vs_enqueue_pkts(vdev, VIRTIO_RXQ,
 						pkts, rx_count);
+	} else if (async_vhost_driver) {
+		enqueue_count = rte_vhost_submit_enqueue_burst(vdev->vid,
+					VIRTIO_RXQ, pkts, rx_count);
+		vdev->nr_async_pkts += enqueue_count;
 	} else {
 		enqueue_count = rte_vhost_enqueue_burst(vdev->vid, VIRTIO_RXQ,
 						pkts, rx_count);
 	}
+
 	if (enable_stats) {
 		rte_atomic64_add(&vdev->stats.rx_total_atomic, rx_count);
 		rte_atomic64_add(&vdev->stats.rx_atomic, enqueue_count);
 	}
 
-	free_pkts(pkts, rx_count);
+	if (!async_vhost_driver)
+		free_pkts(pkts, rx_count);
 }
 
 static __rte_always_inline void
@@ -1242,6 +1278,9 @@ destroy_device(int vid)
 		"(%d) device has been removed from data core\n",
 		vdev->vid);
 
+	if (async_vhost_driver)
+		rte_vhost_async_channel_unregister(vid, VIRTIO_RXQ);
+
 	rte_free(vdev);
 }
 
@@ -1256,6 +1295,12 @@ new_device(int vid)
 	uint32_t device_num_min = num_devices;
 	struct vhost_dev *vdev;
 
+	struct rte_vhost_async_channel_ops channel_ops = {
+		.transfer_data = ioat_transfer_data_cb,
+		.check_completed_copies = ioat_check_completed_copies_cb
+	};
+	struct rte_vhost_async_features f;
+
 	vdev = rte_zmalloc("vhost device", sizeof(*vdev), RTE_CACHE_LINE_SIZE);
 	if (vdev == NULL) {
 		RTE_LOG(INFO, VHOST_DATA,
@@ -1296,6 +1341,13 @@ new_device(int vid)
 		"(%d) device has been added to data core %d\n",
 		vid, vdev->coreid);
 
+	if (async_vhost_driver) {
+		f.async_inorder = 1;
+		f.async_threshold = 256;
+		return rte_vhost_async_channel_register(vid, VIRTIO_RXQ,
+			f.intval, &channel_ops);
+	}
+
 	return 0;
 }
 
@@ -1534,6 +1586,9 @@ main(int argc, char *argv[])
 	/* Register vhost user driver to handle vhost messages. */
 	for (i = 0; i < nb_sockets; i++) {
 		char *file = socket_files + i * PATH_MAX;
+		if (async_vhost_driver)
+			flags = flags | RTE_VHOST_USER_ASYNC_COPY;
+
 		ret = rte_vhost_driver_register(file, flags);
 		if (ret != 0) {
 			unregister_drivers(i);
diff --git a/examples/vhost/main.h b/examples/vhost/main.h
index 7cba0edbf..4317b6ae8 100644
--- a/examples/vhost/main.h
+++ b/examples/vhost/main.h
@@ -51,6 +51,7 @@ struct vhost_dev {
 	uint64_t features;
 	size_t hdr_len;
 	uint16_t nr_vrings;
+	uint16_t nr_async_pkts;
 	struct rte_vhost_memory *mem;
 	struct device_statistics stats;
 	TAILQ_ENTRY(vhost_dev) global_vdev_entry;
-- 
2.27.0


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

* [dpdk-dev] [PATCH v10 3/4] doc: update vhost sample doc for vhost async data path
  2020-10-22  8:59 ` [dpdk-dev] [PATCH v10 " Cheng Jiang
  2020-10-22  8:59   ` [dpdk-dev] [PATCH v10 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
  2020-10-22  8:59   ` [dpdk-dev] [PATCH v10 2/4] example/vhost: add support for vhost async data path Cheng Jiang
@ 2020-10-22  8:59   ` Cheng Jiang
  2020-10-23 11:15     ` Maxime Coquelin
  2020-10-22  8:59   ` [dpdk-dev] [PATCH v10 4/4] doc: update release notes for vhost sample Cheng Jiang
  2020-10-23 11:23   ` [dpdk-dev] [PATCH v10 0/4] add async data path in " Maxime Coquelin
  4 siblings, 1 reply; 71+ messages in thread
From: Cheng Jiang @ 2020-10-22  8:59 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang, Cheng Jiang

Add vhost async driver arguments information for vhost async data
path in vhost sample application.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 doc/guides/sample_app_ug/vhost.rst | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/doc/guides/sample_app_ug/vhost.rst b/doc/guides/sample_app_ug/vhost.rst
index b7ed4f8bd..0f4f70945 100644
--- a/doc/guides/sample_app_ug/vhost.rst
+++ b/doc/guides/sample_app_ug/vhost.rst
@@ -162,6 +162,17 @@ enabled and cannot be disabled.
 A very simple vhost-user net driver which demonstrates how to use the generic
 vhost APIs will be used when this option is given. It is disabled by default.
 
+**--dma-type**
+This parameter is used to specify DMA type for async vhost-user net driver which
+demonstrates how to use the async vhost APIs. It's used in combination with dmas.
+
+**--dmas**
+This parameter is used to specify the assigned DMA device of a vhost device.
+Async vhost-user net driver will be used if --dmas is set. For example
+--dmas [txd0@00:04.0,txd1@00:04.1] means use DMA channel 00:04.0 for vhost
+device 0 enqueue operation and use DMA channel 00:04.1 for vhost device 1
+enqueue operation.
+
 Common Issues
 -------------
 
-- 
2.27.0


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

* [dpdk-dev] [PATCH v10 4/4] doc: update release notes for vhost sample
  2020-10-22  8:59 ` [dpdk-dev] [PATCH v10 " Cheng Jiang
                     ` (2 preceding siblings ...)
  2020-10-22  8:59   ` [dpdk-dev] [PATCH v10 3/4] doc: update vhost sample doc " Cheng Jiang
@ 2020-10-22  8:59   ` Cheng Jiang
  2020-10-23 11:15     ` Maxime Coquelin
  2020-10-23 11:23   ` [dpdk-dev] [PATCH v10 0/4] add async data path in " Maxime Coquelin
  4 siblings, 1 reply; 71+ messages in thread
From: Cheng Jiang @ 2020-10-22  8:59 UTC (permalink / raw)
  To: maxime.coquelin, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang, Cheng Jiang

Add release notes for vhost async data path support in vhost sample.

Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
---
 doc/guides/rel_notes/release_20_11.rst | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst
index 0d45b5003..f2db063e0 100644
--- a/doc/guides/rel_notes/release_20_11.rst
+++ b/doc/guides/rel_notes/release_20_11.rst
@@ -345,6 +345,12 @@ New Features
   * Replaced ``--scalar`` command-line option with ``--alg=<value>``, to allow
     the user to select the desired classify method.
 
+* **Updated vhost sample application.**
+
+  Added vhost asynchronous APIs support, which demonstrated how the application
+  leverage IOAT DMA channel with vhost asynchronous APIs.
+  See the :doc:`../sample_app_ug/vhost` for more details.
+
 
 Removed Items
 -------------
-- 
2.27.0


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

* Re: [dpdk-dev] [PATCH v9 0/4] add async data path in vhost sample
  2020-10-22  6:46               ` [dpdk-dev] [PATCH v9 0/4] add async data path in " Cheng Jiang
                                   ` (3 preceding siblings ...)
  2020-10-22  6:46                 ` [dpdk-dev] [PATCH v9 4/4] doc: update release notes for vhost sample Cheng Jiang
@ 2020-10-22  9:10                 ` Maxime Coquelin
  2020-10-22  9:14                   ` Jiang, Cheng1
  4 siblings, 1 reply; 71+ messages in thread
From: Maxime Coquelin @ 2020-10-22  9:10 UTC (permalink / raw)
  To: Cheng Jiang, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang

Hi,

On 10/22/20 8:46 AM, Cheng Jiang wrote:
> This patch set makes vhost-vswitch be able to use vhost async APIs
> for enqueue operations. Demonstrated how the application
> leverage IOAT DMA channel with vhost async APIs.
> 
> We introduce two parameters to enable DMA acceleration for Tx
> operations of queues:
> -dma_type This parameter is used to specify DMA type for async
> vhost-user net driver.
> -dmas This parameter is used to specify the assigned DMA device of a
> vhost device and enable async vhost data path.
> 
> ---
> v9:
>  * Optimized code structure to solve compilation issue on non-x86 platforms
> 
> v8:
>  * Changed meson build file due to the change of ioat component name
> 
> v7:
>  * Improved IOAT callbacks and added some comments
> 
> v6:
>  * Cleand code and rebased for latest code
> 
> v5:
>  * Improved meson build file and fixed dependency problem
> 
> v4:
>  * Code rebased for latest IOAT driver
> 
> v3:
>  * Fixed a coding style problem
> 
> v2:
>  * Changed meson build file to fix dependency problem
>  * Added parameter description in usage function
>  * Optimized parameter settings and parsing function
>  * Optimized abstraction, moved some code to ioat.c
> 
> Cheng Jiang (4):
>   example/vhost: add async vhost args parsing function
>   example/vhost: add support for vhost async data path
>   doc: update vhost sample doc for vhost async data path
>   doc: update release notes for vhost sample
> 
>  doc/guides/rel_notes/release_20_11.rst |   6 +
>  doc/guides/sample_app_ug/vhost.rst     |  11 ++
>  examples/vhost/ioat.c                  | 198 +++++++++++++++++++++++++
>  examples/vhost/ioat.h                  |  47 ++++++
>  examples/vhost/main.c                  |  93 +++++++++++-
>  examples/vhost/main.h                  |   1 +
>  examples/vhost/meson.build             |   5 +
>  7 files changed, 359 insertions(+), 2 deletions(-)
>  create mode 100644 examples/vhost/ioat.c
>  create mode 100644 examples/vhost/ioat.h
> 
> --
> 2.27.0
> 

It does not build:
http://mails.dpdk.org/archives/test-report/2020-October/161193.html

Maxime


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

* Re: [dpdk-dev] [PATCH v9 0/4] add async data path in vhost sample
  2020-10-22  9:10                 ` [dpdk-dev] [PATCH v9 0/4] add async data path in " Maxime Coquelin
@ 2020-10-22  9:14                   ` Jiang, Cheng1
  0 siblings, 0 replies; 71+ messages in thread
From: Jiang, Cheng1 @ 2020-10-22  9:14 UTC (permalink / raw)
  To: Maxime Coquelin, Xia, Chenbo; +Cc: dev, Fu, Patrick, Yang, YvonneX

Hi,

> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Thursday, October 22, 2020 5:11 PM
> To: Jiang, Cheng1 <cheng1.jiang@intel.com>; Xia, Chenbo
> <chenbo.xia@intel.com>
> Cc: dev@dpdk.org; Fu, Patrick <patrick.fu@intel.com>; Yang, YvonneX
> <yvonnex.yang@intel.com>
> Subject: Re: [PATCH v9 0/4] add async data path in vhost sample
> 
> Hi,
> 
> On 10/22/20 8:46 AM, Cheng Jiang wrote:
> > This patch set makes vhost-vswitch be able to use vhost async APIs for
> > enqueue operations. Demonstrated how the application leverage IOAT
> DMA
> > channel with vhost async APIs.
> >
> > We introduce two parameters to enable DMA acceleration for Tx
> > operations of queues:
> > -dma_type This parameter is used to specify DMA type for async
> > vhost-user net driver.
> > -dmas This parameter is used to specify the assigned DMA device of a
> > vhost device and enable async vhost data path.
> >
> > ---
> > v9:
> >  * Optimized code structure to solve compilation issue on non-x86
> > platforms
> >
> > v8:
> >  * Changed meson build file due to the change of ioat component name
> >
> > v7:
> >  * Improved IOAT callbacks and added some comments
> >
> > v6:
> >  * Cleand code and rebased for latest code
> >
> > v5:
> >  * Improved meson build file and fixed dependency problem
> >
> > v4:
> >  * Code rebased for latest IOAT driver
> >
> > v3:
> >  * Fixed a coding style problem
> >
> > v2:
> >  * Changed meson build file to fix dependency problem
> >  * Added parameter description in usage function
> >  * Optimized parameter settings and parsing function
> >  * Optimized abstraction, moved some code to ioat.c
> >
> > Cheng Jiang (4):
> >   example/vhost: add async vhost args parsing function
> >   example/vhost: add support for vhost async data path
> >   doc: update vhost sample doc for vhost async data path
> >   doc: update release notes for vhost sample
> >
> >  doc/guides/rel_notes/release_20_11.rst |   6 +
> >  doc/guides/sample_app_ug/vhost.rst     |  11 ++
> >  examples/vhost/ioat.c                  | 198 +++++++++++++++++++++++++
> >  examples/vhost/ioat.h                  |  47 ++++++
> >  examples/vhost/main.c                  |  93 +++++++++++-
> >  examples/vhost/main.h                  |   1 +
> >  examples/vhost/meson.build             |   5 +
> >  7 files changed, 359 insertions(+), 2 deletions(-)  create mode
> > 100644 examples/vhost/ioat.c  create mode 100644 examples/vhost/ioat.h
> >
> > --
> > 2.27.0
> >
> 
> It does not build:
> http://mails.dpdk.org/archives/test-report/2020-October/161193.html
> 
> Maxime

Problem solved in v10. 

Thanks.
Cheng


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

* Re: [dpdk-dev] [PATCH v10 1/4] example/vhost: add async vhost args parsing function
  2020-10-22  8:59   ` [dpdk-dev] [PATCH v10 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
@ 2020-10-23 11:08     ` Maxime Coquelin
  0 siblings, 0 replies; 71+ messages in thread
From: Maxime Coquelin @ 2020-10-23 11:08 UTC (permalink / raw)
  To: Cheng Jiang, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang



On 10/22/20 10:59 AM, Cheng Jiang wrote:
> This patch is to add async vhost driver arguments parsing function
> for CBDMA channel, DMA initiation function and args description.
> The meson build file is changed to fix dependency problem. With
> these arguments vhost device can be set to use CBDMA or CPU for
> enqueue operation and bind vhost device with specific CBDMA channel
> to accelerate data copy.
> 
> Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
> ---
>  examples/vhost/ioat.c      | 101 +++++++++++++++++++++++++++++++++++++
>  examples/vhost/ioat.h      |  33 ++++++++++++
>  examples/vhost/main.c      |  36 ++++++++++++-
>  examples/vhost/meson.build |   5 ++
>  4 files changed, 174 insertions(+), 1 deletion(-)
>  create mode 100644 examples/vhost/ioat.c
>  create mode 100644 examples/vhost/ioat.h
> 

Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>

Thanks,
Maxime


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

* Re: [dpdk-dev] [PATCH v10 2/4] example/vhost: add support for vhost async data path
  2020-10-22  8:59   ` [dpdk-dev] [PATCH v10 2/4] example/vhost: add support for vhost async data path Cheng Jiang
@ 2020-10-23 11:12     ` Maxime Coquelin
  0 siblings, 0 replies; 71+ messages in thread
From: Maxime Coquelin @ 2020-10-23 11:12 UTC (permalink / raw)
  To: Cheng Jiang, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang



On 10/22/20 10:59 AM, Cheng Jiang wrote:
> This patch is to implement vhost DMA operation callbacks for CBDMA
> PMD and add vhost async data-path in vhost sample. With providing
> callback implementation for CBDMA, vswitch can leverage IOAT to
> accelerate vhost async data-path.
> 
> Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
> ---
>  examples/vhost/ioat.c | 100 ++++++++++++++++++++++++++++++++++++++++++
>  examples/vhost/ioat.h |  12 +++++
>  examples/vhost/main.c |  57 +++++++++++++++++++++++-
>  examples/vhost/main.h |   1 +
>  4 files changed, 169 insertions(+), 1 deletion(-)
> 

Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>

Thanks,
Maxime


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

* Re: [dpdk-dev] [PATCH v10 3/4] doc: update vhost sample doc for vhost async data path
  2020-10-22  8:59   ` [dpdk-dev] [PATCH v10 3/4] doc: update vhost sample doc " Cheng Jiang
@ 2020-10-23 11:15     ` Maxime Coquelin
  0 siblings, 0 replies; 71+ messages in thread
From: Maxime Coquelin @ 2020-10-23 11:15 UTC (permalink / raw)
  To: Cheng Jiang, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang



On 10/22/20 10:59 AM, Cheng Jiang wrote:
> Add vhost async driver arguments information for vhost async data
> path in vhost sample application.
> 
> Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
> ---
>  doc/guides/sample_app_ug/vhost.rst | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>

Thanks,
Maxime


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

* Re: [dpdk-dev] [PATCH v10 4/4] doc: update release notes for vhost sample
  2020-10-22  8:59   ` [dpdk-dev] [PATCH v10 4/4] doc: update release notes for vhost sample Cheng Jiang
@ 2020-10-23 11:15     ` Maxime Coquelin
  0 siblings, 0 replies; 71+ messages in thread
From: Maxime Coquelin @ 2020-10-23 11:15 UTC (permalink / raw)
  To: Cheng Jiang, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang



On 10/22/20 10:59 AM, Cheng Jiang wrote:
> Add release notes for vhost async data path support in vhost sample.
> 
> Signed-off-by: Cheng Jiang <Cheng1.jiang@intel.com>
> ---
>  doc/guides/rel_notes/release_20_11.rst | 6 ++++++
>  1 file changed, 6 insertions(+)
> 

Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>

Thanks,
Maxime


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

* Re: [dpdk-dev] [PATCH v10 0/4] add async data path in vhost sample
  2020-10-22  8:59 ` [dpdk-dev] [PATCH v10 " Cheng Jiang
                     ` (3 preceding siblings ...)
  2020-10-22  8:59   ` [dpdk-dev] [PATCH v10 4/4] doc: update release notes for vhost sample Cheng Jiang
@ 2020-10-23 11:23   ` Maxime Coquelin
  2020-10-23 13:20     ` Ferruh Yigit
  2020-11-09 12:40     ` David Marchand
  4 siblings, 2 replies; 71+ messages in thread
From: Maxime Coquelin @ 2020-10-23 11:23 UTC (permalink / raw)
  To: Cheng Jiang, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang



On 10/22/20 10:59 AM, Cheng Jiang wrote:
> This patch set makes vhost-vswitch be able to use vhost async APIs
> for enqueue operations. Demonstrated how the application
> leverage IOAT DMA channel with vhost async APIs.
> 
> We introduce two parameters to enable DMA acceleration for Tx
> operations of queues:
> -dma_type This parameter is used to specify DMA type for async
> vhost-user net driver.
> -dmas This parameter is used to specify the assigned DMA device of a
> vhost device and enable async vhost data path.
> 
> ---
> v10:
>  * Fixed compilation issue on specific environment
> 
> v9:
>  * Optimized code structure to solve compilation issue on non-x86 platforms
> 
> v8:
>  * Changed meson build file due to the change of ioat component name
> 
> v7:
>  * Improved IOAT callbacks and added some comments
> 
> v6:
>  * Cleand code and rebased for latest code
> 
> v5:
>  * Improved meson build file and fixed dependency problem
> 
> v4:
>  * Code rebased for latest IOAT driver
> 
> v3:
>  * Fixed a coding style problem
> 
> v2:
>  * Changed meson build file to fix dependency problem
>  * Added parameter description in usage function
>  * Optimized parameter settings and parsing function
>  * Optimized abstraction, moved some code to ioat.c
> 
> Cheng Jiang (4):
>   example/vhost: add async vhost args parsing function
>   example/vhost: add support for vhost async data path
>   doc: update vhost sample doc for vhost async data path
>   doc: update release notes for vhost sample
> 
>  doc/guides/rel_notes/release_20_11.rst |   6 +
>  doc/guides/sample_app_ug/vhost.rst     |  11 ++
>  examples/vhost/ioat.c                  | 201 +++++++++++++++++++++++++
>  examples/vhost/ioat.h                  |  45 ++++++
>  examples/vhost/main.c                  |  93 +++++++++++-
>  examples/vhost/main.h                  |   1 +
>  examples/vhost/meson.build             |   5 +
>  7 files changed, 360 insertions(+), 2 deletions(-)
>  create mode 100644 examples/vhost/ioat.c
>  create mode 100644 examples/vhost/ioat.h
> 
> --
> 2.27.0
> 


Applied to dpdk-next-virtio/main.

Thanks,
Maxime


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

* Re: [dpdk-dev] [PATCH v10 0/4] add async data path in vhost sample
  2020-10-23 11:23   ` [dpdk-dev] [PATCH v10 0/4] add async data path in " Maxime Coquelin
@ 2020-10-23 13:20     ` Ferruh Yigit
  2020-11-09 12:40     ` David Marchand
  1 sibling, 0 replies; 71+ messages in thread
From: Ferruh Yigit @ 2020-10-23 13:20 UTC (permalink / raw)
  To: Maxime Coquelin, Cheng Jiang, chenbo.xia; +Cc: dev, patrick.fu, YvonneX.Yang

On 10/23/2020 12:23 PM, Maxime Coquelin wrote:
> 
> 
> On 10/22/20 10:59 AM, Cheng Jiang wrote:
>> This patch set makes vhost-vswitch be able to use vhost async APIs
>> for enqueue operations. Demonstrated how the application
>> leverage IOAT DMA channel with vhost async APIs.
>>
>> We introduce two parameters to enable DMA acceleration for Tx
>> operations of queues:
>> -dma_type This parameter is used to specify DMA type for async
>> vhost-user net driver.
>> -dmas This parameter is used to specify the assigned DMA device of a
>> vhost device and enable async vhost data path.
>>
>> ---
>> v10:
>>   * Fixed compilation issue on specific environment
>>
>> v9:
>>   * Optimized code structure to solve compilation issue on non-x86 platforms
>>
>> v8:
>>   * Changed meson build file due to the change of ioat component name
>>
>> v7:
>>   * Improved IOAT callbacks and added some comments
>>
>> v6:
>>   * Cleand code and rebased for latest code
>>
>> v5:
>>   * Improved meson build file and fixed dependency problem
>>
>> v4:
>>   * Code rebased for latest IOAT driver
>>
>> v3:
>>   * Fixed a coding style problem
>>
>> v2:
>>   * Changed meson build file to fix dependency problem
>>   * Added parameter description in usage function
>>   * Optimized parameter settings and parsing function
>>   * Optimized abstraction, moved some code to ioat.c
>>
>> Cheng Jiang (4):
>>    example/vhost: add async vhost args parsing function
>>    example/vhost: add support for vhost async data path
>>    doc: update vhost sample doc for vhost async data path
>>    doc: update release notes for vhost sample
>>
>>   doc/guides/rel_notes/release_20_11.rst |   6 +
>>   doc/guides/sample_app_ug/vhost.rst     |  11 ++
>>   examples/vhost/ioat.c                  | 201 +++++++++++++++++++++++++
>>   examples/vhost/ioat.h                  |  45 ++++++
>>   examples/vhost/main.c                  |  93 +++++++++++-
>>   examples/vhost/main.h                  |   1 +
>>   examples/vhost/meson.build             |   5 +
>>   7 files changed, 360 insertions(+), 2 deletions(-)
>>   create mode 100644 examples/vhost/ioat.c
>>   create mode 100644 examples/vhost/ioat.h
>>
>> --
>> 2.27.0
>>
> 
> 
> Applied to dpdk-next-virtio/main.
> 

Document patches squashed into the code patch in next-net.

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

* Re: [dpdk-dev] [PATCH v10 0/4] add async data path in vhost sample
  2020-10-23 11:23   ` [dpdk-dev] [PATCH v10 0/4] add async data path in " Maxime Coquelin
  2020-10-23 13:20     ` Ferruh Yigit
@ 2020-11-09 12:40     ` David Marchand
  2020-11-10  3:02       ` Jiang, Cheng1
  1 sibling, 1 reply; 71+ messages in thread
From: David Marchand @ 2020-11-09 12:40 UTC (permalink / raw)
  To: Maxime Coquelin, Cheng Jiang
  Cc: Xia, Chenbo, dev, patrick.fu, YvonneX.Yang, Thomas Monjalon,
	Yigit, Ferruh

On Fri, Oct 23, 2020 at 1:23 PM Maxime Coquelin
<maxime.coquelin@redhat.com> wrote:
> On 10/22/20 10:59 AM, Cheng Jiang wrote:
> > This patch set makes vhost-vswitch be able to use vhost async APIs
> > for enqueue operations. Demonstrated how the application
> > leverage IOAT DMA channel with vhost async APIs.
> >
> > We introduce two parameters to enable DMA acceleration for Tx
> > operations of queues:
> > -dma_type This parameter is used to specify DMA type for async
> > vhost-user net driver.
> > -dmas This parameter is used to specify the assigned DMA device of a
> > vhost device and enable async vhost data path.
> >
> >
> > Cheng Jiang (4):
> >   example/vhost: add async vhost args parsing function
> >   example/vhost: add support for vhost async data path

- This series breaks external compilation, as the external Makefile
was not updated.

/usr/bin/ld: /tmp/cce4w26j.o: in function `new_device':
main.c:(.text+0x173): undefined reference to `ioat_transfer_data_cb'
/usr/bin/ld: main.c:(.text+0x178): undefined reference to
`ioat_check_completed_copies_cb'
/usr/bin/ld: /tmp/cce4w26j.o: in function `main':
main.c:(.text.startup+0x25e): undefined reference to `open_ioat'
collect2: error: ld returned 1 exit status


- This series imposes a dependency on the raw/ioat driver for no reason.

$ meson configure build -Ddisable_drivers=raw/ioat
$ ninja-build -C build -j4
...
examples/meson.build:91:4: ERROR:  Problem encountered: Missing
dependency "raw_ioat" for example "vhost"

The check for the architecture == x86 is wrong.
The example must check for RTE_RAW_IOAT presence.


Please provide fixes before rc4 or I will revert this series.
Thanks.


-- 
David Marchand


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

* Re: [dpdk-dev] [PATCH v10 0/4] add async data path in vhost sample
  2020-11-09 12:40     ` David Marchand
@ 2020-11-10  3:02       ` Jiang, Cheng1
  2020-11-10  8:17         ` David Marchand
  0 siblings, 1 reply; 71+ messages in thread
From: Jiang, Cheng1 @ 2020-11-10  3:02 UTC (permalink / raw)
  To: David Marchand, Maxime Coquelin
  Cc: Xia, Chenbo, dev, Fu, Patrick, Yang, YvonneX, Thomas Monjalon,
	Yigit, Ferruh, Hu, Jiayu

Hi,
The replies are inline.

> -----Original Message-----
> From: David Marchand <david.marchand@redhat.com>
> Sent: Monday, November 9, 2020 8:40 PM
> To: Maxime Coquelin <maxime.coquelin@redhat.com>; Jiang, Cheng1
> <cheng1.jiang@intel.com>
> Cc: Xia, Chenbo <chenbo.xia@intel.com>; dev <dev@dpdk.org>; Fu, Patrick
> <patrick.fu@intel.com>; Yang, YvonneX <yvonnex.yang@intel.com>;
> Thomas Monjalon <thomas@monjalon.net>; Yigit, Ferruh
> <ferruh.yigit@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v10 0/4] add async data path in vhost sample
> 
> On Fri, Oct 23, 2020 at 1:23 PM Maxime Coquelin
> <maxime.coquelin@redhat.com> wrote:
> > On 10/22/20 10:59 AM, Cheng Jiang wrote:
> > > This patch set makes vhost-vswitch be able to use vhost async APIs
> > > for enqueue operations. Demonstrated how the application leverage
> > > IOAT DMA channel with vhost async APIs.
> > >
> > > We introduce two parameters to enable DMA acceleration for Tx
> > > operations of queues:
> > > -dma_type This parameter is used to specify DMA type for async
> > > vhost-user net driver.
> > > -dmas This parameter is used to specify the assigned DMA device of a
> > > vhost device and enable async vhost data path.
> > >
> > >
> > > Cheng Jiang (4):
> > >   example/vhost: add async vhost args parsing function
> > >   example/vhost: add support for vhost async data path
> 
> - This series breaks external compilation, as the external Makefile was not
> updated.
> 

I'm not sure I understand what you mean by external Makefile, because as far as I know, makefile has been deprecated.
Do you mean I need to update the Makfile in examples/vhost?

> /usr/bin/ld: /tmp/cce4w26j.o: in function `new_device':
> main.c:(.text+0x173): undefined reference to `ioat_transfer_data_cb'
> /usr/bin/ld: main.c:(.text+0x178): undefined reference to
> `ioat_check_completed_copies_cb'
> /usr/bin/ld: /tmp/cce4w26j.o: in function `main':
> main.c:(.text.startup+0x25e): undefined reference to `open_ioat'
> collect2: error: ld returned 1 exit status
> 
> 
> - This series imposes a dependency on the raw/ioat driver for no reason.
> 
> $ meson configure build -Ddisable_drivers=raw/ioat $ ninja-build -C build -
> j4 ...
> examples/meson.build:91:4: ERROR:  Problem encountered: Missing
> dependency "raw_ioat" for example "vhost"
> 
> The check for the architecture == x86 is wrong.
> The example must check for RTE_RAW_IOAT presence.
> 

As for this issue, I agreed with you. I will fix it by changing the x86 check into RTE_RAW_IOAT check.

Thanks.
Cheng

> 
> Please provide fixes before rc4 or I will revert this series.
> Thanks.
> 
> 
> --
> David Marchand


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

* Re: [dpdk-dev] [PATCH v10 0/4] add async data path in vhost sample
  2020-11-10  3:02       ` Jiang, Cheng1
@ 2020-11-10  8:17         ` David Marchand
  2020-11-10 11:19           ` Bruce Richardson
  0 siblings, 1 reply; 71+ messages in thread
From: David Marchand @ 2020-11-10  8:17 UTC (permalink / raw)
  To: Jiang, Cheng1, Bruce Richardson
  Cc: Maxime Coquelin, Xia, Chenbo, dev, Fu, Patrick, Yang, YvonneX,
	Thomas Monjalon, Yigit, Ferruh, Hu, Jiayu

On Tue, Nov 10, 2020 at 4:02 AM Jiang, Cheng1 <cheng1.jiang@intel.com> wrote:
> > - This series breaks external compilation, as the external Makefile was not
> > updated.
> >
>
> I'm not sure I understand what you mean by external Makefile, because as far as I know, makefile has been deprecated.

make support is dropped for dpdk compilation itself.

For the examples, the users will use make to compile them, as this is
the only way provided to users *out of* dpdk.
But the examples are compiled too via meson when compiling dpdk itself
if you pass -Dexamples= options.


Bruce,

I want to avoid more misses like this one.

If we want to keep the examples compilation in meson, we need a
consistent framework to compile in both cases.
Right now, we don't export meson for examples, and it makes no sense
in their current form.
It seems simpler to me to only maintain make support, and meson can
still call make for each example.

Another solution is to rely only on test-meson-builds.sh, but then it
ends up on the maintainer shoulders, so I prefer the solution above.

Other ideas?


Cheng,

For the problem on vhost, there are different ways to reproduce, but
the simpler for now is:
$ meson --default-library=shared builddir
$ ninja-build -C builddir -j4
$ export DESTDIR=$(pwd)/installdir
$ ninja-build -C builddir -j4 install
$ export PKG_CONFIG_PATH=$(dirname $(find $DESTDIR -name
libdpdk.pc)):$PKG_CONFIG_PATH
$ export LD_LIBRARY_PATH=$(dirname $(find $DESTDIR -name
librte_eal.so)):$LD_LIBRARY_PATH
$ export PKGCONF="pkg-config --define-prefix"
$ make -C $DESTDIR/usr/local/share/dpdk/examples/vhost clean shared static
...
rm -f build/vhost-switch build/vhost-switch-static build/vhost-switch-shared
test -d build && rmdir -p build || true
cc -O3 -I.../installdir/usr/local/include -include rte_config.h
-march=native -I/usr/usr/include  -DALLOW_EXPERIMENTAL_API main.c
virtio_net.c -o build/vhost-switch-shared -pthread -Wl,--as-needed
-L.../installdir/usr/local/lib64 -lrte_node -lrte_graph -lrte_bpf
-lrte_flow_classify -lrte_pipeline -lrte_table -lrte_port -lrte_fib
-lrte_ipsec -lrte_vhost -lrte_stack -lrte_security -lrte_sched
-lrte_reorder -lrte_rib -lrte_regexdev -lrte_rawdev -lrte_pdump
-lrte_power -lrte_member -lrte_lpm -lrte_latencystats -lrte_kni
-lrte_jobstats -lrte_ip_frag -lrte_gso -lrte_gro -lrte_eventdev
-lrte_efd -lrte_distributor -lrte_cryptodev -lrte_compressdev
-lrte_cfgfile -lrte_bitratestats -lrte_bbdev -lrte_acl -lrte_timer
-lrte_hash -lrte_metrics -lrte_cmdline -lrte_pci -lrte_ethdev
-lrte_meter -lrte_net -lrte_mbuf -lrte_mempool -lrte_rcu -lrte_ring
-lrte_eal -lrte_telemetry -lrte_kvargs -lbsd
/usr/bin/ld: /tmp/ccXZVDJk.o: in function `new_device':
main.c:(.text+0x173): undefined reference to `ioat_transfer_data_cb'
/usr/bin/ld: main.c:(.text+0x178): undefined reference to
`ioat_check_completed_copies_cb'
/usr/bin/ld: /tmp/ccXZVDJk.o: in function `main':
main.c:(.text.startup+0x25e): undefined reference to `open_ioat'
collect2: error: ld returned 1 exit status
make: *** [Makefile:34: build/vhost-switch-shared] Error 1


> Do you mean I need to update the Makfile in examples/vhost?

Yes.


> > - This series imposes a dependency on the raw/ioat driver for no reason.
> >
> > $ meson configure build -Ddisable_drivers=raw/ioat $ ninja-build -C build -
> > j4 ...
> > examples/meson.build:91:4: ERROR:  Problem encountered: Missing
> > dependency "raw_ioat" for example "vhost"
> >
> > The check for the architecture == x86 is wrong.
> > The example must check for RTE_RAW_IOAT presence.
> >
>
> As for this issue, I agreed with you. I will fix it by changing the x86 check into RTE_RAW_IOAT check.

Reading the thread again, Maxime had already asked for this change.


-- 
David Marchand


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

* Re: [dpdk-dev] [PATCH v10 0/4] add async data path in vhost sample
  2020-11-10  8:17         ` David Marchand
@ 2020-11-10 11:19           ` Bruce Richardson
  2020-11-10 13:37             ` Thomas Monjalon
  0 siblings, 1 reply; 71+ messages in thread
From: Bruce Richardson @ 2020-11-10 11:19 UTC (permalink / raw)
  To: David Marchand
  Cc: Jiang, Cheng1, Maxime Coquelin, Xia, Chenbo, dev, Fu, Patrick,
	Yang, YvonneX, Thomas Monjalon, Yigit, Ferruh, Hu, Jiayu

On Tue, Nov 10, 2020 at 09:17:36AM +0100, David Marchand wrote:
> On Tue, Nov 10, 2020 at 4:02 AM Jiang, Cheng1 <cheng1.jiang@intel.com> wrote:
> > > - This series breaks external compilation, as the external Makefile was not
> > > updated.
> > >
> >
> > I'm not sure I understand what you mean by external Makefile, because as far as I know, makefile has been deprecated.
> 
> make support is dropped for dpdk compilation itself.
> 
> For the examples, the users will use make to compile them, as this is
> the only way provided to users *out of* dpdk.
> But the examples are compiled too via meson when compiling dpdk itself
> if you pass -Dexamples= options.
> 
> 
> Bruce,
> 
> I want to avoid more misses like this one.
> 
> If we want to keep the examples compilation in meson, we need a
> consistent framework to compile in both cases.
> Right now, we don't export meson for examples, and it makes no sense
> in their current form.
> It seems simpler to me to only maintain make support, and meson can
> still call make for each example.
> 
> Another solution is to rely only on test-meson-builds.sh, but then it
> ends up on the maintainer shoulders, so I prefer the solution above.
> 
> Other ideas?
> 

Hi David,

I've been thinking a bit about this since I got your email, but inspiration
for new ideas has yet to strike me.

While I can see the downside of having both make and meson build files for
the examples, I'm loath to see one of them dropped. Here is my current
thinking on it:

* We obviously need to keep the basic makefiles so as to make it easy for
  end-users to compile up and use the examples separate from DPDK itself.
  The makefiles serve as good examples as to how to pull the DPDK info from
  pkg-config.

* On the other hand, being able to build the examples as part of a regular
  meson build is a big advantage over having to build them separately, and
  allows errors with examples to be caught quicker. It's also useful for
  those of us working on specific components with associated sample apps to
  have just that one app built constantly as we work.

* Therefore, while it looks like the more logical part to drop is indeed
  the meson support for the examples, we may struggle to implement clean
  building of the examples from meson using make, at least until meson 0.54
  becomes our standard. Before that version, we don't have a
  "meson-uninstalled" folder with build-time package-config file to use as
  source of build flags for each example.

* One final idea I had and investigated in the past was whether we could at
  build or install time auto-generate the Makefile for each example from
  the meson.build file. Unfortunately, nothing came of that idea the first
  time I tried it, but it might still be worth looking at. Even if it works
  for 80-90% of cases, it means that we have a much smaller subset of
  examples where we need to test independently the make and meson builds.

So overall my assessment is that it needs a bit of investigation and
prototyping to see what we can come up with.

On a semi-related note, it's perhaps a bigger problem that we cannot rely
on test-meson-builds and CI infrastructure to prevent issues like this.
Surely this is what CI is there for - to help reduce the workload for
maintainers. The fact that we are considering removing the meson build of
examples because we cannot rely on CI is surely more worthy of a solution
than trying to find a way to build examples with make from within meson?

Perhaps we need to see about stricter measures from CI failure, e.g.
anything failing travis build automatically gets marked as changes
requested in patchwork, and the author gets an email informing them of
such?

Regards,
/Bruce

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

* Re: [dpdk-dev] [PATCH v10 0/4] add async data path in vhost sample
  2020-11-10 11:19           ` Bruce Richardson
@ 2020-11-10 13:37             ` Thomas Monjalon
  2020-11-10 14:34               ` Bruce Richardson
  0 siblings, 1 reply; 71+ messages in thread
From: Thomas Monjalon @ 2020-11-10 13:37 UTC (permalink / raw)
  To: David Marchand, Bruce Richardson
  Cc: Jiang, Cheng1, Maxime Coquelin, Xia, Chenbo, dev, Fu, Patrick,
	Yang, YvonneX, Yigit, Ferruh, Hu, Jiayu

10/11/2020 12:19, Bruce Richardson:
> On Tue, Nov 10, 2020 at 09:17:36AM +0100, David Marchand wrote:
> > On Tue, Nov 10, 2020 at 4:02 AM Jiang, Cheng1 <cheng1.jiang@intel.com> wrote:
> > > > - This series breaks external compilation, as the external Makefile was not
> > > > updated.
> > > >
> > >
> > > I'm not sure I understand what you mean by external Makefile,
> > > because as far as I know, makefile has been deprecated.
> > 
> > make support is dropped for dpdk compilation itself.
> > 
> > For the examples, the users will use make to compile them, as this is
> > the only way provided to users *out of* dpdk.
> > But the examples are compiled too via meson when compiling dpdk itself
> > if you pass -Dexamples= options.
> > 
> > 
> > Bruce,
> > 
> > I want to avoid more misses like this one.
> > 
> > If we want to keep the examples compilation in meson, we need a
> > consistent framework to compile in both cases.
> > Right now, we don't export meson for examples, and it makes no sense
> > in their current form.
> > It seems simpler to me to only maintain make support, and meson can
> > still call make for each example.
> > 
> > Another solution is to rely only on test-meson-builds.sh, but then it
> > ends up on the maintainer shoulders, so I prefer the solution above.
> > 
> > Other ideas?
> > 
> 
> Hi David,
> 
> I've been thinking a bit about this since I got your email, but inspiration
> for new ideas has yet to strike me.
> 
> While I can see the downside of having both make and meson build files for
> the examples, I'm loath to see one of them dropped. Here is my current
> thinking on it:
> 
> * We obviously need to keep the basic makefiles so as to make it easy for
>   end-users to compile up and use the examples separate from DPDK itself.
>   The makefiles serve as good examples as to how to pull the DPDK info from
>   pkg-config.

The external compilation is part of the example, yes.

> * On the other hand, being able to build the examples as part of a regular
>   meson build is a big advantage over having to build them separately, and
>   allows errors with examples to be caught quicker.

In the past we had a Makefile which builds all examples.
If you want, it can even been called at the end of meson DPDK compilation.

>   It's also useful for those of us working on specific components
>   with associated sample apps to have just that one app built constantly
>   as we work.

I don't understand this point:
	ninja -C build && make -C examples/myexample

> * Therefore, while it looks like the more logical part to drop is indeed
>   the meson support for the examples,

Yes, building the examples from the inside build system is strange,
and hide issues.

>   we may struggle to implement clean
>   building of the examples from meson using make, at least until meson 0.54
>   becomes our standard. Before that version, we don't have a
>   "meson-uninstalled" folder with build-time package-config file to use as
>   source of build flags for each example.

We don't have to use meson at all.

> * One final idea I had and investigated in the past was whether we could at
>   build or install time auto-generate the Makefile for each example from
>   the meson.build file. Unfortunately, nothing came of that idea the first
>   time I tried it, but it might still be worth looking at. Even if it works
>   for 80-90% of cases, it means that we have a much smaller subset of
>   examples where we need to test independently the make and meson builds.

Hand-crafted Makefile is enough. They may be improved.
If we feel it is too hard, we can use another build system
in examples, like cmake.

> So overall my assessment is that it needs a bit of investigation and
> prototyping to see what we can come up with.

I think testing external build + removing build from internal meson
would be a good start to ensure quality of examples maintenance.

> On a semi-related note, it's perhaps a bigger problem that we cannot rely
> on test-meson-builds and CI infrastructure to prevent issues like this.

We can. We just have to add all examples in test-meson-builds.sh.

> Surely this is what CI is there for - to help reduce the workload for
> maintainers. The fact that we are considering removing the meson build of
> examples because we cannot rely on CI is surely more worthy of a solution
> than trying to find a way to build examples with make from within meson?

No the concern is to have all contributors work on the same
single build path.

> Perhaps we need to see about stricter measures from CI failure, e.g.
> anything failing travis build automatically gets marked as changes
> requested in patchwork, and the author gets an email informing them of
> such?

When there is a failure, authors receive an email,
and maintainers can see a red flag. I think it's OK.

The only issue was that this build path was not tested.
I think David is going to fix it by compiling all possible examples
with external make build from test-meson-builds.sh.



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

* Re: [dpdk-dev] [PATCH v10 0/4] add async data path in vhost sample
  2020-11-10 13:37             ` Thomas Monjalon
@ 2020-11-10 14:34               ` Bruce Richardson
  2020-11-10 14:40                 ` Thomas Monjalon
  0 siblings, 1 reply; 71+ messages in thread
From: Bruce Richardson @ 2020-11-10 14:34 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: David Marchand, Jiang, Cheng1, Maxime Coquelin, Xia, Chenbo, dev,
	Fu, Patrick, Yang, YvonneX, Yigit, Ferruh, Hu, Jiayu

On Tue, Nov 10, 2020 at 02:37:02PM +0100, Thomas Monjalon wrote:
> 10/11/2020 12:19, Bruce Richardson:
> > On Tue, Nov 10, 2020 at 09:17:36AM +0100, David Marchand wrote:
> > > On Tue, Nov 10, 2020 at 4:02 AM Jiang, Cheng1 <cheng1.jiang@intel.com> wrote:
> > > > > - This series breaks external compilation, as the external Makefile was not
> > > > > updated.
> > > > >
> > > >
> > > > I'm not sure I understand what you mean by external Makefile,
> > > > because as far as I know, makefile has been deprecated.
> > > 
> > > make support is dropped for dpdk compilation itself.
> > > 
> > > For the examples, the users will use make to compile them, as this is
> > > the only way provided to users *out of* dpdk.
> > > But the examples are compiled too via meson when compiling dpdk itself
> > > if you pass -Dexamples= options.
> > > 
> > > 
> > > Bruce,
> > > 
> > > I want to avoid more misses like this one.
> > > 
> > > If we want to keep the examples compilation in meson, we need a
> > > consistent framework to compile in both cases.
> > > Right now, we don't export meson for examples, and it makes no sense
> > > in their current form.
> > > It seems simpler to me to only maintain make support, and meson can
> > > still call make for each example.
> > > 
> > > Another solution is to rely only on test-meson-builds.sh, but then it
> > > ends up on the maintainer shoulders, so I prefer the solution above.
> > > 
> > > Other ideas?
> > > 
> > 
> > Hi David,
> > 
> > I've been thinking a bit about this since I got your email, but inspiration
> > for new ideas has yet to strike me.
> > 
> > While I can see the downside of having both make and meson build files for
> > the examples, I'm loath to see one of them dropped. Here is my current
> > thinking on it:
> > 
> > * We obviously need to keep the basic makefiles so as to make it easy for
> >   end-users to compile up and use the examples separate from DPDK itself.
> >   The makefiles serve as good examples as to how to pull the DPDK info from
> >   pkg-config.
> 
> The external compilation is part of the example, yes.
> 
> > * On the other hand, being able to build the examples as part of a regular
> >   meson build is a big advantage over having to build them separately, and
> >   allows errors with examples to be caught quicker.
> 
> In the past we had a Makefile which builds all examples.
> If you want, it can even been called at the end of meson DPDK compilation.
> 

Yes, we can do that, but my concern is not so much about having them built
as part of build tests, but rather having them part of a build workflow for
developers during development.  Thinking here in particular of those coding
with IDEs such as eclipse or VScode, which I know a lot of people use -
including myself from time to time, depending on what I am working on.

> >   It's also useful for those of us working on specific components
> >   with associated sample apps to have just that one app built constantly
> >   as we work.
> 
> I don't understand this point:
> 	ninja -C build && make -C examples/myexample
> 

That works fine for building on the commandline, but does not work well for
building as part of "build-on-save" inside an IDE, which is the biggest
reason I want to keep support for building examples using meson. For doing
development with a feature and associated sample app, being able to
configure your build folder to rebuild a particular sample app as part of a
main infrastructure rebuild is really useful - and works really quickly
too, since incremental builds of C file changes happen really fast with
meson.

> > * Therefore, while it looks like the more logical part to drop is indeed
> >   the meson support for the examples,
> 
> Yes, building the examples from the inside build system is strange,
> and hide issues.
> 

Sorry, while it may hide issues with the makefile because people weren't
really aware that they were sticking around, it definitely helps pick up
issues with C code changes as you are developing.

> >   we may struggle to implement clean
> >   building of the examples from meson using make, at least until meson 0.54
> >   becomes our standard. Before that version, we don't have a
> >   "meson-uninstalled" folder with build-time package-config file to use as
> >   source of build flags for each example.
> 
> We don't have to use meson at all.
> 

No, we don't, so long as we don't miss out on the benefits we currently get
from having it integrated.

> > * One final idea I had and investigated in the past was whether we could at
> >   build or install time auto-generate the Makefile for each example from
> >   the meson.build file. Unfortunately, nothing came of that idea the first
> >   time I tried it, but it might still be worth looking at. Even if it works
> >   for 80-90% of cases, it means that we have a much smaller subset of
> >   examples where we need to test independently the make and meson builds.
> 
> Hand-crafted Makefile is enough. They may be improved.
> If we feel it is too hard, we can use another build system
> in examples, like cmake.
> 
> > So overall my assessment is that it needs a bit of investigation and
> > prototyping to see what we can come up with.
> 
> I think testing external build + removing build from internal meson
> would be a good start to ensure quality of examples maintenance.
> 
If we remove the meson build of the examples, I think we need equivalent
functionality provided some other way. Calling make for examples from
within meson may be good enough, so long as it's not too slow.

> > On a semi-related note, it's perhaps a bigger problem that we cannot rely
> > on test-meson-builds and CI infrastructure to prevent issues like this.
> 
> We can. We just have to add all examples in test-meson-builds.sh.
> 

Yep, definite +1 here.
Once that is done, I'd then like to wait and see what future issues crop up
before we start ripping out other bits. This is the first release where we
have removed the make build system, so there are lots of teething issues
all over the place, of which this is but one example!

> > Surely this is what CI is there for - to help reduce the workload for
> > maintainers. The fact that we are considering removing the meson build of
> > examples because we cannot rely on CI is surely more worthy of a solution
> > than trying to find a way to build examples with make from within meson?
> 
> No the concern is to have all contributors work on the same
> single build path.
> 
Building all examples from test-meson-build should probably be sufficient
here, I think.

> > Perhaps we need to see about stricter measures from CI failure, e.g.
> > anything failing travis build automatically gets marked as changes
> > requested in patchwork, and the author gets an email informing them of
> > such?
> 
> When there is a failure, authors receive an email,
> and maintainers can see a red flag. I think it's OK.
> 
> The only issue was that this build path was not tested.
> I think David is going to fix it by compiling all possible examples
> with external make build from test-meson-builds.sh.
> 

Seems like we are all aligned on the first step anyway. Let's see beyond
that what needs to be done in 21.02.

/Bruce

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

* Re: [dpdk-dev] [PATCH v10 0/4] add async data path in vhost sample
  2020-11-10 14:34               ` Bruce Richardson
@ 2020-11-10 14:40                 ` Thomas Monjalon
  0 siblings, 0 replies; 71+ messages in thread
From: Thomas Monjalon @ 2020-11-10 14:40 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: David Marchand, Jiang, Cheng1, Maxime Coquelin, Xia, Chenbo, dev,
	Fu, Patrick, Yang, YvonneX, Yigit, Ferruh, Hu, Jiayu

10/11/2020 15:34, Bruce Richardson:
> On Tue, Nov 10, 2020 at 02:37:02PM +0100, Thomas Monjalon wrote:
> > 10/11/2020 12:19, Bruce Richardson:
> > > On Tue, Nov 10, 2020 at 09:17:36AM +0100, David Marchand wrote:
> > > > On Tue, Nov 10, 2020 at 4:02 AM Jiang, Cheng1 <cheng1.jiang@intel.com> wrote:
> > > > > > - This series breaks external compilation, as the external Makefile was not
> > > > > > updated.
> > > > > >
> > > > >
> > > > > I'm not sure I understand what you mean by external Makefile,
> > > > > because as far as I know, makefile has been deprecated.
> > > > 
> > > > make support is dropped for dpdk compilation itself.
> > > > 
> > > > For the examples, the users will use make to compile them, as this is
> > > > the only way provided to users *out of* dpdk.
> > > > But the examples are compiled too via meson when compiling dpdk itself
> > > > if you pass -Dexamples= options.
> > > > 
> > > > 
> > > > Bruce,
> > > > 
> > > > I want to avoid more misses like this one.
> > > > 
> > > > If we want to keep the examples compilation in meson, we need a
> > > > consistent framework to compile in both cases.
> > > > Right now, we don't export meson for examples, and it makes no sense
> > > > in their current form.
> > > > It seems simpler to me to only maintain make support, and meson can
> > > > still call make for each example.
> > > > 
> > > > Another solution is to rely only on test-meson-builds.sh, but then it
> > > > ends up on the maintainer shoulders, so I prefer the solution above.
> > > > 
> > > > Other ideas?
> > > > 
> > > 
> > > Hi David,
> > > 
> > > I've been thinking a bit about this since I got your email, but inspiration
> > > for new ideas has yet to strike me.
> > > 
> > > While I can see the downside of having both make and meson build files for
> > > the examples, I'm loath to see one of them dropped. Here is my current
> > > thinking on it:
> > > 
> > > * We obviously need to keep the basic makefiles so as to make it easy for
> > >   end-users to compile up and use the examples separate from DPDK itself.
> > >   The makefiles serve as good examples as to how to pull the DPDK info from
> > >   pkg-config.
> > 
> > The external compilation is part of the example, yes.
> > 
> > > * On the other hand, being able to build the examples as part of a regular
> > >   meson build is a big advantage over having to build them separately, and
> > >   allows errors with examples to be caught quicker.
> > 
> > In the past we had a Makefile which builds all examples.
> > If you want, it can even been called at the end of meson DPDK compilation.
> > 
> 
> Yes, we can do that, but my concern is not so much about having them built
> as part of build tests, but rather having them part of a build workflow for
> developers during development.  Thinking here in particular of those coding
> with IDEs such as eclipse or VScode, which I know a lot of people use -
> including myself from time to time, depending on what I am working on.
> 
> > >   It's also useful for those of us working on specific components
> > >   with associated sample apps to have just that one app built constantly
> > >   as we work.
> > 
> > I don't understand this point:
> > 	ninja -C build && make -C examples/myexample
> > 
> 
> That works fine for building on the commandline, but does not work well for
> building as part of "build-on-save" inside an IDE, which is the biggest
> reason I want to keep support for building examples using meson. For doing
> development with a feature and associated sample app, being able to
> configure your build folder to rebuild a particular sample app as part of a
> main infrastructure rebuild is really useful - and works really quickly
> too, since incremental builds of C file changes happen really fast with
> meson.
> 
> > > * Therefore, while it looks like the more logical part to drop is indeed
> > >   the meson support for the examples,
> > 
> > Yes, building the examples from the inside build system is strange,
> > and hide issues.
> > 
> 
> Sorry, while it may hide issues with the makefile because people weren't
> really aware that they were sticking around, it definitely helps pick up
> issues with C code changes as you are developing.
> 
> > >   we may struggle to implement clean
> > >   building of the examples from meson using make, at least until meson 0.54
> > >   becomes our standard. Before that version, we don't have a
> > >   "meson-uninstalled" folder with build-time package-config file to use as
> > >   source of build flags for each example.
> > 
> > We don't have to use meson at all.
> > 
> 
> No, we don't, so long as we don't miss out on the benefits we currently get
> from having it integrated.
> 
> > > * One final idea I had and investigated in the past was whether we could at
> > >   build or install time auto-generate the Makefile for each example from
> > >   the meson.build file. Unfortunately, nothing came of that idea the first
> > >   time I tried it, but it might still be worth looking at. Even if it works
> > >   for 80-90% of cases, it means that we have a much smaller subset of
> > >   examples where we need to test independently the make and meson builds.
> > 
> > Hand-crafted Makefile is enough. They may be improved.
> > If we feel it is too hard, we can use another build system
> > in examples, like cmake.
> > 
> > > So overall my assessment is that it needs a bit of investigation and
> > > prototyping to see what we can come up with.
> > 
> > I think testing external build + removing build from internal meson
> > would be a good start to ensure quality of examples maintenance.
> > 
> If we remove the meson build of the examples, I think we need equivalent
> functionality provided some other way. Calling make for examples from
> within meson may be good enough, so long as it's not too slow.
> 
> > > On a semi-related note, it's perhaps a bigger problem that we cannot rely
> > > on test-meson-builds and CI infrastructure to prevent issues like this.
> > 
> > We can. We just have to add all examples in test-meson-builds.sh.
> > 
> 
> Yep, definite +1 here.
> Once that is done, I'd then like to wait and see what future issues crop up
> before we start ripping out other bits. This is the first release where we
> have removed the make build system, so there are lots of teething issues
> all over the place, of which this is but one example!
> 
> > > Surely this is what CI is there for - to help reduce the workload for
> > > maintainers. The fact that we are considering removing the meson build of
> > > examples because we cannot rely on CI is surely more worthy of a solution
> > > than trying to find a way to build examples with make from within meson?
> > 
> > No the concern is to have all contributors work on the same
> > single build path.
> > 
> Building all examples from test-meson-build should probably be sufficient
> here, I think.
> 
> > > Perhaps we need to see about stricter measures from CI failure, e.g.
> > > anything failing travis build automatically gets marked as changes
> > > requested in patchwork, and the author gets an email informing them of
> > > such?
> > 
> > When there is a failure, authors receive an email,
> > and maintainers can see a red flag. I think it's OK.
> > 
> > The only issue was that this build path was not tested.
> > I think David is going to fix it by compiling all possible examples
> > with external make build from test-meson-builds.sh.
> > 
> 
> Seems like we are all aligned on the first step anyway. Let's see beyond
> that what needs to be done in 21.02.

OK



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

end of thread, other threads:[~2020-11-10 14:40 UTC | newest]

Thread overview: 71+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-10  6:43 [dpdk-dev] [PATCH v1 0/4] add async data path in vhost sample Cheng Jiang
2020-09-10  6:43 ` [dpdk-dev] [PATCH v1 1/4] example/vhost: add async vhost driver args parsing function Cheng Jiang
2020-09-23  8:25   ` Maxime Coquelin
2020-09-28  6:09     ` Jiang, Cheng1
2020-09-10  6:43 ` [dpdk-dev] [PATCH v1 2/4] example/vhost: add support for vhost async data path Cheng Jiang
2020-09-10  6:43 ` [dpdk-dev] [PATCH v1 3/4] doc: update vhost sample doc " Cheng Jiang
2020-09-10  6:43 ` [dpdk-dev] [PATCH v1 4/4] doc: update release notes for vhost sample Cheng Jiang
2020-09-29  6:42 ` [dpdk-dev] [PATCH v2 0/4] add async data path in " Cheng Jiang
2020-09-29  6:42   ` [dpdk-dev] [PATCH v2 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
2020-09-29  6:42   ` [dpdk-dev] [PATCH v2 2/4] example/vhost: add support for vhost async data path Cheng Jiang
2020-09-29  6:42   ` [dpdk-dev] [PATCH v2 3/4] doc: update vhost sample doc " Cheng Jiang
2020-09-29  6:42   ` [dpdk-dev] [PATCH v2 4/4] doc: update release notes for vhost sample Cheng Jiang
2020-09-30  3:08   ` [dpdk-dev] [PATCH v3 0/4] add async data path in " Cheng Jiang
2020-09-30  3:08     ` [dpdk-dev] [PATCH v3 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
2020-09-30  3:08     ` [dpdk-dev] [PATCH v3 2/4] example/vhost: add support for vhost async data path Cheng Jiang
2020-09-30  3:08     ` [dpdk-dev] [PATCH v3 3/4] doc: update vhost sample doc " Cheng Jiang
2020-09-30  3:08     ` [dpdk-dev] [PATCH v3 4/4] doc: update release notes for vhost sample Cheng Jiang
2020-10-12  4:54     ` [dpdk-dev] [PATCH v4 0/4] add async data path in " Cheng Jiang
2020-10-12  4:54       ` [dpdk-dev] [PATCH v4 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
2020-10-14  9:23         ` Maxime Coquelin
2020-10-15  5:11           ` Jiang, Cheng1
2020-10-12  4:54       ` [dpdk-dev] [PATCH v4 2/4] example/vhost: add support for vhost async data path Cheng Jiang
2020-10-12  4:54       ` [dpdk-dev] [PATCH v4 3/4] doc: update vhost sample doc " Cheng Jiang
2020-10-12  4:54       ` [dpdk-dev] [PATCH v4 4/4] doc: update release notes for vhost sample Cheng Jiang
2020-10-15  4:54       ` [dpdk-dev] [PATCH v5 0/4] add async data path in " Cheng Jiang
2020-10-15  4:54         ` [dpdk-dev] [PATCH v5 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
2020-10-15 15:13           ` Maxime Coquelin
2020-10-15  4:54         ` [dpdk-dev] [PATCH v5 2/4] example/vhost: add support for vhost async data path Cheng Jiang
2020-10-15  4:54         ` [dpdk-dev] [PATCH v5 3/4] doc: update vhost sample doc " Cheng Jiang
2020-10-15  4:54         ` [dpdk-dev] [PATCH v5 4/4] doc: update release notes for vhost sample Cheng Jiang
2020-10-16  4:29         ` [dpdk-dev] [PATCH v6 0/4] add async data path in " Cheng Jiang
2020-10-16  4:29           ` [dpdk-dev] [PATCH v6 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
2020-10-16  4:29           ` [dpdk-dev] [PATCH v6 2/4] example/vhost: add support for vhost async data path Cheng Jiang
2020-10-16  4:29           ` [dpdk-dev] [PATCH v6 3/4] doc: update vhost sample doc " Cheng Jiang
2020-10-16  4:29           ` [dpdk-dev] [PATCH v6 4/4] doc: update release notes for vhost sample Cheng Jiang
2020-10-19  5:49             ` Jiang, Cheng1
2020-10-20 11:20           ` [dpdk-dev] [PATCH v7 0/4] add async data path in " Cheng Jiang
2020-10-20 11:20             ` [dpdk-dev] [PATCH v7 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
2020-10-20 11:20             ` [dpdk-dev] [PATCH v7 2/4] example/vhost: add support for vhost async data path Cheng Jiang
2020-10-20 11:20             ` [dpdk-dev] [PATCH v7 3/4] doc: update vhost sample doc " Cheng Jiang
2020-10-20 11:20             ` [dpdk-dev] [PATCH v7 4/4] doc: update release notes for vhost sample Cheng Jiang
2020-10-21  6:50             ` [dpdk-dev] [PATCH v8 0/4] add async data path in " Cheng Jiang
2020-10-21  6:50               ` [dpdk-dev] [PATCH v8 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
2020-10-21  6:50               ` [dpdk-dev] [PATCH v8 2/4] example/vhost: add support for vhost async data path Cheng Jiang
2020-10-21  6:50               ` [dpdk-dev] [PATCH v8 3/4] doc: update vhost sample doc " Cheng Jiang
2020-10-21  6:50               ` [dpdk-dev] [PATCH v8 4/4] doc: update release notes for vhost sample Cheng Jiang
2020-10-22  6:46               ` [dpdk-dev] [PATCH v9 0/4] add async data path in " Cheng Jiang
2020-10-22  6:46                 ` [dpdk-dev] [PATCH v9 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
2020-10-22  6:46                 ` [dpdk-dev] [PATCH v9 2/4] example/vhost: add support for vhost async data path Cheng Jiang
2020-10-22  6:46                 ` [dpdk-dev] [PATCH v9 3/4] doc: update vhost sample doc " Cheng Jiang
2020-10-22  6:46                 ` [dpdk-dev] [PATCH v9 4/4] doc: update release notes for vhost sample Cheng Jiang
2020-10-22  9:10                 ` [dpdk-dev] [PATCH v9 0/4] add async data path in " Maxime Coquelin
2020-10-22  9:14                   ` Jiang, Cheng1
2020-10-22  8:59 ` [dpdk-dev] [PATCH v10 " Cheng Jiang
2020-10-22  8:59   ` [dpdk-dev] [PATCH v10 1/4] example/vhost: add async vhost args parsing function Cheng Jiang
2020-10-23 11:08     ` Maxime Coquelin
2020-10-22  8:59   ` [dpdk-dev] [PATCH v10 2/4] example/vhost: add support for vhost async data path Cheng Jiang
2020-10-23 11:12     ` Maxime Coquelin
2020-10-22  8:59   ` [dpdk-dev] [PATCH v10 3/4] doc: update vhost sample doc " Cheng Jiang
2020-10-23 11:15     ` Maxime Coquelin
2020-10-22  8:59   ` [dpdk-dev] [PATCH v10 4/4] doc: update release notes for vhost sample Cheng Jiang
2020-10-23 11:15     ` Maxime Coquelin
2020-10-23 11:23   ` [dpdk-dev] [PATCH v10 0/4] add async data path in " Maxime Coquelin
2020-10-23 13:20     ` Ferruh Yigit
2020-11-09 12:40     ` David Marchand
2020-11-10  3:02       ` Jiang, Cheng1
2020-11-10  8:17         ` David Marchand
2020-11-10 11:19           ` Bruce Richardson
2020-11-10 13:37             ` Thomas Monjalon
2020-11-10 14:34               ` Bruce Richardson
2020-11-10 14:40                 ` Thomas Monjalon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).