summaryrefslogtreecommitdiffstats
path: root/examples/vhost/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/vhost/main.c')
-rw-r--r--examples/vhost/main.c125
1 files changed, 69 insertions, 56 deletions
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 92a98233..07098594 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -90,9 +90,6 @@
/* Size of buffers used for snprintfs. */
#define MAX_PRINT_BUFF 6072
-/* Maximum character device basename size. */
-#define MAX_BASENAME_SZ 10
-
/* Maximum long option length for option parsing. */
#define MAX_LONG_OPT_SZ 64
@@ -109,9 +106,6 @@ static uint32_t num_devices;
static struct rte_mempool *mbuf_pool;
static int mergeable;
-/* Do vlan strip on host, enabled on default */
-static uint32_t vlan_strip = 1;
-
/* Enable VM2VM communications. If this is disabled then the MAC address compare is skipped. */
typedef enum {
VM2VM_DISABLED = 0,
@@ -133,14 +127,16 @@ static uint32_t enable_tx_csum;
static uint32_t enable_tso;
static int client_mode;
+static int dequeue_zero_copy;
/* 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. */
static uint32_t burst_rx_retry_num = BURST_RX_RETRIES;
-/* Character device basename. Can be set by user. */
-static char dev_basename[MAX_BASENAME_SZ] = "vhost-net";
+/* Socket file paths. Can be set by user */
+static char *socket_files;
+static int nb_sockets;
/* empty vmdq configuration structure. Filled in programatically */
static struct rte_eth_conf vmdq_conf_default = {
@@ -299,6 +295,17 @@ port_init(uint8_t port)
rx_ring_size = RTE_TEST_RX_DESC_DEFAULT;
tx_ring_size = RTE_TEST_TX_DESC_DEFAULT;
+
+ /*
+ * When dequeue zero copy is enabled, guest Tx used vring will be
+ * updated only when corresponding mbuf is freed. Thus, the nb_tx_desc
+ * (tx_ring_size here) must be small enough so that the driver will
+ * hit the free threshold easily and free mbufs timely. Otherwise,
+ * guest Tx vring would be starved.
+ */
+ if (dequeue_zero_copy)
+ tx_ring_size = 64;
+
tx_rings = (uint16_t)rte_lcore_count();
retval = validate_num_devices(MAX_DEVICES);
@@ -392,17 +399,18 @@ port_init(uint8_t port)
}
/*
- * Set character device basename.
+ * Set socket file path.
*/
static int
-us_vhost_parse_basename(const char *q_arg)
+us_vhost_parse_socket_path(const char *q_arg)
{
/* parse number string */
-
- if (strnlen(q_arg, MAX_BASENAME_SZ) > MAX_BASENAME_SZ)
+ if (strnlen(q_arg, PATH_MAX) > PATH_MAX)
return -1;
- else
- snprintf((char*)&dev_basename, MAX_BASENAME_SZ, "%s", q_arg);
+
+ socket_files = realloc(socket_files, PATH_MAX * (nb_sockets + 1));
+ snprintf(socket_files + nb_sockets * PATH_MAX, PATH_MAX, "%s", q_arg);
+ nb_sockets++;
return 0;
}
@@ -462,7 +470,7 @@ us_vhost_usage(const char *prgname)
RTE_LOG(INFO, VHOST_CONFIG, "%s [EAL options] -- -p PORTMASK\n"
" --vm2vm [0|1|2]\n"
" --rx_retry [0|1] --mergeable [0|1] --stats [0-N]\n"
- " --dev-basename <name>\n"
+ " --socket-file <path>\n"
" --nb-devices ND\n"
" -p PORTMASK: Set mask for ports to be used by application\n"
" --vm2vm [0|1|2]: disable/software(default)/hardware vm2vm comms\n"
@@ -470,12 +478,12 @@ us_vhost_usage(const char *prgname)
" --rx-retry-delay [0-N]: timeout(in usecond) between retries on RX. This makes effect only if retries on rx enabled\n"
" --rx-retry-num [0-N]: the number of retries on rx. This makes effect only if retries on rx enabled\n"
" --mergeable [0|1]: disable(default)/enable RX mergeable buffers\n"
- " --vlan-strip [0|1]: disable/enable(default) RX VLAN strip on host\n"
" --stats [0-N]: 0: Disable stats, N: Time in seconds to print stats\n"
- " --dev-basename: The basename to be used for the character device.\n"
+ " --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"
+ " --dequeue-zero-copy enables dequeue zero copy\n",
prgname);
}
@@ -495,12 +503,12 @@ us_vhost_parse_args(int argc, char **argv)
{"rx-retry-delay", required_argument, NULL, 0},
{"rx-retry-num", required_argument, NULL, 0},
{"mergeable", required_argument, NULL, 0},
- {"vlan-strip", required_argument, NULL, 0},
{"stats", required_argument, NULL, 0},
- {"dev-basename", required_argument, NULL, 0},
+ {"socket-file", required_argument, NULL, 0},
{"tx-csum", required_argument, NULL, 0},
{"tso", required_argument, NULL, 0},
{"client", no_argument, &client_mode, 1},
+ {"dequeue-zero-copy", no_argument, &dequeue_zero_copy, 1},
{NULL, 0, 0, 0},
};
@@ -618,27 +626,12 @@ us_vhost_parse_args(int argc, char **argv)
}
}
- /* Enable/disable RX VLAN strip on host. */
- if (!strncmp(long_option[option_index].name,
- "vlan-strip", MAX_LONG_OPT_SZ)) {
- ret = parse_num_opt(optarg, 1);
- if (ret == -1) {
- RTE_LOG(INFO, VHOST_CONFIG,
- "Invalid argument for VLAN strip [0|1]\n");
- us_vhost_usage(prgname);
- return -1;
- } else {
- vlan_strip = !!ret;
- vmdq_conf_default.rxmode.hw_vlan_strip =
- vlan_strip;
- }
- }
-
/* Enable/disable stats. */
if (!strncmp(long_option[option_index].name, "stats", MAX_LONG_OPT_SZ)) {
ret = parse_num_opt(optarg, INT32_MAX);
if (ret == -1) {
- RTE_LOG(INFO, VHOST_CONFIG, "Invalid argument for stats [0..N]\n");
+ RTE_LOG(INFO, VHOST_CONFIG,
+ "Invalid argument for stats [0..N]\n");
us_vhost_usage(prgname);
return -1;
} else {
@@ -646,10 +639,13 @@ us_vhost_parse_args(int argc, char **argv)
}
}
- /* Set character device basename. */
- if (!strncmp(long_option[option_index].name, "dev-basename", MAX_LONG_OPT_SZ)) {
- if (us_vhost_parse_basename(optarg) == -1) {
- RTE_LOG(INFO, VHOST_CONFIG, "Invalid argument for character device basename (Max %d characters)\n", MAX_BASENAME_SZ);
+ /* Set socket file path. */
+ if (!strncmp(long_option[option_index].name,
+ "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);
us_vhost_usage(prgname);
return -1;
}
@@ -761,10 +757,7 @@ link_vmdq(struct vhost_dev *vdev, struct rte_mbuf *m)
"(%d) failed to add device MAC address to VMDQ\n",
vdev->vid);
- /* Enable stripping of the vlan tag as we handle routing. */
- if (vlan_strip)
- rte_eth_dev_set_vlan_strip_on_queue(ports[0],
- (uint16_t)vdev->vmdq_rx_q, 1);
+ rte_eth_dev_set_vlan_strip_on_queue(ports[0], vdev->vmdq_rx_q, 1);
/* Set device as ready for RX. */
vdev->ready = DEVICE_RX;
@@ -1340,14 +1333,27 @@ print_stats(void)
}
}
+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. */
- int ret = rte_vhost_driver_unregister((char *)&dev_basename);
- if (ret != 0)
- rte_exit(EXIT_FAILURE, "vhost driver unregister failure.\n");
+ unregister_drivers(nb_sockets);
+
exit(0);
}
@@ -1403,15 +1409,14 @@ create_mbuf_pool(uint16_t nr_port, uint32_t nr_switch_core, uint32_t mbuf_size,
}
/*
- * Main function, does initialisation and calls the per-lcore functions. The CUSE
- * device is also registered here to handle the IOCTLs.
+ * Main function, does initialisation and calls the per-lcore functions.
*/
int
main(int argc, char *argv[])
{
unsigned lcore_id, core_id = 0;
unsigned nb_ports, valid_num_ports;
- int ret;
+ int ret, i;
uint8_t portid;
static pthread_t tid;
char thread_name[RTE_MAX_THREAD_NAME_LEN];
@@ -1509,14 +1514,22 @@ main(int argc, char *argv[])
if (client_mode)
flags |= RTE_VHOST_USER_CLIENT;
- /* Register vhost(cuse or user) driver to handle vhost messages. */
- ret = rte_vhost_driver_register(dev_basename, flags);
- if (ret != 0)
- rte_exit(EXIT_FAILURE, "vhost driver register failure.\n");
+ if (dequeue_zero_copy)
+ flags |= RTE_VHOST_USER_DEQUEUE_ZERO_COPY;
+
+ /* Register vhost user driver to handle vhost messages. */
+ for (i = 0; i < nb_sockets; i++) {
+ ret = rte_vhost_driver_register
+ (socket_files + i * PATH_MAX, flags);
+ if (ret != 0) {
+ unregister_drivers(i);
+ rte_exit(EXIT_FAILURE,
+ "vhost driver register failure.\n");
+ }
+ }
rte_vhost_driver_callback_register(&virtio_net_device_ops);
- /* Start CUSE session. */
rte_vhost_driver_session_start();
return 0;