[dpdk-dev,v2,07/14] eal/soc: extend and utilize devargs

Message ID 1472641235-23626-8-git-send-email-shreyansh.jain@nxp.com (mailing list archive)
State Superseded, archived
Headers

Commit Message

Shreyansh Jain Aug. 31, 2016, 11 a.m. UTC
  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@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@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      | 55 ++++++++++++++++++++++++++---
 lib/librte_eal/common/include/rte_devargs.h |  8 +++++
 lib/librte_eal/common/include/rte_soc.h     | 24 +++++++++++++
 5 files changed, 119 insertions(+), 12 deletions(-)
  

Patch

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index d1f0ad8..fbc4443 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -106,17 +106,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;
@@ -131,15 +137,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 4797dd9..efa722d 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"
@@ -47,6 +49,21 @@  struct soc_driver_list soc_driver_list =
 struct soc_device_list soc_device_list =
 	TAILQ_HEAD_INITIALIZER(soc_device_list);
 
+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)
@@ -60,6 +77,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->devinit != NULL);
 	return drv->devinit(drv, dev);
@@ -104,8 +133,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);
 
@@ -218,13 +247,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);
+
+		/* 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);
+			rte_exit(EXIT_FAILURE, "Requested device %s "
+				 "cannot be used\n", dev->addr.name);
 	}
 
 	return 0;
diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h
index 53c59f5..757320e 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,
 };
 
@@ -82,6 +85,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 cc17829..c45b37e 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -158,6 +158,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;
+}
+
+/**
  * Probe SoC devices for registered drivers.
  */
 int rte_eal_soc_probe(void);