[dpdk-dev] [PATCH v4 08/17] eal/soc: extend and utilize devargs

Shreyansh Jain shreyansh.jain at nxp.com
Sat Oct 15 15:44:59 CEST 2016


From: Jan Viktorin <viktorin at rehivetech.com>

It is assumed that SoC Devices provided on command line are prefixed with
"soc:". This patch adds parse and attach support for such devices.

Signed-off-by: Jan Viktorin <viktorin at rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain at nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal at nxp.com>
---
 lib/librte_eal/common/eal_common_dev.c      | 27 +++++++++----
 lib/librte_eal/common/eal_common_devargs.c  | 17 ++++++++
 lib/librte_eal/common/eal_common_soc.c      | 61 ++++++++++++++++++++++++-----
 lib/librte_eal/common/include/rte_devargs.h |  8 ++++
 lib/librte_eal/common/include/rte_soc.h     | 24 ++++++++++++
 5 files changed, 120 insertions(+), 17 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 457d227..ebbcf47 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -107,17 +107,23 @@ rte_eal_dev_init(void)
 
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
-	struct rte_pci_addr addr;
+	struct rte_soc_addr soc_addr;
+	struct rte_pci_addr pci_addr;
 
 	if (name == NULL || devargs == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
 		return -EINVAL;
 	}
 
-	if (eal_parse_pci_DomBDF(name, &addr) == 0) {
-		if (rte_eal_pci_probe_one(&addr) < 0)
+	memset(&soc_addr, 0, sizeof(soc_addr));
+	if (rte_eal_parse_soc_spec(name, &soc_addr) == 0) {
+		if (rte_eal_soc_probe_one(&soc_addr) < 0) {
+			free(soc_addr.name);
+			goto err;
+		}
+	} else if (eal_parse_pci_DomBDF(name, &pci_addr) == 0) {
+		if (rte_eal_pci_probe_one(&pci_addr) < 0)
 			goto err;
-
 	} else {
 		if (rte_eal_vdev_init(name, devargs))
 			goto err;
@@ -132,15 +138,22 @@ err:
 
 int rte_eal_dev_detach(const char *name)
 {
-	struct rte_pci_addr addr;
+	struct rte_soc_addr soc_addr;
+	struct rte_pci_addr pci_addr;
 
 	if (name == NULL) {
 		RTE_LOG(ERR, EAL, "Invalid device provided.\n");
 		return -EINVAL;
 	}
 
-	if (eal_parse_pci_DomBDF(name, &addr) == 0) {
-		if (rte_eal_pci_detach(&addr) < 0)
+	memset(&soc_addr, 0, sizeof(soc_addr));
+	if (rte_eal_parse_soc_spec(name, &soc_addr) == 0) {
+		if (rte_eal_soc_detach(&soc_addr) < 0) {
+			free(soc_addr.name);
+			goto err;
+		}
+	} else if (eal_parse_pci_DomBDF(name, &pci_addr) == 0) {
+		if (rte_eal_pci_detach(&pci_addr) < 0)
 			goto err;
 	} else {
 		if (rte_eal_vdev_uninit(name))
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
index e403717..e1dae1a 100644
--- a/lib/librte_eal/common/eal_common_devargs.c
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -41,6 +41,7 @@
 #include <string.h>
 
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_devargs.h>
 #include "eal_private.h"
 
@@ -105,6 +106,14 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
 			goto fail;
 
 		break;
+
+	case RTE_DEVTYPE_WHITELISTED_SOC:
+	case RTE_DEVTYPE_BLACKLISTED_SOC:
+		/* try to parse soc device with prefix "soc:" */
+		if (rte_eal_parse_soc_spec(buf, &devargs->soc.addr) != 0)
+			goto fail;
+		break;
+
 	case RTE_DEVTYPE_VIRTUAL:
 		/* save driver name */
 		ret = snprintf(devargs->virt.drv_name,
@@ -166,6 +175,14 @@ rte_eal_devargs_dump(FILE *f)
 			       devargs->pci.addr.devid,
 			       devargs->pci.addr.function,
 			       devargs->args);
+		else if (devargs->type == RTE_DEVTYPE_WHITELISTED_SOC)
+			fprintf(f, "  SoC whitelist %s %s\n",
+			       devargs->soc.addr.name,
+			       devargs->soc.addr.fdt_path);
+		else if (devargs->type == RTE_DEVTYPE_BLACKLISTED_SOC)
+			fprintf(f, "  SoC blacklist %s %s\n",
+			       devargs->soc.addr.name,
+			       devargs->soc.addr.fdt_path);
 		else if (devargs->type == RTE_DEVTYPE_VIRTUAL)
 			fprintf(f, "  VIRTUAL %s %s\n",
 			       devargs->virt.drv_name,
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 256cef8..44f5559 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -37,6 +37,8 @@
 
 #include <rte_log.h>
 #include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_eal.h>
 #include <rte_soc.h>
 
 #include "eal_private.h"
@@ -70,6 +72,21 @@ rte_eal_soc_match_compat(struct rte_soc_driver *drv,
 	return 1;
 }
 
+static struct rte_devargs *soc_devargs_lookup(struct rte_soc_device *dev)
+{
+	struct rte_devargs *devargs;
+
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->type != RTE_DEVTYPE_BLACKLISTED_SOC &&
+			devargs->type != RTE_DEVTYPE_WHITELISTED_SOC)
+			continue;
+		if (!rte_eal_compare_soc_addr(&dev->addr, &devargs->soc.addr))
+			return devargs;
+	}
+
+	return NULL;
+}
+
 static int
 rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
 			     struct rte_soc_device *dev)
@@ -85,6 +102,18 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
 		return ret;
 	}
 
+	RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %d\n",
+			dev->addr.name, dev->device.numa_node);
+	RTE_LOG(DEBUG, EAL, "  probe driver %s\n", drv->driver.name);
+
+	/* no initialization when blacklisted, return without error */
+	if (dev->device.devargs != NULL
+		&& dev->device.devargs->type == RTE_DEVTYPE_BLACKLISTED_SOC) {
+		RTE_LOG(DEBUG, EAL,
+			"  device is blacklisted, skipping\n");
+		return ret;
+	}
+
 	dev->driver = drv;
 	RTE_VERIFY(drv->probe != NULL);
 	return drv->probe(drv, dev);
@@ -129,8 +158,8 @@ rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
 		return ret;
 	}
 
-	RTE_LOG(DEBUG, EAL, "SoC device %s\n",
-		dev->addr.name);
+	RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %i\n",
+			dev->addr.name, dev->device.numa_node);
 
 	RTE_LOG(DEBUG, EAL, "  remove driver: %s\n", drv->driver.name);
 
@@ -233,17 +262,29 @@ int
 rte_eal_soc_probe(void)
 {
 	struct rte_soc_device *dev = NULL;
+	struct rte_devargs *devargs = NULL;
 	int ret = 0;
+	int probe_all = 0;
+
+	if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_SOC) == 0)
+		probe_all = 1;
 
 	TAILQ_FOREACH(dev, &soc_device_list, next) {
-		ret = soc_probe_all_drivers(dev);
-		if (ret < 0) {
-			RTE_LOG(DEBUG, EAL, "Requested device %s"
-				 " cannot be used\n", dev->addr.name);
-			/* Failure for a particular device is logged and
-			 * ignored
-			 */
-		}
+
+		/* set devargs in SoC structure */
+		devargs = soc_devargs_lookup(dev);
+		if (devargs != NULL)
+			dev->device.devargs = devargs;
+
+		/* probe all or only whitelisted devices */
+		if (probe_all)
+			ret = soc_probe_all_drivers(dev);
+		else if (devargs != NULL &&
+			devargs->type == RTE_DEVTYPE_WHITELISTED_SOC)
+			ret = soc_probe_all_drivers(dev);
+		if (ret < 0)
+			rte_exit(EXIT_FAILURE, "Requested device %s "
+				 "cannot be used\n", dev->addr.name);
 	}
 
 	return ret;
diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h
index 88120a1..b5dd436 100644
--- a/lib/librte_eal/common/include/rte_devargs.h
+++ b/lib/librte_eal/common/include/rte_devargs.h
@@ -51,6 +51,7 @@ extern "C" {
 #include <stdio.h>
 #include <sys/queue.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 
 /**
  * Type of generic device
@@ -58,6 +59,8 @@ extern "C" {
 enum rte_devtype {
 	RTE_DEVTYPE_WHITELISTED_PCI,
 	RTE_DEVTYPE_BLACKLISTED_PCI,
+	RTE_DEVTYPE_WHITELISTED_SOC,
+	RTE_DEVTYPE_BLACKLISTED_SOC,
 	RTE_DEVTYPE_VIRTUAL,
 };
 
@@ -83,6 +86,11 @@ struct rte_devargs {
 			/** PCI location. */
 			struct rte_pci_addr addr;
 		} pci;
+		/** Used if type is RTE_DEVTYPE_*_SOC. */
+		struct {
+			/** SoC location. */
+			struct rte_soc_addr addr;
+		} soc;
 		/** Used if type is RTE_DEVTYPE_VIRTUAL. */
 		struct {
 			/** Driver name. */
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 030df6f..90cd6aa 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -164,6 +164,30 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 }
 
 /**
+ * Parse a specification of a soc device. The specification must differentiate
+ * a SoC device specification from the PCI bus and virtual devices. We assume
+ * a SoC specification starts with "soc:". The function allocates the name
+ * entry of the given addr.
+ *
+ * @return
+ *      -  0 on success
+ *      -  1 when not a SoC spec
+ *      - -1 on failure
+ */
+static inline int
+rte_eal_parse_soc_spec(const char *spec, struct rte_soc_addr *addr)
+{
+	if (strstr(spec, "soc:") == spec) {
+		addr->name = strdup(spec + 4);
+		if (addr->name == NULL)
+			return -1;
+		return 0;
+	}
+
+	return 1;
+}
+
+/**
  * Default function for matching the Soc driver with device. Each driver can
  * either use this function or define their own soc matching function.
  * This function relies on the compatible string extracted from sysfs. But,
-- 
2.7.4



More information about the dev mailing list