From patchwork Sun Nov 16 21:26:55 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Nicol=C3=A1s_Pernas_Maradei?= X-Patchwork-Id: 1316 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id DCAF27F74; Sun, 16 Nov 2014 22:16:53 +0100 (CET) Received: from smtp.digiweb.ie (smtp2.digiweb.ie [83.147.160.14]) by dpdk.org (Postfix) with ESMTP id 0F0147F71 for ; Sun, 16 Nov 2014 22:16:52 +0100 (CET) Received: from statler.emutex.com (unknown [92.51.199.138]) by smtp.digiweb.ie (Postfix) with ESMTP id AE0C9290037 for ; Sun, 16 Nov 2014 21:27:02 +0000 (GMT) Received: from [10.10.64.102] (helo=nico-emutex.emutex.com) by statler.emutex.com with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.72) (envelope-from ) id 1Xq7La-0001u4-GR; Sun, 16 Nov 2014 21:27:02 +0000 From: =?UTF-8?q?Nicol=C3=A1s=20Pernas=20Maradei?= To: dev@dpdk.org Date: Sun, 16 Nov 2014 21:26:55 +0000 Message-Id: <1416173215-27533-1-git-send-email-nicolas.pernas.maradei@emutex.com> X-Mailer: git-send-email 1.8.3.2 MIME-Version: 1.0 Cc: =?UTF-8?q?Nicol=C3=A1s=20Pernas=20Maradei?= Subject: [dpdk-dev] [PATCH] eal: allow virtual devices to be white/black listed X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Nicolás 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ás 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); } 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 #include +#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; }