openflow: Implement OF1.4+ OFPMP_QUEUE_DESC multipart message.
[cascardo/ovs.git] / lib / netdev-dpdk.c
index e4e3d2c..de7e488 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Nicira, Inc.
+ * Copyright (c) 2014, 2015, 2016 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -242,7 +242,7 @@ struct netdev_rxq_dpdk {
     int port_id;
 };
 
-static bool thread_is_pmd(void);
+static bool dpdk_thread_is_pmd(void);
 
 static int netdev_dpdk_construct(struct netdev *);
 
@@ -749,6 +749,10 @@ netdev_dpdk_vhost_destruct(struct netdev *netdev_)
                 return;
     }
 
+    if (rte_vhost_driver_unregister(dev->vhost_id)) {
+        VLOG_ERR("Unable to remove vhost-user socket %s", dev->vhost_id);
+    }
+
     ovs_mutex_lock(&dpdk_mutex);
     list_remove(&dev->list_node);
     dpdk_mp_put(dev->dpdk_mp);
@@ -1176,7 +1180,7 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid, struct dp_packet **pkts,
     /* If we are on a non pmd thread we have to use the mempool mutex, because
      * every non pmd thread shares the same mempool cache */
 
-    if (!thread_is_pmd()) {
+    if (!dpdk_thread_is_pmd()) {
         ovs_mutex_lock(&nonpmd_mempool_mutex);
     }
 
@@ -1220,7 +1224,7 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid, struct dp_packet **pkts,
         dpdk_queue_flush(dev, qid);
     }
 
-    if (!thread_is_pmd()) {
+    if (!dpdk_thread_is_pmd()) {
         ovs_mutex_unlock(&nonpmd_mempool_mutex);
     }
 }
@@ -1686,8 +1690,12 @@ netdev_dpdk_get_status(const struct netdev *netdev_, struct smap *args)
     smap_add_format(args, "max_vfs", "%u", dev_info.max_vfs);
     smap_add_format(args, "max_vmdq_pools", "%u", dev_info.max_vmdq_pools);
 
-    smap_add_format(args, "pci-vendor_id", "0x%u", dev_info.pci_dev->id.vendor_id);
-    smap_add_format(args, "pci-device_id", "0x%x", dev_info.pci_dev->id.device_id);
+    if (dev_info.pci_dev) {
+        smap_add_format(args, "pci-vendor_id", "0x%u",
+                        dev_info.pci_dev->id.vendor_id);
+        smap_add_format(args, "pci-device_id", "0x%x",
+                        dev_info.pci_dev->id.device_id);
+    }
 
     return 0;
 }
@@ -1785,14 +1793,14 @@ new_device(struct virtio_net *dev)
     ovs_mutex_unlock(&dpdk_mutex);
 
     if (!exists) {
-        VLOG_INFO("vHost Device '%s' (%ld) can't be added - name not found",
-                   dev->ifname, dev->device_fh);
+        VLOG_INFO("vHost Device '%s' %"PRIu64" can't be added - name not "
+                  "found", dev->ifname, dev->device_fh);
 
         return -1;
     }
 
-    VLOG_INFO("vHost Device '%s' (%ld) has been added",
-               dev->ifname, dev->device_fh);
+    VLOG_INFO("vHost Device '%s' %"PRIu64" has been added", dev->ifname,
+              dev->device_fh);
     return 0;
 }
 
@@ -1830,8 +1838,8 @@ destroy_device(volatile struct virtio_net *dev)
     }
     ovs_mutex_unlock(&dpdk_mutex);
 
-    VLOG_INFO("vHost Device '%s' (%ld) has been removed",
-               dev->ifname, dev->device_fh);
+    VLOG_INFO("vHost Device '%s' %"PRIu64" has been removed", dev->ifname,
+              dev->device_fh);
 }
 
 struct virtio_net *
@@ -1927,9 +1935,9 @@ dpdk_ring_create(const char dev_name[], unsigned int port_no,
         return -err;
     }
 
-    /* Create single consumer/producer rings, netdev does explicit locking. */
+    /* Create single producer tx ring, netdev does explicit locking. */
     ivshmem->cring_tx = rte_ring_create(ring_name, DPDK_RING_SIZE, SOCKET0,
-                                        RING_F_SP_ENQ | RING_F_SC_DEQ);
+                                        RING_F_SP_ENQ);
     if (ivshmem->cring_tx == NULL) {
         rte_free(ivshmem);
         return ENOMEM;
@@ -1940,9 +1948,9 @@ dpdk_ring_create(const char dev_name[], unsigned int port_no,
         return -err;
     }
 
-    /* Create single consumer/producer rings, netdev does explicit locking. */
+    /* Create single consumer rx ring, netdev does explicit locking. */
     ivshmem->cring_rx = rte_ring_create(ring_name, DPDK_RING_SIZE, SOCKET0,
-                                        RING_F_SP_ENQ | RING_F_SC_DEQ);
+                                        RING_F_SC_DEQ);
     if (ivshmem->cring_rx == NULL) {
         rte_free(ivshmem);
         return ENOMEM;
@@ -2111,14 +2119,14 @@ process_vhost_flags(char *flag, char *default_val, int size,
      * flag if it is provided on the vswitchd command line, otherwise resort to
      * a default value.
      *
-     * For vhost-user: Process "-cuse_dev_name" to set the custom location of
+     * For vhost-user: Process "-vhost_sock_dir" to set the custom location of
      * the vhost-user socket(s).
-     * For vhost-cuse: Process "-vhost_sock_dir" to set the custom name of the
+     * For vhost-cuse: Process "-cuse_dev_name" to set the custom name of the
      * vhost-cuse character device.
      */
     if (!strcmp(argv[1], flag) && (strlen(argv[2]) <= size)) {
         changed = 1;
-        *new_val = strdup(argv[2]);
+        *new_val = xstrdup(argv[2]);
         VLOG_INFO("User-provided %s in use: %s", flag, *new_val);
     } else {
         VLOG_INFO("No %s provided - defaulting to %s", flag, default_val);
@@ -2142,11 +2150,19 @@ dpdk_init(int argc, char **argv)
     argc--;
     argv++;
 
+    /* Reject --user option */
+    int i;
+    for (i = 0; i < argc; i++) {
+        if (!strcmp(argv[i], "--user")) {
+            VLOG_ERR("Can not mix --dpdk and --user options, aborting.");
+        }
+    }
+
 #ifdef VHOST_CUSE
-    if (process_vhost_flags("-cuse_dev_name", strdup("vhost-net"),
+    if (process_vhost_flags("-cuse_dev_name", xstrdup("vhost-net"),
                             PATH_MAX, argv, &cuse_dev_name)) {
 #else
-    if (process_vhost_flags("-vhost_sock_dir", strdup(ovs_rundir()),
+    if (process_vhost_flags("-vhost_sock_dir", xstrdup(ovs_rundir()),
                             NAME_MAX, argv, &vhost_sock_dir)) {
         struct stat s;
         int err;
@@ -2290,7 +2306,7 @@ pmd_thread_setaffinity_cpu(unsigned cpu)
 }
 
 static bool
-thread_is_pmd(void)
+dpdk_thread_is_pmd(void)
 {
     return rte_lcore_id() != NON_PMD_CORE_ID;
 }