[dpdk-dev] [PATCH v2 8/9] pci: implement blacklist using a hook

David Marchand david.marchand at 6wind.com
Fri Jan 29 15:49:12 CET 2016


The idea is to prepare a generic hook system for all bus, but I am still
unsure if this approach will be the right one, hence, keeping this as
private for now.

Here, blacklisting policy is removed from pci scan code, making it possible
to override it later by the application (once the api is judged generic and
good enough).

With this, blacklist evaluation moves to rte_eal_pci_probe() only.
This way, rte_eal_pci_probe_one() (used by hotplug when attaching) now
accepts to probe devices that were blacklisted initially.

A new debug trace is added when skipping a device not part of a given
whitelist.

Signed-off-by: David Marchand <david.marchand at 6wind.com>
---
 lib/librte_eal/common/eal_common_pci.c | 101 +++++++++++++++++++++++++--------
 1 file changed, 77 insertions(+), 24 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 082eab8..4a0ec73 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -87,6 +87,62 @@ struct pci_driver_list pci_driver_list =
 struct pci_device_list pci_device_list =
 	TAILQ_HEAD_INITIALIZER(pci_device_list);
 
+enum rte_eal_pci_hook {
+	RTE_EAL_PCI_SCAN,
+};
+
+enum rte_eal_pci_hook_return {
+	RTE_EAL_PCI_HOOK_OK,
+	RTE_EAL_PCI_HOOK_ERROR,
+	RTE_EAL_PCI_HOOK_SKIP,
+};
+
+typedef int (rte_eal_pci_hook_t)(enum rte_eal_pci_hook,
+				 struct rte_pci_driver *,
+				 struct rte_pci_device *);
+
+static int
+blacklist_pci_hook(enum rte_eal_pci_hook h,
+		   struct rte_pci_driver *dr __rte_unused,
+		   struct rte_pci_device *dev)
+{
+	int ret;
+
+	switch (h) {
+	case RTE_EAL_PCI_SCAN:
+	{
+		int whitelist =
+			rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI);
+		int blacklist =
+			rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_PCI);
+
+		/*
+		 * We want to probe this device when:
+		 * - there is no whitelist/blacklist,
+		 * - there is a whitelist, and device is part of it,
+		 * - there is a blacklist, and device is not part of it.
+		 */
+		if (whitelist && !dev->devargs) {
+			RTE_LOG(DEBUG, EAL, "  Device is not whitelisted, not initializing\n");
+			ret = RTE_EAL_PCI_HOOK_SKIP;
+		} else if (blacklist && dev->devargs) {
+			RTE_LOG(DEBUG, EAL, "  Device is blacklisted, not initializing\n");
+			ret = RTE_EAL_PCI_HOOK_SKIP;
+		} else
+			ret = RTE_EAL_PCI_HOOK_OK;
+		break;
+	}
+	default:
+		/* nothing to do here, just say ok */
+		ret = RTE_EAL_PCI_HOOK_OK;
+		break;
+	}
+
+	return ret;
+}
+
+static rte_eal_pci_hook_t *pci_hook = &blacklist_pci_hook;
+
 static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
 {
 	struct rte_devargs *devargs;
@@ -209,22 +265,10 @@ static int
 pci_probe_device(struct rte_pci_driver *dr, struct rte_pci_device *dev)
 {
 	int ret;
-	struct rte_pci_addr *loc = &dev->addr;
-
-	RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
-		loc->domain, loc->bus, loc->devid, loc->function,
-		dev->numa_node);
 
 	RTE_LOG(DEBUG, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
 		dev->id.device_id, dr->name);
 
-	/* no initialization when blacklisted, return without error */
-	if (dev->devargs != NULL &&
-		dev->devargs->type == RTE_DEVTYPE_BLACKLISTED_PCI) {
-		RTE_LOG(DEBUG, EAL, "  Device is blacklisted, not initializing\n");
-		return 1;
-	}
-
 	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
 #ifdef RTE_PCI_CONFIG
 		/*
@@ -310,6 +354,11 @@ rte_eal_pci_probe_one(const struct rte_pci_addr *addr)
 	if (!dev)
 		goto err_return;
 
+	RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+		dev->addr.domain, dev->addr.bus,
+		dev->addr.devid, dev->addr.function,
+		dev->numa_node);
+
 	dr = pci_find_driver(dev);
 	if (!dr)
 		goto err_return;
@@ -369,27 +418,31 @@ rte_eal_pci_probe(void)
 	struct rte_pci_device *dev;
 	struct rte_pci_driver *dr;
 	struct rte_devargs *devargs;
-	int probe_all = 0;
-
-	if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) == 0)
-		probe_all = 1;
+	int ret;
 
 	TAILQ_FOREACH(dev, &pci_device_list, next) {
 
-		/* no driver available */
-		dr = pci_find_driver(dev);
-		if (!dr)
-			continue;
+		RTE_LOG(DEBUG, EAL,
+			"PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+			dev->addr.domain, dev->addr.bus,
+			dev->addr.devid, dev->addr.function,
+			dev->numa_node);
 
 		/* set devargs in PCI structure */
 		devargs = pci_devargs_lookup(dev);
 		if (devargs != NULL)
 			dev->devargs = devargs;
 
-		/* skip if not probing all and device is not whitelisted */
-		if (!probe_all &&
-		    (devargs == NULL ||
-		     devargs->type != RTE_DEVTYPE_WHITELISTED_PCI))
+		ret = pci_hook(RTE_EAL_PCI_SCAN, NULL, dev);
+		if (ret != RTE_EAL_PCI_HOOK_OK) {
+			RTE_LOG(DEBUG, EAL, "  scan hook refused dev, err=%d\n",
+				ret);
+			continue;
+		}
+
+		/* no driver available */
+		dr = pci_find_driver(dev);
+		if (!dr)
 			continue;
 
 		if (pci_probe_device(dr, dev) < 0)
-- 
1.9.1



More information about the dev mailing list