diff mbox

[ovs-dev,RFC,1/1] netdev-dpdk: Arbitrary 'dpdk' port naming

Message ID 1465913254-19624-2-git-send-email-ciara.loftus@intel.com
State Superseded
Delegated to: Daniele Di Proietto
Headers show

Commit Message

Ciara Loftus June 14, 2016, 2:07 p.m. UTC
'dpdk' ports no longer have naming restrictions. Now, instead
of specifying the dpdk port ID as part of the name, the PCI
address of the device must be specified via the 'dpdk-pci'
option. eg.

ovs-vsctl add-port br0 my-port
ovs-vsctl set Interface my-port type=dpdk
ovs-vsctl set Interface my-port options:dpdk-pci=0000:06:00.3

Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
 INSTALL.DPDK.md   | 10 ++++----
 NEWS              |  2 ++
 lib/netdev-dpdk.c | 71 +++++++++++++++++++++++++++++++++++++++++++++----------
 3 files changed, 66 insertions(+), 17 deletions(-)
diff mbox

Patch

diff --git a/INSTALL.DPDK.md b/INSTALL.DPDK.md
index c2e32bf..f4df0a7 100644
--- a/INSTALL.DPDK.md
+++ b/INSTALL.DPDK.md
@@ -208,13 +208,13 @@  Using the DPDK with ovs-vswitchd:
 
    `ovs-vsctl add-br br0 -- set bridge br0 datapath_type=netdev`
 
-   Now you can add dpdk devices. OVS expects DPDK device names to start with
-   "dpdk" and end with a portid. vswitchd should print (in the log file) the
-   number of dpdk devices found.
+   Now you can add dpdk devices. The PCI address of the device needs to be
+   set using the 'dpdk-pci' option. vswitchd should print (in the log file)
+   the number and PCI addresses of dpdk devices found.
 
    ```
-   ovs-vsctl add-port br0 dpdk0 -- set Interface dpdk0 type=dpdk
-   ovs-vsctl add-port br0 dpdk1 -- set Interface dpdk1 type=dpdk
+   ovs-vsctl add-port br0 dpdk0 -- set Interface dpdk0 type=dpdk options:dpdk-pci=0000:06:00.0
+   ovs-vsctl add-port br0 dpdk1 -- set Interface dpdk1 type=dpdk options:dpdk-pci=0000:06:00.1
    ```
 
    Once first DPDK port is added to vswitchd, it creates a Polling thread and
diff --git a/NEWS b/NEWS
index 08094c5..4ecc3c2 100644
--- a/NEWS
+++ b/NEWS
@@ -35,6 +35,8 @@  Post-v2.5.0
        arguments. Additional arguments can be passed via the dpdk-extra
        entry.
      * Add ingress policing functionality.
+     * DPDK physical ports can now have arbitrary names. The PCI address of
+       the device must be set using the 'dpdk-pci' option.
    - ovs-benchmark: This utility has been removed due to lack of use and
      bitrot.
    - ovs-appctl:
diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index 19d355f..e2aeda9 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -141,6 +141,10 @@  static char *cuse_dev_name = NULL;    /* Character device cuse_dev_name. */
 #endif
 static char *vhost_sock_dir = NULL;   /* Location of vhost-user sockets */
 
+static uint8_t nb_ports; /* Number of DPDK ports initialised */
+struct rte_pci_addr pci_devs[RTE_MAX_ETHPORTS]; /* PCI info of initialised DPDK
+                                                   devices */
+
 /*
  * Maximum amount of time in micro seconds to try and enqueue to vhost.
  */
@@ -754,7 +758,7 @@  netdev_dpdk_init(struct netdev *netdev, unsigned int port_no,
     /* If the 'sid' is negative, it means that the kernel fails
      * to obtain the pci numa info.  In that situation, always
      * use 'SOCKET0'. */
-    if (type == DPDK_DEV_ETH) {
+    if (type == DPDK_DEV_ETH && (dev->port_id != -1)) {
         sid = rte_eth_dev_socket_id(port_no);
     } else {
         sid = rte_lcore_to_socket_id(rte_get_master_lcore());
@@ -791,9 +795,11 @@  netdev_dpdk_init(struct netdev *netdev, unsigned int port_no,
 
     if (type == DPDK_DEV_ETH) {
         netdev_dpdk_alloc_txq(dev, NR_QUEUE);
-        err = dpdk_eth_dev_init(dev);
-        if (err) {
-            goto unlock;
+        if (dev->port_id != -1) {
+            err = dpdk_eth_dev_init(dev);
+            if (err) {
+                goto unlock;
+            }
         }
     } else {
         netdev_dpdk_alloc_txq(dev, OVS_VHOST_MAX_QUEUE_NUM);
@@ -905,21 +911,14 @@  netdev_dpdk_vhost_user_construct(struct netdev *netdev)
 static int
 netdev_dpdk_construct(struct netdev *netdev)
 {
-    unsigned int port_no;
     int err;
 
     if (rte_eal_init_ret) {
         return rte_eal_init_ret;
     }
 
-    /* Names always start with "dpdk" */
-    err = dpdk_dev_parse_name(netdev->name, "dpdk", &port_no);
-    if (err) {
-        return err;
-    }
-
     ovs_mutex_lock(&dpdk_mutex);
-    err = netdev_dpdk_init(netdev, port_no, DPDK_DEV_ETH);
+    err = netdev_dpdk_init(netdev, -1, DPDK_DEV_ETH);
     ovs_mutex_unlock(&dpdk_mutex);
     return err;
 }
@@ -998,11 +997,36 @@  netdev_dpdk_get_config(const struct netdev *netdev, struct smap *args)
     return 0;
 }
 
+static void
+netdev_dpdk_attach_pci(struct netdev_dpdk *dev, struct rte_pci_addr *addr)
+{
+    int i = 0;
+
+    for (i = 0; i < nb_ports; i++) {
+        if (!rte_eal_compare_pci_addr(&pci_devs[i], addr)) {
+            dev->port_id = i;
+            break;
+        }
+    }
+
+    if (dev->port_id != -1) {
+        rte_eth_dev_stop(dev->port_id);
+        dev->socket_id = rte_eth_dev_socket_id(dev->port_id);
+        dpdk_eth_dev_init(dev);
+    } else {
+        VLOG_INFO("Invalid PCI address for device %s", dev->up.name);
+    }
+
+    return;
+}
+
 static int
 netdev_dpdk_set_config(struct netdev *netdev, const struct smap *args)
 {
     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
     int new_n_rxq;
+    struct rte_pci_addr addr;
+    const char *pci_str;
 
     ovs_mutex_lock(&dev->mutex);
     new_n_rxq = MAX(smap_get_int(args, "n_rxq", dev->requested_n_rxq), 1);
@@ -1010,6 +1034,19 @@  netdev_dpdk_set_config(struct netdev *netdev, const struct smap *args)
         dev->requested_n_rxq = new_n_rxq;
         netdev_request_reconfigure(netdev);
     }
+
+    if (dev->port_id == -1) {
+        pci_str = smap_get(args, "dpdk-pci");
+        if (pci_str != NULL) {
+            if (!eal_parse_pci_DomBDF(pci_str, &addr)) {
+                netdev_dpdk_attach_pci(dev, &addr);
+            } else {
+                VLOG_ERR("Error parsing PCI address %s, please check format",
+                          pci_str);
+            }
+        }
+    }
+
     ovs_mutex_unlock(&dev->mutex);
 
     return 0;
@@ -3274,6 +3311,8 @@  dpdk_init__(const struct smap *ovs_other_config)
     int argc, argc_tmp;
     bool auto_determine = true;
     int err = 0;
+    int i = 0;
+    struct rte_eth_dev_info info;
     cpu_set_t cpuset;
 #ifndef VHOST_CUSE
     char *sock_dir_subcomponent;
@@ -3396,6 +3435,14 @@  dpdk_init__(const struct smap *ovs_other_config)
 
     atexit(deferred_argv_release);
 
+    nb_ports = rte_eth_dev_count();
+    for (i = 0; i < nb_ports; i++) {
+        rte_eth_dev_info_get(i, &info);
+        pci_devs[i] = info.pci_dev->addr;
+        VLOG_INFO("DPDK PCI device %i:%i:%i.%i available", pci_devs[i].domain,
+                   pci_devs[i].bus, pci_devs[i].devid, pci_devs[i].function);
+    }
+
     rte_memzone_dump(stdout);
     rte_eal_init_ret = 0;