From: "Nicolás Pernas Maradei" <nicolas.pernas.maradei@emutex.com>
To: dev@dpdk.org
Cc: "Nicolás Pernas Maradei" <nico@emutex.com>
Subject: [dpdk-dev] [PATCH] eal: allow virtual devices to be white/black listed
Date: Sun, 16 Nov 2014 21:26:55 +0000 [thread overview]
Message-ID: <1416173215-27533-1-git-send-email-nicolas.pernas.maradei@emutex.com> (raw)
From: Nicolás Pernas Maradei <nico@emutex.com>
Virtual and physical devices are now treated the same in terms of
white/black listing. Virtual devices can be defined using --vdev as
before and also whitelisted (using -w vdev_name) or blacklisted (using -b
vdev_name). This allows the user to have only a virtual device (port) in
use.
Signed-off-by: Nicolás Pernas Maradei <nico@emutex.com>
---
app/test-pmd/cmdline.c | 5 +-
app/test/commands.c | 4 +-
app/test/test_devargs.c | 69 +++++-----
app/test/test_pci.c | 3 +-
lib/librte_eal/bsdapp/eal/eal.c | 8 +-
lib/librte_eal/bsdapp/eal/eal_pci.c | 2 +-
lib/librte_eal/common/eal_common_dev.c | 24 ++--
lib/librte_eal/common/eal_common_devargs.c | 196 ++++++++++++++++++++--------
lib/librte_eal/common/eal_common_options.c | 11 +-
lib/librte_eal/common/eal_common_pci.c | 11 +-
lib/librte_eal/common/include/rte_devargs.h | 124 +++++++++++++-----
lib/librte_eal/linuxapp/eal/eal.c | 8 +-
lib/librte_eal/linuxapp/eal/eal_pci.c | 2 +-
13 files changed, 319 insertions(+), 148 deletions(-)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 4c3fc76..f6ba4fe 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -6844,6 +6844,8 @@ static void cmd_dump_parsed(void *parsed_result,
rte_mempool_list_dump(stdout);
else if (!strcmp(res->dump, "dump_devargs"))
rte_eal_devargs_dump(stdout);
+ else if (!strcmp(res->dump, "dump_vdevargs"))
+ rte_eal_vdevargs_dump(stdout);
}
cmdline_parse_token_string_t cmd_dump_dump =
@@ -6854,7 +6856,8 @@ cmdline_parse_token_string_t cmd_dump_dump =
"dump_struct_sizes#"
"dump_ring#"
"dump_mempool#"
- "dump_devargs");
+ "dump_devargs#"
+ "dump_vdevargs");
cmdline_parse_inst_t cmd_dump = {
.f = cmd_dump_parsed, /* function to call */
diff --git a/app/test/commands.c b/app/test/commands.c
index 92a17ed..6799d63 100644
--- a/app/test/commands.c
+++ b/app/test/commands.c
@@ -161,13 +161,15 @@ static void cmd_dump_parsed(void *parsed_result,
rte_mempool_list_dump(stdout);
else if (!strcmp(res->dump, "dump_devargs"))
rte_eal_devargs_dump(stdout);
+ else if (!strcmp(res->dump, "dump_vdevargs"))
+ rte_eal_vdevargs_dump(stdout);
}
cmdline_parse_token_string_t cmd_dump_dump =
TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
"dump_physmem#dump_memzone#dump_log_history#"
"dump_struct_sizes#dump_ring#dump_mempool#"
- "dump_devargs");
+ "dump_devargs#dump_vdevargs");
cmdline_parse_inst_t cmd_dump = {
.f = cmd_dump_parsed, /* function to call */
diff --git a/app/test/test_devargs.c b/app/test/test_devargs.c
index f0acf8e..8fb93df 100644
--- a/app/test/test_devargs.c
+++ b/app/test/test_devargs.c
@@ -52,52 +52,60 @@ static void free_devargs_list(void)
}
}
+/* clear vdevargs list that was modified by the test */
+static void free_vdevargs_list(void)
+{
+ struct rte_vdevargs *vdevargs;
+
+ while (!TAILQ_EMPTY(&vdevargs_list)) {
+ vdevargs = TAILQ_FIRST(&vdevargs_list);
+ TAILQ_REMOVE(&vdevargs_list, vdevargs, next);
+ free(vdevargs);
+ }
+}
+
static int
test_devargs(void)
{
struct rte_devargs_list save_devargs_list;
+ struct rte_vdevargs_list save_vdevargs_list;
struct rte_devargs *devargs;
+ struct rte_vdevargs *vdevargs;
/* save the real devargs_list, it is restored at the end of the test */
save_devargs_list = devargs_list;
+ save_vdevargs_list = vdevargs_list;
TAILQ_INIT(&devargs_list);
+ TAILQ_INIT(&vdevargs_list);
/* test valid cases */
- if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "08:00.1") < 0)
- goto fail;
- if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "0000:5:00.0") < 0)
- goto fail;
- if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI, "04:00.0,arg=val") < 0)
- goto fail;
- if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI, "0000:01:00.1") < 0)
+ if (rte_eal_devargs_add(RTE_DEV_WHITELISTED, "08:00.1") < 0)
goto fail;
- if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) != 2)
+ if (rte_eal_devargs_add(RTE_DEV_WHITELISTED, "0000:5:00.0") < 0)
goto fail;
- if (rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_PCI) != 2)
+ if (rte_eal_devargs_add(RTE_DEV_BLACKLISTED, "04:00.0") < 0)
goto fail;
- if (rte_eal_devargs_type_count(RTE_DEVTYPE_VIRTUAL) != 0)
+ if (rte_eal_devargs_add(RTE_DEV_BLACKLISTED, "0000:01:00.1") < 0)
goto fail;
- if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "eth_ring0") < 0)
+ if (rte_eal_devargs_type_count(RTE_DEV_WHITELISTED) != 2)
goto fail;
- if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "eth_ring1,key=val,k2=val2") < 0)
- goto fail;
- if (rte_eal_devargs_type_count(RTE_DEVTYPE_VIRTUAL) != 2)
+ if (rte_eal_devargs_type_count(RTE_DEV_BLACKLISTED) != 2)
goto fail;
free_devargs_list();
/* check virtual device with argument parsing */
- if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "eth_ring1,k1=val,k2=val2") < 0)
+ if (rte_eal_vdevargs_add("eth_ring1,k1=val,k2=val2") < 0)
goto fail;
- devargs = TAILQ_FIRST(&devargs_list);
- if (strncmp(devargs->virtual.drv_name, "eth_ring1",
- sizeof(devargs->virtual.drv_name) != 0))
+ vdevargs = TAILQ_FIRST(&vdevargs_list);
+ if (strncmp(vdevargs->drv_name, "eth_ring1",
+ sizeof(vdevargs->drv_name) != 0))
goto fail;
- if (strncmp(devargs->args, "k1=val,k2=val2", sizeof(devargs->args) != 0))
+ if (strncmp(vdevargs->args, "k1=val,k2=val2", sizeof(vdevargs->args) != 0))
goto fail;
- free_devargs_list();
+ free_vdevargs_list();
/* check PCI device with empty argument parsing */
- if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "04:00.1") < 0)
+ if (rte_eal_devargs_add(RTE_DEV_WHITELISTED, "04:00.1") < 0)
goto fail;
devargs = TAILQ_FIRST(&devargs_list);
if (devargs->pci.addr.domain != 0 ||
@@ -105,28 +113,25 @@ test_devargs(void)
devargs->pci.addr.devid != 0 ||
devargs->pci.addr.function != 1)
goto fail;
- if (strncmp(devargs->args, "", sizeof(devargs->args) != 0))
- goto fail;
free_devargs_list();
- /* test error case: bad PCI address */
- if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "08:1") == 0)
+ /* Check that virtual devices can be also whitelisted */
+ if (rte_eal_devargs_add(RTE_DEV_WHITELISTED, "eth_pcap0") < 0)
goto fail;
- if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "00.1") == 0)
- goto fail;
- if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "foo") == 0)
- goto fail;
- if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, ",") == 0)
- goto fail;
- if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "000f:0:0") == 0)
+ devargs = TAILQ_FIRST(&devargs_list);
+ if (strncmp(devargs->virtual.drv_name, "eth_pcap0",
+ sizeof(devargs->virtual.drv_name)) != 0)
goto fail;
devargs_list = save_devargs_list;
+ vdevargs_list = save_vdevargs_list;
return 0;
fail:
free_devargs_list();
+ free_vdevargs_list();
devargs_list = save_devargs_list;
+ vdevargs_list = save_vdevargs_list;
return -1;
}
diff --git a/app/test/test_pci.c b/app/test/test_pci.c
index 4f0169a..308abb9 100644
--- a/app/test/test_pci.c
+++ b/app/test/test_pci.c
@@ -126,8 +126,7 @@ blacklist_all_devices(void)
snprintf(pci_addr_str, sizeof(pci_addr_str), PCI_PRI_FMT,
dev->addr.domain, dev->addr.bus, dev->addr.devid,
dev->addr.function);
- if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI,
- pci_addr_str) < 0) {
+ if (rte_eal_devargs_add(RTE_DEV_BLACKLISTED, pci_addr_str) < 0) {
printf("Error: cannot blacklist <%s>", pci_addr_str);
break;
}
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index ca99cb9..c59c203 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -429,14 +429,18 @@ eal_parse_args(int argc, char **argv)
return -1;
}
- if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) != 0 &&
- rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_PCI) != 0) {
+ if (rte_eal_devargs_type_count(RTE_DEV_WHITELISTED) != 0 &&
+ rte_eal_devargs_type_count(RTE_DEV_BLACKLISTED) != 0) {
RTE_LOG(ERR, EAL, "Error: blacklist [-b] and whitelist "
"[-w] options cannot be used at the same time\n");
eal_usage(prgname);
return -1;
}
+ /* Check if all white/black listed virtual devices were also defined */
+ if (rte_eal_check_vdevs_definition() < 0)
+ return -1;
+
if (optind >= 0)
argv[optind-1] = prgname;
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 74ecce7..df179eb 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -462,7 +462,7 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *d
/* no initialization when blacklisted, return without error */
if (dev->devargs != NULL &&
- dev->devargs->type == RTE_DEVTYPE_BLACKLISTED_PCI) {
+ dev->devargs->select == RTE_DEV_BLACKLISTED) {
RTE_LOG(DEBUG, EAL, " Device is blacklisted, not initializing\n");
return 0;
diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index eae5656..5181ba8 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -64,8 +64,11 @@ rte_eal_driver_unregister(struct rte_driver *driver)
int
rte_eal_dev_init(void)
{
- struct rte_devargs *devargs;
+ struct rte_vdevargs *vdevargs;
struct rte_driver *driver;
+ int whitelisted_devs;
+
+ whitelisted_devs = rte_eal_devargs_type_count(RTE_DEV_WHITELISTED);
/*
* Note that the dev_driver_list is populated here
@@ -74,9 +77,13 @@ rte_eal_dev_init(void)
*/
/* call the init function for each virtual device */
- TAILQ_FOREACH(devargs, &devargs_list, next) {
+ TAILQ_FOREACH(vdevargs, &vdevargs_list, next) {
+
+ if (rte_eal_vdevargs_is(vdevargs, RTE_DEV_BLACKLISTED))
+ continue;
- if (devargs->type != RTE_DEVTYPE_VIRTUAL)
+ if (whitelisted_devs
+ && !rte_eal_vdevargs_is(vdevargs, RTE_DEV_WHITELISTED))
continue;
TAILQ_FOREACH(driver, &dev_driver_list, next) {
@@ -84,18 +91,15 @@ rte_eal_dev_init(void)
continue;
/* search a driver prefix in virtual device name */
- if (!strncmp(driver->name, devargs->virtual.drv_name,
+ if (!strncmp(driver->name, vdevargs->drv_name,
strlen(driver->name))) {
- driver->init(devargs->virtual.drv_name,
- devargs->args);
+ driver->init(vdevargs->drv_name, vdevargs->args);
break;
}
}
- if (driver == NULL) {
- rte_panic("no driver found for %s\n",
- devargs->virtual.drv_name);
- }
+ if (driver == NULL)
+ rte_panic("no driver found for %s\n", vdevargs->drv_name);
}
/* Once the vdevs are initalized, start calling all the pdev drivers */
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
index 4c7d11a..4171654 100644
--- a/lib/librte_eal/common/eal_common_devargs.c
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -43,14 +43,15 @@
/** Global list of user devices */
struct rte_devargs_list devargs_list =
TAILQ_HEAD_INITIALIZER(devargs_list);
+struct rte_vdevargs_list vdevargs_list =
+ TAILQ_HEAD_INITIALIZER(vdevargs_list);
/* store a whitelist parameter for later parsing */
int
-rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
+rte_eal_devargs_add(enum rte_devselect devselect, const char *devargs_str)
{
struct rte_devargs *devargs;
- char buf[RTE_DEVARGS_LEN];
- char *sep;
+ char buf[RTE_VDEV_NAME_LEN];
int ret;
ret = snprintf(buf, sizeof(buf), "%s", devargs_str);
@@ -67,86 +68,177 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
return -1;
}
memset(devargs, 0, sizeof(*devargs));
- devargs->type = devtype;
+ devargs->select = devselect;
+
+ /* try to parse short PCI identifier */
+ if (eal_parse_pci_BDF(buf, &devargs->pci.addr) == 0)
+ goto done;
+
+ /* try to parse long PCI identifier */
+ if (eal_parse_pci_DomBDF(buf, &devargs->pci.addr) == 0)
+ goto done;
+
+ /* If device ID is not a valid PCI ID assume is a virtual driver name */
+ devargs->is_vdev = 1;
+ ret = snprintf(devargs->virtual.drv_name, sizeof(devargs->virtual.drv_name), "%s", buf);
+ if (ret < 0 || ret >= (int)sizeof(devargs->virtual.drv_name)) {
+ RTE_LOG(ERR, EAL, "driver name too large: <%s>\n", buf);
+ free(devargs);
+ return -1;
+ }
+
+done:
+ TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
+ return 0;
+}
+
+int
+rte_eal_vdevargs_add(const char *vdevargs_str)
+{
+ struct rte_vdevargs *vdevargs;
+ char buf[RTE_VDEVARGS_LEN];
+ char *sep;
+ int ret;
+
+ ret = snprintf(buf, sizeof(buf), "%s", vdevargs_str);
+ if (ret < 0 || ret >= (int)sizeof(buf)) {
+ RTE_LOG(ERR, EAL, "user device args too large: <%s>\n", vdevargs_str);
+ return -1;
+ }
+
+ /* use malloc instead of rte_malloc as it's called early at init */
+ vdevargs = malloc(sizeof(*vdevargs));
+ if (vdevargs == NULL) {
+ RTE_LOG(ERR, EAL, "cannot allocate vdevargs\n");
+ return -1;
+ }
+ memset(vdevargs, 0, sizeof(*vdevargs));
/* set the first ',' to '\0' to split name and arguments */
sep = strchr(buf, ',');
if (sep != NULL) {
sep[0] = '\0';
- snprintf(devargs->args, sizeof(devargs->args), "%s", sep + 1);
+ snprintf(vdevargs->args, sizeof(vdevargs->args), "%s", sep + 1);
}
- switch (devargs->type) {
- case RTE_DEVTYPE_WHITELISTED_PCI:
- case RTE_DEVTYPE_BLACKLISTED_PCI:
- /* try to parse pci identifier */
- if (eal_parse_pci_BDF(buf, &devargs->pci.addr) != 0 &&
- eal_parse_pci_DomBDF(buf, &devargs->pci.addr) != 0) {
- RTE_LOG(ERR, EAL,
- "invalid PCI identifier <%s>\n", buf);
- free(devargs);
- return -1;
- }
- break;
- case RTE_DEVTYPE_VIRTUAL:
- /* save driver name */
- ret = snprintf(devargs->virtual.drv_name,
- sizeof(devargs->virtual.drv_name), "%s", buf);
- if (ret < 0 || ret >= (int)sizeof(devargs->virtual.drv_name)) {
- RTE_LOG(ERR, EAL,
- "driver name too large: <%s>\n", buf);
- free(devargs);
- return -1;
- }
- break;
+ /* save driver name */
+ ret = snprintf(vdevargs->drv_name, sizeof(vdevargs->drv_name), "%s", buf);
+ if (ret < 0 || ret >= (int)sizeof(vdevargs->drv_name)) {
+ RTE_LOG(ERR, EAL, "driver name too large: <%s>\n", buf);
+ free(vdevargs);
+ return -1;
}
- TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
+ TAILQ_INSERT_TAIL(&vdevargs_list, vdevargs, next);
return 0;
}
/* count the number of devices of a specified type */
unsigned int
-rte_eal_devargs_type_count(enum rte_devtype devtype)
+rte_eal_devargs_type_count(enum rte_devselect devselect)
{
struct rte_devargs *devargs;
unsigned int count = 0;
TAILQ_FOREACH(devargs, &devargs_list, next) {
- if (devargs->type != devtype)
+ if (devargs->select != devselect)
continue;
count++;
}
return count;
}
-/* dump the user devices on the console */
+int
+rte_eal_vdevargs_is(struct rte_vdevargs *vdevargs, enum rte_devselect devselect)
+{
+ struct rte_devargs *devargs;
+
+ TAILQ_FOREACH(devargs, &devargs_list, next) {
+ if (!devargs->is_vdev)
+ continue;
+
+ if (!strncmp(vdevargs->drv_name, devargs->virtual.drv_name,
+ sizeof(vdevargs->drv_name)))
+ return !!(devargs->select == devselect);
+ }
+ return 0;
+}
+
+/* dump the user selected devices on the console */
void
rte_eal_devargs_dump(FILE *f)
{
struct rte_devargs *devargs;
- fprintf(f, "User device white list:\n");
+ fprintf(f, "User selected devices list:\n");
TAILQ_FOREACH(devargs, &devargs_list, next) {
- if (devargs->type == RTE_DEVTYPE_WHITELISTED_PCI)
- fprintf(f, " PCI whitelist " PCI_PRI_FMT " %s\n",
- devargs->pci.addr.domain,
- devargs->pci.addr.bus,
- devargs->pci.addr.devid,
- devargs->pci.addr.function,
- devargs->args);
- else if (devargs->type == RTE_DEVTYPE_BLACKLISTED_PCI)
- fprintf(f, " PCI blacklist " PCI_PRI_FMT " %s\n",
- devargs->pci.addr.domain,
- devargs->pci.addr.bus,
- devargs->pci.addr.devid,
- devargs->pci.addr.function,
- devargs->args);
- else if (devargs->type == RTE_DEVTYPE_VIRTUAL)
- fprintf(f, " VIRTUAL %s %s\n",
- devargs->virtual.drv_name,
- devargs->args);
+ if (devargs->select == RTE_DEV_WHITELISTED)
+ fprintf(f, " PCI whitelist ");
+ else if (devargs->select == RTE_DEV_BLACKLISTED)
+ fprintf(f, " PCI blacklist ");
+ else
+ fprintf(f, " UNKNOWN ");
+
+ if (devargs->is_vdev)
+ fprintf(f, "(VIRTUAL) %s %s\n", devargs->virtual.vdev->drv_name,
+ devargs->virtual.vdev->args);
else
- fprintf(f, " UNKNOWN %s\n", devargs->args);
+ fprintf(f, PCI_PRI_FMT "\n",
+ devargs->pci.addr.domain,
+ devargs->pci.addr.bus,
+ devargs->pci.addr.devid,
+ devargs->pci.addr.function);
+ }
+}
+
+/* dump the user virtual devices on the console */
+void
+rte_eal_vdevargs_dump(FILE *f)
+{
+ struct rte_vdevargs *vdevargs;
+
+ fprintf(f, "User virtual devices list:\n");
+ TAILQ_FOREACH(vdevargs, &vdevargs_list, next) {
+ fprintf(f, " VIRTUAL %s %s\n",
+ vdevargs->drv_name,
+ vdevargs->args);
+ }
+}
+
+int
+rte_eal_check_vdevs_definition(void)
+{
+ struct rte_devargs *devargs;
+ struct rte_vdevargs *vdevargs;
+ int found;
+
+ /* Go through all white/black listed devices */
+ TAILQ_FOREACH(devargs, &devargs_list, next) {
+
+ /* Only check the virtual ones */
+ if (!devargs->is_vdev)
+ continue;
+
+ /* Search for the virtual device definition */
+ found = 0;
+ TAILQ_FOREACH(vdevargs, &vdevargs_list, next) {
+ if (!strncmp(vdevargs->drv_name, devargs->virtual.drv_name,
+ sizeof(vdevargs->drv_name))) {
+ found = 1;
+ devargs->virtual.vdev = vdevargs;
+ }
+ }
+
+ /* If the virtual device was not defined return an error */
+ if (!found) {
+ RTE_LOG(ERR, EAL, "Virtual device %s is %slisted but not defined. "
+ "Use '--vdev=%s,...' to define it.\n",
+ devargs->virtual.drv_name,
+ devargs->select == RTE_DEV_WHITELISTED ? "white" : "black",
+ devargs->virtual.drv_name);
+ return -1;
+ }
}
+
+ return 0;
}
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 7a5d55e..e044a51 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -244,17 +244,13 @@ eal_parse_common_option(int opt, const char *optarg,
switch (opt) {
/* blacklist */
case 'b':
- if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI,
- optarg) < 0) {
+ if (rte_eal_devargs_add(RTE_DEV_BLACKLISTED, optarg) < 0)
return -1;
- }
break;
/* whitelist */
case 'w':
- if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI,
- optarg) < 0) {
+ if (rte_eal_devargs_add(RTE_DEV_WHITELISTED, optarg) < 0)
return -1;
- }
break;
/* coremask */
case 'c':
@@ -321,8 +317,7 @@ eal_parse_common_option(int opt, const char *optarg,
break;
case OPT_VDEV_NUM:
- if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL,
- optarg) < 0) {
+ if (rte_eal_vdevargs_add(optarg) < 0) {
return -1;
}
break;
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index f3c7f71..19b3ce4 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -85,13 +85,14 @@
struct pci_driver_list pci_driver_list;
struct pci_device_list pci_device_list;
-static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
+static struct rte_devargs *
+pci_devargs_lookup(struct rte_pci_device *dev)
{
struct rte_devargs *devargs;
TAILQ_FOREACH(devargs, &devargs_list, next) {
- if (devargs->type != RTE_DEVTYPE_BLACKLISTED_PCI &&
- devargs->type != RTE_DEVTYPE_WHITELISTED_PCI)
+ if (devargs->select != RTE_DEV_BLACKLISTED &&
+ devargs->select != RTE_DEV_WHITELISTED)
continue;
if (!memcmp(&dev->addr, &devargs->pci.addr, sizeof(dev->addr)))
return devargs;
@@ -136,7 +137,7 @@ rte_eal_pci_probe(void)
int probe_all = 0;
int ret = 0;
- if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) == 0)
+ if (rte_eal_devargs_type_count(RTE_DEV_WHITELISTED) == 0)
probe_all = 1;
TAILQ_FOREACH(dev, &pci_device_list, next) {
@@ -150,7 +151,7 @@ rte_eal_pci_probe(void)
if (probe_all)
ret = pci_probe_all_drivers(dev);
else if (devargs != NULL &&
- devargs->type == RTE_DEVTYPE_WHITELISTED_PCI)
+ devargs->select == RTE_DEV_WHITELISTED)
ret = pci_probe_all_drivers(dev);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Requested device " PCI_PRI_FMT
diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h
index 9f9c98f..b6599ef 100644
--- a/lib/librte_eal/common/include/rte_devargs.h
+++ b/lib/librte_eal/common/include/rte_devargs.h
@@ -52,96 +52,158 @@ extern "C" {
#include <sys/queue.h>
#include <rte_pci.h>
+#define RTE_VDEV_NAME_LEN 32
+
/**
- * Type of generic device
+ * Type of device selection
*/
-enum rte_devtype {
- RTE_DEVTYPE_WHITELISTED_PCI,
- RTE_DEVTYPE_BLACKLISTED_PCI,
- RTE_DEVTYPE_VIRTUAL,
+enum rte_devselect {
+ RTE_DEV_WHITELISTED,
+ RTE_DEV_BLACKLISTED,
};
/**
- * Structure that stores a device given by the user with its arguments
+ * Structure that stores a virtual device given by the user with its arguments
+ *
+ * The structure stores the configuration of the device and its name which
+ * contains its driver name
+ */
+struct rte_vdevargs {
+ /** Next in list. */
+ TAILQ_ENTRY(rte_vdevargs) next;
+ /** Driver name. */
+ char drv_name[RTE_VDEV_NAME_LEN];
+#define RTE_VDEVARGS_LEN 256
+ char args[RTE_VDEVARGS_LEN]; /**< Arguments string as given by user. */
+};
+
+/**
+ * Structure that stores the user selected devices.
*
* A user device is a physical or a virtual device given by the user to
* the DPDK application at startup through command line arguments.
*
- * The structure stores the configuration of the device, its PCI
- * identifier if it's a PCI device or the driver name if it's a virtual
- * device.
+ * The devices can be whitelisted or blacklisted independently if they are
+ * physical or virtual devices.
*/
struct rte_devargs {
/** Next in list. */
TAILQ_ENTRY(rte_devargs) next;
- /** Type of device. */
- enum rte_devtype type;
+ /** Type of device selection. */
+ enum rte_devselect select;
+ int is_vdev;
union {
- /** Used if type is RTE_DEVTYPE_*_PCI. */
+ /** Used if physical device. */
struct {
/** PCI location. */
struct rte_pci_addr addr;
} pci;
- /** Used if type is RTE_DEVTYPE_VIRTUAL. */
+ /** Used if virtual device. */
struct {
/** Driver name. */
- char drv_name[32];
+ char drv_name[RTE_VDEV_NAME_LEN];
+ struct rte_vdevargs *vdev;
} virtual;
};
-#define RTE_DEVARGS_LEN 256
- char args[RTE_DEVARGS_LEN]; /**< Arguments string as given by user. */
};
/** user device double-linked queue type definition */
TAILQ_HEAD(rte_devargs_list, rte_devargs);
+TAILQ_HEAD(rte_vdevargs_list, rte_vdevargs);
/** Global list of user devices */
extern struct rte_devargs_list devargs_list;
+/** Global list of virtual devices */
+extern struct rte_vdevargs_list vdevargs_list;
+
/**
* Add a device to the user device list
*
- * For PCI devices, the format of arguments string is "PCI_ADDR" or
- * "PCI_ADDR,key=val,key2=val2,...". Examples: "08:00.1", "0000:5:00.0",
- * "04:00.0,arg=val".
+ * For PCI devices, the format of arguments string is "PCI_ADDR"
+ * Examples: "08:00.1", "0000:5:00.0".
*
- * For virtual devices, the format of arguments string is "DRIVER_NAME*"
- * or "DRIVER_NAME*,key=val,key2=val2,...". Examples: "eth_ring",
- * "eth_ring0", "eth_pmdAnything,arg=0:arg2=1". The validity of the
- * driver name is not checked by this function, it is done when probing
- * the drivers.
+ * For virtual devices, the format of arguments string is "DRIVER_NAME".
+ * Examples: "eth_ring", "eth_ring0", "eth_pmdAnything". This function does not
+ * validate if the driver name is valid or if it was already defined with
+ * --vdev.
*
- * @param devtype
- * The type of the device.
- * @param devargs_list
+ * @param devselect
+ * Whether the device is black or white listed.
+ * @param devargs_str
* The arguments as given by the user.
*
* @return
* - 0 on success
* - A negative value on error
*/
-int rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str);
+int rte_eal_devargs_add(enum rte_devselect devselect, const char *devargs_str);
/**
* Count the number of user devices of a specified type
*
- * @param devtype
+ * @param devselect
* The type of the devices to counted.
*
* @return
* The number of devices.
*/
unsigned int
-rte_eal_devargs_type_count(enum rte_devtype devtype);
+rte_eal_devargs_type_count(enum rte_devselect devselect);
/**
- * This function dumps the list of user device and their arguments.
+ * This function dumps the list of user selected devices.
*
* @param f
* A pointer to a file for output
*/
void rte_eal_devargs_dump(FILE *f);
+/**
+ * This function dumps the list of user virtual devices and their arguments.
+ *
+ * @param f
+ * A pointer to a file for output
+ */
+void rte_eal_vdevargs_dump(FILE *f);
+
+/**
+ * Add a virtual device
+ *
+ * The format of arguments string is "DRIVER_NAME*"
+ * or "DRIVER_NAME*,key=val,key2=val2,...". Examples: "eth_ring",
+ * "eth_ring0", "eth_pmdAnything,arg=0:arg2=1". The validity of the
+ * driver name is not checked by this function, it is done when probing
+ * the drivers.
+ *
+ * @param devargs_str
+ * The arguments as given by the user.
+ *
+ * @return
+ * - 0 on success
+ * - A negative value on error
+ */
+int rte_eal_vdevargs_add(const char *devargs_str);
+
+/**
+ * Check if the white/black-listed virtual devices have been defined
+ *
+ * @return
+ * - 0 on success
+ * - A negative value on error
+ */
+int rte_eal_check_vdevs_definition(void);
+
+/**
+ * Check if the virtual device is white/black-listed
+ *
+ * @return
+ * - 1 if the device is white/black-listed.
+ * - 0 otherwise.
+ */
+int rte_eal_vdevargs_is(struct rte_vdevargs *vdevargs,
+ enum rte_devselect devselect);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 7a1d087..e898688 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -696,14 +696,18 @@ eal_parse_args(int argc, char **argv)
return -1;
}
- if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) != 0 &&
- rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_PCI) != 0) {
+ if (rte_eal_devargs_type_count(RTE_DEV_WHITELISTED) != 0 &&
+ rte_eal_devargs_type_count(RTE_DEV_BLACKLISTED) != 0) {
RTE_LOG(ERR, EAL, "Error: blacklist [-b] and whitelist "
"[-w] options cannot be used at the same time\n");
eal_usage(prgname);
return -1;
}
+ /* Check if all white/black listed virtual devices were also defined */
+ if (rte_eal_check_vdevs_definition() < 0)
+ return -1;
+
if (optind >= 0)
argv[optind-1] = prgname;
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index ddb0535..b49722e 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -544,7 +544,7 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *d
/* no initialization when blacklisted, return without error */
if (dev->devargs != NULL &&
- dev->devargs->type == RTE_DEVTYPE_BLACKLISTED_PCI) {
+ dev->devargs->select == RTE_DEV_BLACKLISTED) {
RTE_LOG(DEBUG, EAL, " Device is blacklisted, not initializing\n");
return 1;
}
--
1.8.3.2
next reply other threads:[~2014-11-16 21:16 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-16 21:26 Nicolás Pernas Maradei [this message]
2014-11-17 14:10 ` Neil Horman
2014-11-17 14:58 ` Nicolas Pernas Maradei
[not found] ` <546A0BA2.3040306@emutex.com>
2014-11-17 16:00 ` Neil Horman
2014-11-17 16:40 ` Nicolas Pernas Maradei
2014-11-17 16:52 ` Bruce Richardson
2014-11-17 21:17 ` Neil Horman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1416173215-27533-1-git-send-email-nicolas.pernas.maradei@emutex.com \
--to=nicolas.pernas.maradei@emutex.com \
--cc=dev@dpdk.org \
--cc=nico@emutex.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).