[dpdk-dev] [PATCH v1 12/28] eal/soc: extend and utilize devargs
Jan Viktorin
viktorin at rehivetech.com
Fri May 6 15:47:54 CEST 2016
This code is not tested. We assume to white/blacklist SoC devices by giving
the prefix "soc:" on the command line.
Signed-off-by: Jan Viktorin <viktorin at rehivetech.com>
---
lib/librte_eal/common/eal_common_dev.c | 31 ++++++++++++++++++-----
lib/librte_eal/common/eal_common_devargs.c | 7 ++++++
lib/librte_eal/common/eal_common_soc.c | 39 ++++++++++++++++++++++++++++-
lib/librte_eal/common/include/rte_devargs.h | 8 ++++++
lib/librte_eal/common/include/rte_soc.h | 28 +++++++++++++++++++++
5 files changed, 106 insertions(+), 7 deletions(-)
diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index d2763b0..4182a55 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -154,11 +154,19 @@ rte_eal_vdev_uninit(const char *name)
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;
int ret = -1;
- 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)
+ goto err_soc;
+
+ free(soc_addr.name);
+
+ } else if (eal_parse_pci_DomBDF(name, &pci_addr) == 0) {
+ if (rte_eal_pci_probe_one(&pci_addr) < 0)
goto err;
} else {
@@ -168,6 +176,8 @@ int rte_eal_dev_attach(const char *name, const char *devargs)
return 0;
+err_soc:
+ free(soc_addr.name);
err:
RTE_LOG(ERR, EAL, "Driver, cannot attach the device\n");
return ret;
@@ -175,10 +185,17 @@ 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 (rte_eal_parse_soc_spec(name, &soc_addr) == 0) {
+ if (rte_eal_soc_detach(&soc_addr) < 0)
+ goto soc_err;
+
+ free(soc_addr.name);
- if (eal_parse_pci_DomBDF(name, &addr) == 0) {
- if (rte_eal_pci_detach(&addr) < 0)
+ } 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))
@@ -186,6 +203,8 @@ int rte_eal_dev_detach(const char *name)
}
return 0;
+soc_err:
+ free(soc_addr.name);
err:
RTE_LOG(ERR, EAL, "Driver, cannot detach the device\n");
return -1;
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
index 2bfe54a..5f6bcff 100644
--- a/lib/librte_eal/common/eal_common_devargs.c
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -105,6 +105,13 @@ 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:
+ /* save target device name */
+ devargs->soc.addr.name = strdup(buf); /* FIXME: memory leak */
+ break;
+
case RTE_DEVTYPE_VIRTUAL:
/* save driver name */
ret = snprintf(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 d8f0c00..3b885e8 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -37,6 +37,7 @@
#include <rte_log.h>
#include <rte_common.h>
+#include <rte_devargs.h>
#include <rte_soc.h>
#include "eal_private.h"
@@ -60,6 +61,21 @@ const char *soc_get_sysfs_path(void)
return path;
}
+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 soc_id_match(const struct rte_soc_id *drv_id,
const struct rte_soc_id *dev_id)
{
@@ -96,6 +112,13 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *dr,
dev->addr.name);
RTE_LOG(DEBUG, EAL, " probe driver %s\n", dr->name);
+ if (dev->devargs != NULL
+ && dev->devargs->type == RTE_DEVTYPE_BLACKLISTED_SOC) {
+ RTE_LOG(DEBUG, EAL,
+ " device is blacklisted, skipping\n");
+ return 1;
+ }
+
dev->driver = dr;
RTE_VERIFY(dr->devinit != NULL);
return dr->devinit(dr, dev);
@@ -244,12 +267,26 @@ int
rte_eal_soc_probe(void)
{
struct rte_soc_device *dev = NULL;
+ struct rte_devargs *devargs;
int probe_all = 0;
int ret = 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->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);
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 4117ffb..00fd0a6 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -72,6 +72,8 @@ struct rte_soc_addr {
char *fdt_path; /**< path to the associated node in FDT */
};
+struct rte_devargs;
+
/**
* A structure describing a SoC device.
*/
@@ -80,6 +82,7 @@ struct rte_soc_device {
struct rte_soc_addr addr; /**< SoC device Location */
struct rte_soc_id *id; /**< SoC device ID list */
struct rte_soc_driver *driver; /**< Associated driver */
+ struct rte_devargs *devargs; /**< Device user arguments */
};
struct rte_soc_driver;
@@ -141,6 +144,31 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
return strcmp(a0->name, a1->name);
}
+
+/**
+ * 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;
+}
+
/**
* Scan for new SoC devices.
*/
--
2.8.0
More information about the dev
mailing list