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 | 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(-) 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 bb87a67..e9d413a 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" @@ -71,6 +73,21 @@ rte_eal_soc_match(struct rte_soc_driver *drv, struct rte_soc_device *dev) } +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) @@ -84,6 +101,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); @@ -128,8 +157,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); @@ -242,13 +271,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 bfb49a2..0bbef7d 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; +} + +/** * 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