DPDK patches and discussions
 help / color / mirror / Atom feed
From: Ye Xiaolong <xiaolong.ye@intel.com>
To: Sivaprasad Tummala <Sivaprasad.Tummala@intel.com>
Cc: Maxime Coquelin <maxime.coquelin@redhat.com>,
	Zhihong Wang <zhihong.wang@intel.com>,
	John McNamara <john.mcnamara@intel.com>,
	Marko Kovacevic <marko.kovacevic@intel.com>,
	dev@dpdk.org
Subject: Re: [dpdk-dev] [DPDK v1] examples/vhost: add vhostpmd support
Date: Sun, 22 Mar 2020 19:57:17 +0800	[thread overview]
Message-ID: <20200322115717.GA2334@intel.com> (raw)
In-Reply-To: <20200311052401.12063-1-Sivaprasad.Tummala@intel.com>

Hi, Tummala

A few comments inline.

On 03/11, Sivaprasad Tummala wrote:
>Added vHostPMD based configuration of vHost devices.
>Currently vHost library calls are used for configuring the
>vhost device.
>
>vHostPMD is a pre-requisite for enabling future features
>supported such as FPGA and possibly CBDMA. With the
>vHostPMD integration, upstream features in PMD can be easily
>supported and additional features such as queue stats for
>vhost devices can be useful.
>
>With the patch, user has an option to select
>vHost PMD by passing "--use-vhost-pmd" option.
>Disabled by default.
>
>Note: vHost multi-queue is not enabled on this patch.
>
>Signed-off-by: Sivaprasad Tummala <Sivaprasad.Tummala@intel.com>
>---
> doc/guides/sample_app_ug/vhost.rst |   4 +
> examples/vhost/Makefile            |   4 +
> examples/vhost/main.c              | 475 ++++++++++++++++++++++++-----
> examples/vhost/main.h              |   1 +
> examples/vhost/meson.build         |   3 +-
> 5 files changed, 402 insertions(+), 85 deletions(-)
>
>diff --git a/doc/guides/sample_app_ug/vhost.rst b/doc/guides/sample_app_ug/vhost.rst
>index a71ada654..bb6275249 100644
>--- a/doc/guides/sample_app_ug/vhost.rst
>+++ b/doc/guides/sample_app_ug/vhost.rst
>@@ -152,6 +152,10 @@ note that if NIC is bound to driver with iommu enabled, dequeue zero copy
> cannot work at VM2NIC mode (vm2vm=0) due to currently we don't setup iommu
> dma mapping for guest memory.
> 
>+**--use-vhost-pmd**
>+vHost DPDK PMD will be enabled when this option is given. By default, vHost
>+direct library calls are used to configure devices.
>+
> **--vlan-strip 0|1**
> VLAN strip option is removed, because different NICs have different behaviors
> when disabling VLAN strip. Such feature, which heavily depends on hardware,
>diff --git a/examples/vhost/Makefile b/examples/vhost/Makefile
>index f2b161541..727cbe9d3 100644
>--- a/examples/vhost/Makefile
>+++ b/examples/vhost/Makefile
>@@ -63,6 +63,10 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
> CFLAGS += -O2 -D_FILE_OFFSET_BITS=64
> CFLAGS += $(WERROR_FLAGS)
> 
>+ifeq ($(CONFIG_RTE_LIBRTE_PMD_VHOST),y)
>+LDLIBS += -lrte_pmd_vhost
>+endif
>+
> include $(RTE_SDK)/mk/rte.extapp.mk
> 
> endif
>diff --git a/examples/vhost/main.c b/examples/vhost/main.c
>index ab649bf14..b3e331045 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>
>+#ifdef RTE_LIBRTE_PMD_VHOST
>+#include <rte_eth_vhost.h>
>+#endif
> 
> #include "main.h"
> 
>@@ -96,6 +99,9 @@ static int dequeue_zero_copy;
> 
> static int builtin_net_driver;
> 
>+/* Use vHost PMD instead of vHost library (Default) */
>+static int vhost_pmd;
>+
> /* 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 +188,12 @@ struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];
> 				 / US_PER_S * BURST_TX_DRAIN_US)
> #define VLAN_HLEN       4
> 
>+static int
>+vhost_device_event_callback(uint16_t port_id,
>+				  enum rte_eth_event_type type,
>+				  void *param __rte_unused,
>+				  void *ret_param __rte_unused);
>+
> /*
>  * Builds up the correct configuration for VMDQ VLAN pool map
>  * according to the pool & queue limits.
>@@ -211,6 +223,151 @@ get_eth_conf(struct rte_eth_conf *eth_conf, uint32_t num_devices)
> 	return 0;
> }
> 
>+/*
>+ * Device removal before application exit
>+ * for the device to be re-used
>+ */
>+static void
>+unregister_device(int socket_num)

I think it's the updated version of previous unregister_drivers, why change
its name to unregister_device?

>+{
>+	int ret;
>+
>+	if (vhost_pmd) {
>+		char drv_name[RTE_ETH_NAME_MAX_LEN];
>+		struct vhost_dev *vdev = NULL;
>+		uint16_t port_id;
>+
>+		snprintf(drv_name, RTE_ETH_NAME_MAX_LEN,
>+						"net_vhost%d", socket_num);
>+		ret = rte_eth_dev_get_port_by_name(drv_name, &port_id);
>+		if (ret != 0)
>+			rte_exit(EXIT_FAILURE,
>+				"vhost device port id get failed.\n");

main func would call rte_exit after unregister_driver, so we could just call RTE_LOG
here as the non-vhost-pmd case.

>+
>+		TAILQ_FOREACH(vdev, &vhost_dev_list, global_vdev_entry) {
>+			if (vdev->eth_dev_id == port_id) {
>+				vdev->remove = 1;
>+				break;
>+			}
>+		}
>+
>+		/* Close the Ethernet device */
>+		rte_eth_dev_close(port_id);
>+	} else {
>+		ret = rte_vhost_driver_unregister(socket_files +
>+					socket_num * PATH_MAX);
>+		if (ret != 0)
>+			RTE_LOG(ERR, VHOST_CONFIG,
>+				"Fail to unregister vhost driver for %s.\n",
>+				socket_files + socket_num * PATH_MAX);
>+	}
>+}
>+
>+/*
>+ * Initialises a given port using global settings and with the rx buffers
>+ * coming from the mbuf_pool passed as parameter
>+ */
>+static inline int
>+port_init_v2(uint16_t portid)

What about naming it vhost_pmd_port_init to be more descriptive?

>+{
>+	struct rte_eth_rxconf rxq_conf;
>+	struct rte_eth_txconf txq_conf;
>+	struct rte_eth_dev_info dev_info;
>+	struct rte_eth_conf port_conf = {
>+		.rxmode = {
>+			.split_hdr_size = 0,
>+		},
>+		.txmode = {
>+			.mq_mode = ETH_MQ_TX_NONE,
>+		},
>+	};
>+	uint16_t nb_rxd, nb_txd;
>+	int ret = 0;
>+
>+	/* init port */
>+	printf("Initializing port %u... ", portid);
>+	fflush(stdout);
>+
>+	ret = rte_eth_dev_info_get(portid, &dev_info);
>+	if (ret != 0)
>+		rte_exit(EXIT_FAILURE,
>+			"Error during getting device (port %u) info: %s\n",
>+			portid, strerror(-ret));

main would check the return value of port_init and call ret_exit for failure case,
we can just call RTE_LOG here.

>+
>+	if (strncmp(dev_info.driver_name, "net_vhost",
>+				sizeof("net_vhost")) == 0)
>+		rte_eth_dev_callback_register(portid,
>+			RTE_ETH_EVENT_INTR_LSC,
>+			vhost_device_event_callback, NULL);
>+
>+	ret = rte_eth_dev_configure(portid, 1, 1, &port_conf);
>+	if (ret < 0)
>+		rte_exit(EXIT_FAILURE, "Cannot configure device: err=%d, port=%u\n",
>+			  ret, portid);
>+
>+	nb_rxd = RTE_TEST_RX_DESC_DEFAULT;
>+	nb_txd = RTE_TEST_TX_DESC_DEFAULT;
>+
>+	ret = rte_eth_dev_adjust_nb_rx_tx_desc(portid, &nb_rxd,
>+						   &nb_txd);
>+	if (ret < 0)
>+		rte_exit(EXIT_FAILURE,
>+			 "Cannot adjust number of descriptors: err=%d, port=%u\n",
>+			 ret, portid);
>+
>+	ret = rte_eth_macaddr_get(portid,
>+				  &vmdq_ports_eth_addr[portid]);
>+	if (ret < 0)
>+		rte_exit(EXIT_FAILURE,
>+			 "Cannot get MAC address: err=%d, port=%u\n",
>+			 ret, portid);
>+
>+	/* init RX queue */
>+	fflush(stdout);
>+	rxq_conf = dev_info.default_rxconf;
>+	rxq_conf.offloads = port_conf.rxmode.offloads;
>+	ret = rte_eth_rx_queue_setup(portid, 0, nb_rxd,
>+					 rte_eth_dev_socket_id(portid),
>+					 &rxq_conf,
>+					 mbuf_pool);
>+	if (ret < 0)
>+		rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup:err=%d, port=%u\n",
>+			  ret, portid);
>+
>+	/* init TX queue */
>+	fflush(stdout);
>+	txq_conf = dev_info.default_txconf;
>+	txq_conf.offloads = port_conf.txmode.offloads;
>+	ret = rte_eth_tx_queue_setup(portid, 0, nb_txd,
>+			rte_eth_dev_socket_id(portid),
>+			&txq_conf);
>+	if (ret < 0)
>+		rte_exit(EXIT_FAILURE, "rte_eth_tx_queue_setup:err=%d, port=%u\n",
>+			ret, portid);
>+
>+	/* Start device */
>+	ret = rte_eth_dev_start(portid);
>+	if (ret < 0)
>+		rte_exit(EXIT_FAILURE, "rte_eth_dev_start:err=%d, port=%u\n",
>+				ret, portid);
>+
>+	if (promiscuous) {
>+		ret = rte_eth_promiscuous_enable(portid);
>+		if ((ret != 0) && (ret != -ENOTSUP)) {
>+			uint8_t i;
>+
>+			for (i = 0; i < nb_sockets; i++)
>+				unregister_device(i);
>+
>+			rte_exit(EXIT_FAILURE,
>+				 "rte_eth_promiscuous_enable:err=%s, port=%u\n",
>+				 rte_strerror(-ret), portid);
>+		}
>+	}
>+
>+	return 0;
>+}
>+
> /*
>  * Initialises a given port using global settings and with the rx buffers
>  * coming from the mbuf_pool passed as parameter
>@@ -461,7 +618,8 @@ 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"
>+	"		--use-vhost-pmd enables vHost PMD instead of vHost library\n",
> 	       prgname);
> }
> 
>@@ -488,6 +646,7 @@ 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},
>+		{"use-vhost-pmd", no_argument, &vhost_pmd, 1},
> 		{NULL, 0, 0, 0},
> 	};
> 
>@@ -1047,37 +1206,61 @@ drain_eth_rx(struct vhost_dev *vdev)
> 	if (!rx_count)
> 		return;
> 
>-	/*
>-	 * When "enable_retry" is set, here we wait and retry when there
>-	 * is no enough free slots in the queue to hold @rx_count packets,
>-	 * to diminish packet loss.
>-	 */
>-	if (enable_retry &&
>-	    unlikely(rx_count > rte_vhost_avail_entries(vdev->vid,
>-			VIRTIO_RXQ))) {
>-		uint32_t retry;
>-
>-		for (retry = 0; retry < burst_rx_retry_num; retry++) {
>-			rte_delay_us(burst_rx_delay_time);
>-			if (rx_count <= rte_vhost_avail_entries(vdev->vid,
>-					VIRTIO_RXQ))
>-				break;
>+	if (vhost_pmd) {
>+		enqueue_count = rte_eth_tx_burst(vdev->eth_dev_id, 0,
>+			pkts, rx_count);
>+		if (unlikely(enqueue_count < rx_count)) {
>+			uint32_t retry, pending = rx_count - enqueue_count;
>+			for (retry = 0; retry < burst_rx_retry_num; retry++) {
>+				rte_delay_us(burst_rx_delay_time);
>+				enqueue_count += rte_eth_tx_burst(
>+					vdev->eth_dev_id, 0,
>+					(pkts + enqueue_count), pending);
>+				pending = rx_count - enqueue_count;
>+
>+				if (enqueue_count == rx_count)
>+					break;
>+			}
>+			/* Drop the remaining packets */
>+			uint32_t idx;

This mixed declaration and code statement.

>+			for (idx = enqueue_count; idx < rx_count; idx++)
>+				rte_pktmbuf_free(pkts[idx]);
> 		}
>-	}
>-
>-	if (builtin_net_driver) {
>-		enqueue_count = vs_enqueue_pkts(vdev, VIRTIO_RXQ,
>-						pkts, rx_count);
> 	} else {
>-		enqueue_count = rte_vhost_enqueue_burst(vdev->vid, VIRTIO_RXQ,
>-						pkts, rx_count);
>+		/*
>+		 * When "enable_retry" is set, here we wait and retry
>+		 * when there is no enough free slots in the queue to
>+		 * hold @rx_count packets, to diminish packet loss.
>+		 */
>+		if (enable_retry &&
>+			unlikely(rx_count > rte_vhost_avail_entries(
>+				vdev->vid, VIRTIO_RXQ))) {
>+			uint32_t retry;
>+
>+			for (retry = 0; retry <
>+				burst_rx_retry_num; retry++) {
>+				rte_delay_us(burst_rx_delay_time);
>+				if (rx_count <= rte_vhost_avail_entries(
>+					vdev->vid, VIRTIO_RXQ))
>+					break;
>+			}
>+		}
>+
>+		if (builtin_net_driver) {
>+			enqueue_count = vs_enqueue_pkts(vdev, VIRTIO_RXQ,
>+							pkts, rx_count);
>+		} else {
>+			enqueue_count = rte_vhost_enqueue_burst(vdev->vid,
>+				VIRTIO_RXQ,	pkts, rx_count);
>+		}
>+
>+		free_pkts(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);
> }
> 
> static __rte_always_inline void
>@@ -1087,12 +1270,20 @@ drain_virtio_tx(struct vhost_dev *vdev)
> 	uint16_t count;
> 	uint16_t i;
> 
>-	if (builtin_net_driver) {
>-		count = vs_dequeue_pkts(vdev, VIRTIO_TXQ, mbuf_pool,
>-					pkts, MAX_PKT_BURST);
>+	if (vhost_pmd) {
>+		count = rte_eth_rx_burst(vdev->eth_dev_id,
>+					0, pkts, MAX_PKT_BURST);
>+		if (!count)
>+			return;
>+
> 	} else {
>-		count = rte_vhost_dequeue_burst(vdev->vid, VIRTIO_TXQ,
>-					mbuf_pool, pkts, MAX_PKT_BURST);
>+		if (builtin_net_driver) {
>+			count = vs_dequeue_pkts(vdev, VIRTIO_TXQ, mbuf_pool,
>+						pkts, MAX_PKT_BURST);
>+		} else {
>+			count = rte_vhost_dequeue_burst(vdev->vid, VIRTIO_TXQ,
>+						mbuf_pool, pkts, MAX_PKT_BURST);
>+		}
> 	}
> 
> 	/* setup VMDq for the first packet */
>@@ -1291,6 +1482,91 @@ static const struct vhost_device_ops virtio_net_device_ops =
> 	.destroy_device = destroy_device,
> };
> 
>+static int
>+vhost_device_attach_callback(uint16_t port_id)
>+{
>+	int lcore, core_add = 0, vid = -1;
>+	uint32_t device_num_min = num_devices;
>+	struct vhost_dev *vdev;
>+
>+#ifdef RTE_LIBRTE_PMD_VHOST
>+	vid = rte_eth_vhost_get_vid_from_port_id(port_id);
>+#endif
>+
>+	vdev = rte_zmalloc("vhost device", sizeof(*vdev), RTE_CACHE_LINE_SIZE);
>+	if (vdev == NULL) {
>+		RTE_LOG(INFO, VHOST_DATA,
>+			"(%d) couldn't allocate memory for vhost dev\n",
>+			vid);
>+		return -1;
>+	}
>+
>+	if (builtin_net_driver)
>+		vs_vhost_net_setup(vdev);
>+
>+	TAILQ_INSERT_TAIL(&vhost_dev_list, vdev, global_vdev_entry);
>+	vdev->vmdq_rx_q = vid * queues_per_pool + vmdq_queue_base;
>+
>+	/*reset ready flag*/
>+	vdev->ready = DEVICE_MAC_LEARNING;
>+	vdev->remove = 0;
>+
>+	vdev->vid = vid;
>+	vdev->eth_dev_id = port_id;
>+
>+	/* Find a suitable lcore to add the device. */
>+	RTE_LCORE_FOREACH_SLAVE(lcore) {
>+		if (lcore_info[lcore].device_num < device_num_min) {
>+			device_num_min = lcore_info[lcore].device_num;
>+			core_add = lcore;
>+		}
>+	}
>+	vdev->coreid = core_add;
>+
>+	TAILQ_INSERT_TAIL(&lcore_info[vdev->coreid].vdev_list, vdev,
>+			  lcore_vdev_entry);
>+	lcore_info[vdev->coreid].device_num++;
>+
>+	return 0;
>+}
>+
>+int
>+vhost_device_event_callback(uint16_t port_id,
>+				enum rte_eth_event_type type,
>+				void *param __rte_unused,
>+				void *ret_param __rte_unused)
>+{
>+	struct rte_eth_link link;
>+	int vid = -1;
>+
>+	if (type == RTE_ETH_EVENT_INTR_LSC) {
>+		rte_eth_link_get_nowait(port_id, &link);
>+
>+		if (link.link_status) {
>+			RTE_LOG(INFO, VHOST_DATA,
>+				"Port %d Link Up - speed %u Mbps - %s\n",
>+				port_id, (unsigned int) link.link_speed,
>+				(link.link_duplex == ETH_LINK_FULL_DUPLEX)
>+				? "full-duplex" : "half-duplex");
>+			if (vhost_device_attach_callback(port_id) != 0) {
>+				RTE_LOG(ERR, VHOST_DATA,
>+					"vhost dev (%d) attach callback failed\n",
>+					port_id);
>+				return -1;
>+			}
>+		} else {
>+			RTE_LOG(INFO, VHOST_DATA, "Port %d Link Down\n",
>+					port_id);
>+#ifdef RTE_LIBRTE_PMD_VHOST
>+			vid = rte_eth_vhost_get_vid_from_port_id(port_id);
>+#endif
>+			destroy_device(vid);
>+		}
>+	}
>+
>+	return 0;
>+}
>+
> /*
>  * This is a thread will wake up after a period to print stats if the user has
>  * enabled them.
>@@ -1339,26 +1615,15 @@ print_stats(__rte_unused void *arg)
> 	return NULL;
> }
> 
>-static void
>-unregister_drivers(int socket_num)
>-{
>-	int i, ret;
>-
>-	for (i = 0; i < socket_num; i++) {
>-		ret = rte_vhost_driver_unregister(socket_files + i * PATH_MAX);
>-		if (ret != 0)
>-			RTE_LOG(ERR, VHOST_CONFIG,
>-				"Fail to unregister vhost driver for %s.\n",
>-				socket_files + i * PATH_MAX);
>-	}
>-}
>-
> /* When we receive a INT signal, unregister vhost driver */
> static void
> sigint_handler(__rte_unused int signum)
> {
> 	/* Unregister vhost driver. */
>-	unregister_drivers(nb_sockets);
>+	uint8_t i;
>+
>+	for (i = 0; i < nb_sockets; i++)
>+		unregister_device(i);
> 
> 	exit(0);
> }
>@@ -1441,6 +1706,14 @@ main(int argc, char *argv[])
> 	if (ret < 0)
> 		rte_exit(EXIT_FAILURE, "Invalid argument\n");
> 
>+#ifndef RTE_LIBRTE_PMD_VHOST
>+	if (vhost_pmd == 1) {
>+		RTE_LOG(ERR, VHOST_CONFIG, "Use vHost PMD is not supported\n");
>+		rte_exit(EXIT_FAILURE, "vHost PMD should be enabled in"
>+			" config file\n");
>+	}
>+#endif
>+
> 	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
> 		TAILQ_INIT(&lcore_info[lcore_id].vdev_list);
> 
>@@ -1517,52 +1790,86 @@ 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;
>-		ret = rte_vhost_driver_register(file, flags);
>-		if (ret != 0) {
>-			unregister_drivers(i);
>-			rte_exit(EXIT_FAILURE,
>-				"vhost driver register failure.\n");
>-		}
> 
>-		if (builtin_net_driver)
>-			rte_vhost_driver_set_features(file, VIRTIO_NET_FEATURES);
>+		if (vhost_pmd) {
>+			char dev_name[PATH_MAX];
>+			char drv_name[RTE_ETH_NAME_MAX_LEN];
>+			uint16_t port;
>+
>+			snprintf(drv_name, RTE_ETH_NAME_MAX_LEN,
>+				"net_vhost%d", i);
>+			snprintf(dev_name, PATH_MAX, "%s,"
>+				"iface=%s,client=%d,tso=%d,"
>+				"dequeue-zero-copy=%d",
>+				drv_name, file, client_mode,
>+				enable_tso, dequeue_zero_copy);
>+
>+			ret = rte_dev_probe(dev_name);

I am wondering whether we can use vhost-pmd by specifying net_vhost vdev in eal options.

>+			if (ret != 0) {
>+				rte_exit(EXIT_FAILURE,
>+					"vhost user device probe failed\n");
>+			}
>+			ret = rte_eth_dev_get_port_by_name(drv_name, &port);
>+			if (ret != 0) {
>+				unregister_device(i);

Here unregister_device only deals with one registered vhost driver, but we need
to get rid of all registered ones before rte_exit, right?
And same for below 2 unregister.

>+				rte_exit(EXIT_FAILURE,
>+					"vhost device port id get failed.\n");
>+			}
>+			ret = port_init_v2(port);
>+			if (ret != 0) {
>+				unregister_device(i);
>+				rte_exit(EXIT_FAILURE,
>+					"vhost device port initialization failed.\n");
>+			}
>+		} else {
>+			ret = rte_vhost_driver_register(file, flags);
>+			if (ret != 0) {
>+				unregister_device(i);
>+				rte_exit(EXIT_FAILURE,
>+					"vhost driver register failure.\n");
>+			}
> 
>-		if (mergeable == 0) {
>-			rte_vhost_driver_disable_features(file,
>-				1ULL << VIRTIO_NET_F_MRG_RXBUF);
>-		}
>+			if (builtin_net_driver)
>+				rte_vhost_driver_set_features(file,
>+					VIRTIO_NET_FEATURES);
> 
>-		if (enable_tx_csum == 0) {
>-			rte_vhost_driver_disable_features(file,
>-				1ULL << VIRTIO_NET_F_CSUM);
>-		}
>+			if (mergeable == 0) {
>+				rte_vhost_driver_disable_features(file,
>+					1ULL << VIRTIO_NET_F_MRG_RXBUF);
>+			}
> 
>-		if (enable_tso == 0) {
>-			rte_vhost_driver_disable_features(file,
>-				1ULL << VIRTIO_NET_F_HOST_TSO4);
>-			rte_vhost_driver_disable_features(file,
>-				1ULL << VIRTIO_NET_F_HOST_TSO6);
>-			rte_vhost_driver_disable_features(file,
>-				1ULL << VIRTIO_NET_F_GUEST_TSO4);
>-			rte_vhost_driver_disable_features(file,
>-				1ULL << VIRTIO_NET_F_GUEST_TSO6);
>-		}
>+			if (enable_tx_csum == 0) {
>+				rte_vhost_driver_disable_features(file,
>+					1ULL << VIRTIO_NET_F_CSUM);
>+			}
> 
>-		if (promiscuous) {
>-			rte_vhost_driver_enable_features(file,
>-				1ULL << VIRTIO_NET_F_CTRL_RX);
>-		}
>+			if (enable_tso == 0) {
>+				rte_vhost_driver_disable_features(file,
>+					1ULL << VIRTIO_NET_F_HOST_TSO4);
>+				rte_vhost_driver_disable_features(file,
>+					1ULL << VIRTIO_NET_F_HOST_TSO6);
>+				rte_vhost_driver_disable_features(file,
>+					1ULL << VIRTIO_NET_F_GUEST_TSO4);
>+				rte_vhost_driver_disable_features(file,
>+					1ULL << VIRTIO_NET_F_GUEST_TSO6);
>+			}
> 
>-		ret = rte_vhost_driver_callback_register(file,
>-			&virtio_net_device_ops);
>-		if (ret != 0) {
>-			rte_exit(EXIT_FAILURE,
>-				"failed to register vhost driver callbacks.\n");
>-		}
>+			if (promiscuous) {
>+				rte_vhost_driver_enable_features(file,
>+					1ULL << VIRTIO_NET_F_CTRL_RX);
>+			}
> 
>-		if (rte_vhost_driver_start(file) < 0) {
>-			rte_exit(EXIT_FAILURE,
>-				"failed to start vhost driver.\n");
>+			ret = rte_vhost_driver_callback_register(file,
>+				&virtio_net_device_ops);
>+			if (ret != 0) {
>+				rte_exit(EXIT_FAILURE,
>+					"failed to register vhost driver callbacks.\n");
>+			}
>+
>+			if (rte_vhost_driver_start(file) < 0) {
>+				rte_exit(EXIT_FAILURE,
>+					"failed to start vhost driver.\n");
>+			}
> 		}
> 	}
> 
>diff --git a/examples/vhost/main.h b/examples/vhost/main.h
>index 7cba0edbf..023f43891 100644
>--- a/examples/vhost/main.h
>+++ b/examples/vhost/main.h
>@@ -48,6 +48,7 @@ struct vhost_dev {
> 	volatile uint8_t remove;
> 
> 	int vid;
>+	uint16_t eth_dev_id;
> 	uint64_t features;
> 	size_t hdr_len;
> 	uint16_t nr_vrings;
>diff --git a/examples/vhost/meson.build b/examples/vhost/meson.build
>index 872d51153..158add5eb 100644
>--- a/examples/vhost/meson.build
>+++ b/examples/vhost/meson.build
>@@ -9,7 +9,8 @@
> if not is_linux
> 	build = false
> endif
>-deps += 'vhost'
>+build = dpdk_conf.has('RTE_LIBRTE_PMD_VHOST')
>+deps += 'pmd_vhost'
> allow_experimental_apis = true
> sources = files(
> 	'main.c', 'virtio_net.c'
>-- 
>2.17.1
>

      reply	other threads:[~2020-03-22 12:00 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-11  5:24 Sivaprasad Tummala
2020-03-22 11:57 ` Ye Xiaolong [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200322115717.GA2334@intel.com \
    --to=xiaolong.ye@intel.com \
    --cc=Sivaprasad.Tummala@intel.com \
    --cc=dev@dpdk.org \
    --cc=john.mcnamara@intel.com \
    --cc=marko.kovacevic@intel.com \
    --cc=maxime.coquelin@redhat.com \
    --cc=zhihong.wang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).