dpdk plugin: blacklist PCI devices by type 33/16533/4
authorDave Barach <dave@barachs.net>
Tue, 18 Dec 2018 21:06:36 +0000 (16:06 -0500)
committerDamjan Marion <dmarion@me.com>
Wed, 19 Dec 2018 07:24:56 +0000 (07:24 +0000)
Change-Id: I89695c1ad47131ed830f35c677937ce12025a40d
Signed-off-by: Dave Barach <dave@barachs.net>
src/plugins/dpdk/device/dpdk.h
src/plugins/dpdk/device/init.c
src/vpp/conf/startup.conf

index 4c45e87..a1e07b4 100644 (file)
@@ -377,6 +377,9 @@ typedef struct
   dpdk_device_config_t *dev_confs;
   uword *device_config_index_by_pci_addr;
 
+  /* devices blacklist by pci vendor_id, device_id */
+  u32 *blacklist_by_pci_vendor_and_device;
+
 } dpdk_config_main_t;
 
 extern dpdk_config_main_t dpdk_config_main;
index 9a78ac6..c0a927a 100644 (file)
@@ -828,6 +828,7 @@ dpdk_bind_devices_to_uio (dpdk_config_main_t * conf)
   int num_whitelisted = vec_len (conf->dev_confs);
   vlib_pci_device_info_t *d = 0;
   vlib_pci_addr_t *addr = 0, *addrs;
+  int i;
 
   addrs = vlib_pci_get_all_dev_addrs ();
   /* *INDENT-OFF* */
@@ -856,11 +857,41 @@ dpdk_bind_devices_to_uio (dpdk_config_main_t * conf)
        uword * p = hash_get (conf->device_config_index_by_pci_addr, addr->as_u32);
 
        if (!p)
-         continue;
+          {
+          skipped:
+            continue;
+          }
 
        devconf = pool_elt_at_index (conf->dev_confs, p[0]);
       }
 
+    /* Enforce Device blacklist by vendor and device */
+    for (i = 0; i < vec_len (conf->blacklist_by_pci_vendor_and_device); i++)
+      {
+        u16 vendor, device;
+        vendor = (u16)(conf->blacklist_by_pci_vendor_and_device[i] >> 16);
+        device = (u16)(conf->blacklist_by_pci_vendor_and_device[i] & 0xFFFF);
+        if (d->vendor_id == vendor && d->device_id == device)
+          {
+            /*
+             * Expected case: device isn't whitelisted,
+             * so blacklist it...
+             */
+            if (devconf == 0)
+              {
+                /* Device is blacklisted */
+                pool_get (conf->dev_confs, devconf);
+                hash_set (conf->device_config_index_by_pci_addr, addr->as_u32,
+                          devconf - conf->dev_confs);
+                devconf->pci_addr.as_u32 = addr->as_u32;
+                devconf->is_blacklisted = 1;
+                goto skipped;
+              }
+            else /* explicitly whitelisted, ignore the device blacklist  */
+              break;
+          }
+      }
+
     /* virtio */
     if (d->vendor_id == 0x1af4 &&
             (d->device_id == VIRTIO_PCI_LEGACY_DEVICEID_NET ||
@@ -1095,6 +1126,7 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
   u8 file_prefix = 0;
   u8 *socket_mem = 0;
   u8 *huge_dir_path = 0;
+  u32 vendor, device;
 
   huge_dir_path =
     format (0, "%s/hugepages%c", vlib_unix_get_runtime_dir (), 0);
@@ -1171,6 +1203,17 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
          tmp = format (0, "--no-pci%c", 0);
          vec_add1 (conf->eal_init_args, tmp);
        }
+      else if (unformat (input, "blacklist %x:%x", &vendor, &device))
+       {
+         u32 blacklist_entry;
+         if (vendor > 0xFFFF)
+           return clib_error_return (0, "blacklist PCI vendor out of range");
+         if (device > 0xFFFF)
+           return clib_error_return (0, "blacklist PCI device out of range");
+         blacklist_entry = (vendor << 16) | (device & 0xffff);
+         vec_add1 (conf->blacklist_by_pci_vendor_and_device,
+                   blacklist_entry);
+       }
 
 #define _(a)                                    \
       else if (unformat(input, #a))             \
index 7532f50..7b4f69d 100644 (file)
@@ -94,6 +94,10 @@ cpu {
        ## Whitelist specific interface by specifying PCI address
        # dev 0000:02:00.0
 
+       ## Blacklist specific device type by specifying PCI vendor:device
+        ## Whitelist entries take precedence
+       # blacklist 8086:10fb
+
        ## Set interface name
        # dev 0000:02:00.1 {
        #       name eth0
@@ -140,7 +144,7 @@ cpu {
 
 # plugins {
        ## Adjusting the plugin path depending on where the VPP plugins are
-       #       path /home/bms/vpp/build-root/install-vpp-native/vpp/lib/vpp_plugins
+       #       path /ws/vpp/build-root/install-vpp-native/vpp/lib/vpp_plugins
 
        ## Disable all plugins by default and then selectively enable specific plugins
        # plugin default { disable }
@@ -151,6 +155,3 @@ cpu {
        # plugin dpdk_plugin.so { disable }
        # plugin acl_plugin.so { disable }
 # }
-
-       ## Alternate syntax to choose plugin path
-       # plugin_path /home/bms/vpp/build-root/install-vpp-native/vpp/lib/vpp_plugins