net/vhost: add options for linear and external buffer
[dpdk.git] / drivers / net / vhost / rte_eth_vhost.c
index 90263ae..4d255c6 100644 (file)
@@ -32,6 +32,8 @@ enum {VIRTIO_RXQ, VIRTIO_TXQ, VIRTIO_QNUM};
 #define ETH_VHOST_IOMMU_SUPPORT                "iommu-support"
 #define ETH_VHOST_POSTCOPY_SUPPORT     "postcopy-support"
 #define ETH_VHOST_VIRTIO_NET_F_HOST_TSO "tso"
+#define ETH_VHOST_LINEAR_BUF  "linear-buffer"
+#define ETH_VHOST_EXT_BUF  "ext-buffer"
 #define VHOST_MAX_PKT_BURST 32
 
 static const char *valid_arguments[] = {
@@ -42,6 +44,8 @@ static const char *valid_arguments[] = {
        ETH_VHOST_IOMMU_SUPPORT,
        ETH_VHOST_POSTCOPY_SUPPORT,
        ETH_VHOST_VIRTIO_NET_F_HOST_TSO,
+       ETH_VHOST_LINEAR_BUF,
+       ETH_VHOST_EXT_BUF,
        NULL
 };
 
@@ -876,14 +880,19 @@ vhost_driver_setup(struct rte_eth_dev *eth_dev)
        unsigned int numa_node = eth_dev->device->numa_node;
        const char *name = eth_dev->device->name;
 
+       /* Don't try to setup again if it has already been done. */
+       list = find_internal_resource(internal->iface_name);
+       if (list)
+               return 0;
+
        list = rte_zmalloc_socket(name, sizeof(*list), 0, numa_node);
        if (list == NULL)
-               goto error;
+               return -1;
 
        vring_state = rte_zmalloc_socket(name, sizeof(*vring_state),
                                         0, numa_node);
        if (vring_state == NULL)
-               goto error;
+               goto free_list;
 
        list->eth_dev = eth_dev;
        pthread_mutex_lock(&internal_list_lock);
@@ -894,30 +903,37 @@ vhost_driver_setup(struct rte_eth_dev *eth_dev)
        vring_states[eth_dev->data->port_id] = vring_state;
 
        if (rte_vhost_driver_register(internal->iface_name, internal->flags))
-               goto error;
+               goto list_remove;
 
        if (internal->disable_flags) {
                if (rte_vhost_driver_disable_features(internal->iface_name,
                                                      internal->disable_flags))
-                       goto error;
+                       goto drv_unreg;
        }
 
        if (rte_vhost_driver_callback_register(internal->iface_name,
                                               &vhost_ops) < 0) {
                VHOST_LOG(ERR, "Can't register callbacks\n");
-               goto error;
+               goto drv_unreg;
        }
 
        if (rte_vhost_driver_start(internal->iface_name) < 0) {
                VHOST_LOG(ERR, "Failed to start driver for %s\n",
                          internal->iface_name);
-               goto error;
+               goto drv_unreg;
        }
 
        return 0;
 
-error:
+drv_unreg:
+       rte_vhost_driver_unregister(internal->iface_name);
+list_remove:
+       vring_states[eth_dev->data->port_id] = NULL;
+       pthread_mutex_lock(&internal_list_lock);
+       TAILQ_REMOVE(&internal_list, list, next);
+       pthread_mutex_unlock(&internal_list_lock);
        rte_free(vring_state);
+free_list:
        rte_free(list);
 
        return -1;
@@ -1379,6 +1395,8 @@ rte_pmd_vhost_probe(struct rte_vdev_device *dev)
        int iommu_support = 0;
        int postcopy_support = 0;
        int tso = 0;
+       int linear_buf = 0;
+       int ext_buf = 0;
        struct rte_eth_dev *eth_dev;
        const char *name = rte_vdev_device_name(dev);
 
@@ -1476,6 +1494,28 @@ rte_pmd_vhost_probe(struct rte_vdev_device *dev)
                }
        }
 
+       if (rte_kvargs_count(kvlist, ETH_VHOST_LINEAR_BUF) == 1) {
+               ret = rte_kvargs_process(kvlist,
+                               ETH_VHOST_LINEAR_BUF,
+                               &open_int, &linear_buf);
+               if (ret < 0)
+                       goto out_free;
+
+               if (linear_buf == 1)
+                       flags |= RTE_VHOST_USER_LINEARBUF_SUPPORT;
+       }
+
+       if (rte_kvargs_count(kvlist, ETH_VHOST_EXT_BUF) == 1) {
+               ret = rte_kvargs_process(kvlist,
+                               ETH_VHOST_EXT_BUF,
+                               &open_int, &ext_buf);
+               if (ret < 0)
+                       goto out_free;
+
+               if (ext_buf == 1)
+                       flags |= RTE_VHOST_USER_EXTBUF_SUPPORT;
+       }
+
        if (dev->device.numa_node == SOCKET_ID_ANY)
                dev->device.numa_node = rte_socket_id();
 
@@ -1527,7 +1567,9 @@ RTE_PMD_REGISTER_PARAM_STRING(net_vhost,
        "dequeue-zero-copy=<0|1> "
        "iommu-support=<0|1> "
        "postcopy-support=<0|1> "
-       "tso=<0|1>");
+       "tso=<0|1> "
+       "linear-buffer=<0|1> "
+       "ext-buffer=<0|1>");
 
 RTE_INIT(vhost_init_log)
 {