From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?q?Nicol=C3=A1s=20Pernas=20Maradei?= Subject: [PATCH] eal: allow virtual devices to be white/black listed Date: Sun, 16 Nov 2014 21:26:55 +0000 Message-ID: <1416173215-27533-1-git-send-email-nicolas.pernas.maradei@emutex.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Cc: =?UTF-8?q?Nicol=C3=A1s=20Pernas=20Maradei?= To: dev-VfR2kkLFssw@public.gmane.org Return-path: List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces-VfR2kkLFssw@public.gmane.org Sender: "dev" From: Nicol=C3=A1s Pernas Maradei 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=C3=A1s Pernas Maradei --- 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); } =20 cmdline_parse_token_string_t cmd_dump_dump =3D @@ -6854,7 +6856,8 @@ cmdline_parse_token_string_t cmd_dump_dump =3D "dump_struct_sizes#" "dump_ring#" "dump_mempool#" - "dump_devargs"); + "dump_devargs#" + "dump_vdevargs"); =20 cmdline_parse_inst_t cmd_dump =3D { .f =3D 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); } =20 cmdline_parse_token_string_t cmd_dump_dump =3D 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"); =20 cmdline_parse_inst_t cmd_dump =3D { .f =3D 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) } } =20 +/* 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 =3D 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; =20 /* save the real devargs_list, it is restored at the end of the test */ save_devargs_list =3D devargs_list; + save_vdevargs_list =3D vdevargs_list; TAILQ_INIT(&devargs_list); + TAILQ_INIT(&vdevargs_list); =20 /* 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=3Dval= ") < 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) !=3D 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) !=3D 2) + if (rte_eal_devargs_add(RTE_DEV_BLACKLISTED, "04:00.0") < 0) goto fail; - if (rte_eal_devargs_type_count(RTE_DEVTYPE_VIRTUAL) !=3D 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) !=3D 2) goto fail; - if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "eth_ring1,key=3Dval,k2=3D= val2") < 0) - goto fail; - if (rte_eal_devargs_type_count(RTE_DEVTYPE_VIRTUAL) !=3D 2) + if (rte_eal_devargs_type_count(RTE_DEV_BLACKLISTED) !=3D 2) goto fail; free_devargs_list(); =20 /* check virtual device with argument parsing */ - if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "eth_ring1,k1=3Dval,k2=3Dv= al2") < 0) + if (rte_eal_vdevargs_add("eth_ring1,k1=3Dval,k2=3Dval2") < 0) goto fail; - devargs =3D TAILQ_FIRST(&devargs_list); - if (strncmp(devargs->virtual.drv_name, "eth_ring1", - sizeof(devargs->virtual.drv_name) !=3D 0)) + vdevargs =3D TAILQ_FIRST(&vdevargs_list); + if (strncmp(vdevargs->drv_name, "eth_ring1", + sizeof(vdevargs->drv_name) !=3D 0)) goto fail; - if (strncmp(devargs->args, "k1=3Dval,k2=3Dval2", sizeof(devargs->args) = !=3D 0)) + if (strncmp(vdevargs->args, "k1=3Dval,k2=3Dval2", sizeof(vdevargs->args= ) !=3D 0)) goto fail; - free_devargs_list(); + free_vdevargs_list(); =20 /* 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 =3D TAILQ_FIRST(&devargs_list); if (devargs->pci.addr.domain !=3D 0 || @@ -105,28 +113,25 @@ test_devargs(void) devargs->pci.addr.devid !=3D 0 || devargs->pci.addr.function !=3D 1) goto fail; - if (strncmp(devargs->args, "", sizeof(devargs->args) !=3D 0)) - goto fail; free_devargs_list(); =20 - /* test error case: bad PCI address */ - if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "08:1") =3D=3D 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") =3D=3D 0) - goto fail; - if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "foo") =3D=3D 0) - goto fail; - if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, ",") =3D=3D 0) - goto fail; - if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "000f:0:0") =3D=3D= 0) + devargs =3D TAILQ_FIRST(&devargs_list); + if (strncmp(devargs->virtual.drv_name, "eth_pcap0", + sizeof(devargs->virtual.drv_name)) !=3D 0) goto fail; =20 devargs_list =3D save_devargs_list; + vdevargs_list =3D save_vdevargs_list; return 0; =20 fail: free_devargs_list(); + free_vdevargs_list(); devargs_list =3D save_devargs_list; + vdevargs_list =3D save_vdevargs_list; return -1; } =20 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; } =20 - if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) !=3D 0 && - rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_PCI) !=3D 0) { + if (rte_eal_devargs_type_count(RTE_DEV_WHITELISTED) !=3D 0 && + rte_eal_devargs_type_count(RTE_DEV_BLACKLISTED) !=3D 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; } =20 + /* Check if all white/black listed virtual devices were also defined */ + if (rte_eal_check_vdevs_definition() < 0) + return -1; + if (optind >=3D 0) argv[optind-1] =3D prgname; =20 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 *d= r, struct rte_pci_device *d =20 /* no initialization when blacklisted, return without error */ if (dev->devargs !=3D NULL && - dev->devargs->type =3D=3D RTE_DEVTYPE_BLACKLISTED_PCI) { + dev->devargs->select =3D=3D RTE_DEV_BLACKLISTED) { =20 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/comm= on/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 =3D rte_eal_devargs_type_count(RTE_DEV_WHITELISTED); =20 /* * Note that the dev_driver_list is populated here @@ -74,9 +77,13 @@ rte_eal_dev_init(void) */ =20 /* 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; =20 - if (devargs->type !=3D RTE_DEVTYPE_VIRTUAL) + if (whitelisted_devs + && !rte_eal_vdevargs_is(vdevargs, RTE_DEV_WHITELISTED)) continue; =20 TAILQ_FOREACH(driver, &dev_driver_list, next) { @@ -84,18 +91,15 @@ rte_eal_dev_init(void) continue; =20 /* 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; } } =20 - if (driver =3D=3D NULL) { - rte_panic("no driver found for %s\n", - devargs->virtual.drv_name); - } + if (driver =3D=3D NULL) + rte_panic("no driver found for %s\n", vdevargs->drv_name); } =20 /* 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 =3D TAILQ_HEAD_INITIALIZER(devargs_list); +struct rte_vdevargs_list vdevargs_list =3D + TAILQ_HEAD_INITIALIZER(vdevargs_list); =20 /* 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_st= r) { struct rte_devargs *devargs; - char buf[RTE_DEVARGS_LEN]; - char *sep; + char buf[RTE_VDEV_NAME_LEN]; int ret; =20 ret =3D 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 =3D devtype; + devargs->select =3D devselect; + + /* try to parse short PCI identifier */ + if (eal_parse_pci_BDF(buf, &devargs->pci.addr) =3D=3D 0) + goto done; + + /* try to parse long PCI identifier */ + if (eal_parse_pci_DomBDF(buf, &devargs->pci.addr) =3D=3D 0) + goto done; + + /* If device ID is not a valid PCI ID assume is a virtual driver name *= / + devargs->is_vdev =3D 1; + ret =3D snprintf(devargs->virtual.drv_name, sizeof(devargs->virtual.drv= _name), "%s", buf); + if (ret < 0 || ret >=3D (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 =3D snprintf(buf, sizeof(buf), "%s", vdevargs_str); + if (ret < 0 || ret >=3D (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 =3D malloc(sizeof(*vdevargs)); + if (vdevargs =3D=3D NULL) { + RTE_LOG(ERR, EAL, "cannot allocate vdevargs\n"); + return -1; + } + memset(vdevargs, 0, sizeof(*vdevargs)); =20 /* set the first ',' to '\0' to split name and arguments */ sep =3D strchr(buf, ','); if (sep !=3D NULL) { sep[0] =3D '\0'; - snprintf(devargs->args, sizeof(devargs->args), "%s", sep + 1); + snprintf(vdevargs->args, sizeof(vdevargs->args), "%s", sep + 1); } =20 - 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) !=3D 0 && - eal_parse_pci_DomBDF(buf, &devargs->pci.addr) !=3D 0) { - RTE_LOG(ERR, EAL, - "invalid PCI identifier <%s>\n", buf); - free(devargs); - return -1; - } - break; - case RTE_DEVTYPE_VIRTUAL: - /* save driver name */ - ret =3D snprintf(devargs->virtual.drv_name, - sizeof(devargs->virtual.drv_name), "%s", buf); - if (ret < 0 || ret >=3D (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 =3D snprintf(vdevargs->drv_name, sizeof(vdevargs->drv_name), "%s", = buf); + if (ret < 0 || ret >=3D (int)sizeof(vdevargs->drv_name)) { + RTE_LOG(ERR, EAL, "driver name too large: <%s>\n", buf); + free(vdevargs); + return -1; } =20 - TAILQ_INSERT_TAIL(&devargs_list, devargs, next); + TAILQ_INSERT_TAIL(&vdevargs_list, vdevargs, next); return 0; } =20 /* 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 =3D 0; =20 TAILQ_FOREACH(devargs, &devargs_list, next) { - if (devargs->type !=3D devtype) + if (devargs->select !=3D devselect) continue; count++; } return count; } =20 -/* dump the user devices on the console */ +int +rte_eal_vdevargs_is(struct rte_vdevargs *vdevargs, enum rte_devselect de= vselect) +{ + 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 =3D=3D devselect); + } + return 0; +} + +/* dump the user selected devices on the console */ void rte_eal_devargs_dump(FILE *f) { struct rte_devargs *devargs; =20 - fprintf(f, "User device white list:\n"); + fprintf(f, "User selected devices list:\n"); TAILQ_FOREACH(devargs, &devargs_list, next) { - if (devargs->type =3D=3D 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 =3D=3D 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 =3D=3D RTE_DEVTYPE_VIRTUAL) - fprintf(f, " VIRTUAL %s %s\n", - devargs->virtual.drv_name, - devargs->args); + if (devargs->select =3D=3D RTE_DEV_WHITELISTED) + fprintf(f, " PCI whitelist "); + else if (devargs->select =3D=3D 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 =3D 0; + TAILQ_FOREACH(vdevargs, &vdevargs_list, next) { + if (!strncmp(vdevargs->drv_name, devargs->virtual.drv_name, + sizeof(vdevargs->drv_name))) { + found =3D 1; + devargs->virtual.vdev =3D 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=3D%s,...' to define it.\n", + devargs->virtual.drv_name, + devargs->select =3D=3D 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; =20 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/comm= on/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; =20 -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; =20 TAILQ_FOREACH(devargs, &devargs_list, next) { - if (devargs->type !=3D RTE_DEVTYPE_BLACKLISTED_PCI && - devargs->type !=3D RTE_DEVTYPE_WHITELISTED_PCI) + if (devargs->select !=3D RTE_DEV_BLACKLISTED && + devargs->select !=3D 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 =3D 0; int ret =3D 0; =20 - if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) =3D=3D 0) + if (rte_eal_devargs_type_count(RTE_DEV_WHITELISTED) =3D=3D 0) probe_all =3D 1; =20 TAILQ_FOREACH(dev, &pci_device_list, next) { @@ -150,7 +151,7 @@ rte_eal_pci_probe(void) if (probe_all) ret =3D pci_probe_all_drivers(dev); else if (devargs !=3D NULL && - devargs->type =3D=3D RTE_DEVTYPE_WHITELISTED_PCI) + devargs->select =3D=3D RTE_DEV_WHITELISTED) ret =3D 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 #include =20 +#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, }; =20 /** - * Structure that stores a device given by the user with its arguments + * Structure that stores a virtual device given by the user with its arg= uments + * + * The structure stores the configuration of the device and its name whi= ch + * 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 a= re + * 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. */ }; =20 /** user device double-linked queue type definition */ TAILQ_HEAD(rte_devargs_list, rte_devargs); +TAILQ_HEAD(rte_vdevargs_list, rte_vdevargs); =20 /** Global list of user devices */ extern struct rte_devargs_list devargs_list; =20 +/** 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=3Dval,key2=3Dval2,...". Examples: "08:00.1", "0000:5:00= .0", - * "04:00.0,arg=3Dval". + * 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=3Dval,key2=3Dval2,...". Examples: "eth_ring", - * "eth_ring0", "eth_pmdAnything,arg=3D0:arg2=3D1". 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 d= oes not + * validate if the driver name is valid or if it was already defined wit= h + * --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_st= r); +int rte_eal_devargs_add(enum rte_devselect devselect, const char *devarg= s_str); =20 /** * 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); =20 /** - * 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); =20 +/** + * This function dumps the list of user virtual devices and their argume= nts. + * + * @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=3Dval,key2=3Dval2,...". Examples: "eth_ring", + * "eth_ring0", "eth_pmdAnything,arg=3D0:arg2=3D1". 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; } =20 - if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) !=3D 0 && - rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_PCI) !=3D 0) { + if (rte_eal_devargs_type_count(RTE_DEV_WHITELISTED) !=3D 0 && + rte_eal_devargs_type_count(RTE_DEV_BLACKLISTED) !=3D 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; } =20 + /* Check if all white/black listed virtual devices were also defined */ + if (rte_eal_check_vdevs_definition() < 0) + return -1; + if (optind >=3D 0) argv[optind-1] =3D prgname; =20 diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linux= app/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 *d= r, struct rte_pci_device *d =20 /* no initialization when blacklisted, return without error */ if (dev->devargs !=3D NULL && - dev->devargs->type =3D=3D RTE_DEVTYPE_BLACKLISTED_PCI) { + dev->devargs->select =3D=3D RTE_DEV_BLACKLISTED) { RTE_LOG(DEBUG, EAL, " Device is blacklisted, not initializing\n"); return 1; } --=20 1.8.3.2