[dpdk-dev] [PATCH 09/13] devargs: parse "bus=" argument
Jan Blunck
jblunck at infradead.org
Thu Jul 13 21:34:33 CEST 2017
On Thu, Jul 13, 2017 at 9:40 AM, Gaëtan Rivet <gaetan.rivet at 6wind.com> wrote:
> I still disagree with parsing the body of devargs to retrieve bus
> information. They should not be mixed.
>
I agree. I always said that it should be passed explicitly. If we
agree on this I'll fix the signature of rte_eal_devargs_parse()
accordingly.
> This conceptual discrepancy can be seen plainly in the code structure:
> you emulate librte_kvargs because you do not want to depend on it within
> the EAL, but copy its behavior and are forced to rewrite it partially.
>
> Can you justify this? The commitlog does not describe the problem being
> solved.
>
> I think there should be a discussion about the future format of device
> declarations. One version has been integrated in RC1 but it will be reworked
> anyway. I'd like to hear more opinions.
>
> On Tue, Jul 11, 2017 at 07:25:08PM -0400, Jan Blunck wrote:
>> Let the rte_eal_devargs_parse() function parse the "bus=" argument.
>>
>> Signed-off-by: Jan Blunck <jblunck at infradead.org>
>> ---
>> lib/librte_eal/common/eal_common_devargs.c | 131 ++++++++++++++++++-----------
>> test/test/test_devargs.c | 19 +++++
>> 2 files changed, 102 insertions(+), 48 deletions(-)
>>
>> diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
>> index 2bdee9a30..a0d0e6e91 100644
>> --- a/lib/librte_eal/common/eal_common_devargs.c
>> +++ b/lib/librte_eal/common/eal_common_devargs.c
>> @@ -77,6 +77,40 @@ rte_eal_parse_devargs_str(const char *devargs_str,
>> return 0;
>> }
>>
>> +/*
>> + * Parse "bus=" argument without adding a dependency on rte_kvargs.h
>> + */
>> +static char *parse_bus_arg(const char *args)
>> +{
>> + const char *c;
>> + char *str = NULL;
>> +
>> + if (!args || args[0] == '\0')
>> + return NULL;
>> +
>> + c = args;
>> +
>> + do {
>> + if (strncmp(c, "bus=", 4) == 0) {
>> + c += 4;
>> + break;
>> + }
>> +
>> + c = strchr(c, ',');
>> + if (c)
>> + c++;
>> + } while (c);
>> +
>> + if (c) {
>> + str = strdup(c);
>> + c = strchr(str, ',');
>> + if (c)
>> + c = '\0';
>> + }
>> +
>> + return str;
>> +}
>> +
>> static int
>> devargs_add(const char *busname, const char *name, const char *args)
>> {
>> @@ -113,64 +147,65 @@ devargs_add(const char *busname, const char *name, const char *args)
>> return -1;
>> }
>>
>> -static int
>> -bus_name_cmp(const struct rte_bus *bus, const void *name)
>> -{
>> - return strncmp(bus->name, name, strlen(bus->name));
>> -}
>> -
>> int
>> rte_eal_devargs_parse(const char *dev, struct rte_devargs *da)
>> {
>> - struct rte_bus *bus = NULL;
>> - const char *devname;
>> - const size_t maxlen = sizeof(da->name);
>> - size_t i;
>> + char *busname;
>> + char *devname;
>> + char *drvargs;
>> + int ret;
>>
>> if (dev == NULL || da == NULL)
>> return -EINVAL;
>> - /* Retrieve eventual bus info */
>> - do {
>> - devname = dev;
>> - bus = rte_bus_find(bus, bus_name_cmp, dev);
>> - if (bus == NULL)
>> - break;
>> - devname = dev + strlen(bus->name) + 1;
>> - if (rte_bus_find_by_device_name(devname) == bus)
>> - break;
>> - } while (1);
>> - /* Store device name */
>> - i = 0;
>> - while (devname[i] != '\0' && devname[i] != ',') {
>> - da->name[i] = devname[i];
>> - i++;
>> - if (i == maxlen) {
>> - fprintf(stderr, "WARNING: Parsing \"%s\": device name should be shorter than %zu\n",
>> - dev, maxlen);
>> - da->name[i - 1] = '\0';
>> - return -EINVAL;
>> - }
>> - }
>> - da->name[i] = '\0';
>> - if (bus == NULL) {
>> - bus = rte_bus_find_by_device_name(da->name);
>> +
>> + ret = rte_eal_parse_devargs_str(dev, &devname, &drvargs);
>> + if (ret != 0)
>> + return ret;
>> +
>> + RTE_LOG(DEBUG, EAL, "%s: adding devargs for device [%s]: %s\n",
>> + __FUNCTION__, devname, drvargs);
>> +
>> + /* Retrieve eventual bus info (...,bus=...)*/
>> + busname = parse_bus_arg(drvargs);
>> + if (busname == NULL) {
>> + struct rte_bus *bus;
>> +
>> + bus = rte_bus_find_by_device_name(devname);
>> if (bus == NULL) {
>> - fprintf(stderr, "ERROR: failed to parse device \"%s\"\n",
>> - da->name);
>> - return -EFAULT;
>> + RTE_LOG(ERR, EAL, "failed to parse device [%s]\n",
>> + devname);
>> + ret = -EINVAL;
>> + goto fail;
>> }
>> +
>> + busname = strdup(bus->name);
>> }
>> - da->bus = bus;
>> - /* Parse eventual device arguments */
>> - if (devname[i] == ',')
>> - da->args = strdup(&devname[i + 1]);
>> - else
>> - da->args = strdup("");
>> - if (da->args == NULL) {
>> - fprintf(stderr, "ERROR: not enough memory to parse arguments\n");
>> - return -ENOMEM;
>> +
>> + ret = devargs_add(busname, devname, drvargs);
>> + if (ret != 0) {
>> + RTE_LOG(ERR, EAL, "devargs_add failed for device [%s]\n",
>> + devname);
>> + goto fail;
>> }
>> - return 0;
>> +
>> + ret = snprintf(da->busname, sizeof(da->busname), "%s", busname);
>> + if (ret < 0 || ret >= (int)sizeof(da->busname))
>> + goto fail;
>> +
>> + ret = snprintf(da->name, sizeof(da->name), "%s", devname);
>> + if (ret < 0 || ret >= (int)sizeof(da->name))
>> + goto fail;
>> +
>> + da->args = strdup(drvargs);
>> + if (da->args == NULL)
>> + ret = -ENOMEM;
>> + ret = 0;
>> +
>> +fail:
>> + free(busname);
>> + free(devname);
>> + free(drvargs);
>> + return ret;
>> }
>>
>> static const struct rte_bus_conf BUS_CONF_WHITELIST = {
>> diff --git a/test/test/test_devargs.c b/test/test/test_devargs.c
>> index 048b3d00b..3a1033ca3 100644
>> --- a/test/test/test_devargs.c
>> +++ b/test/test/test_devargs.c
>> @@ -58,6 +58,7 @@ test_devargs(void)
>> {
>> struct rte_devargs_list save_devargs_list;
>> struct rte_devargs *devargs;
>> + struct rte_devargs devargs_stack;
>>
>> /* save the real devargs_list, it is restored at the end of the test */
>> save_devargs_list = devargs_list;
>> @@ -109,6 +110,24 @@ test_devargs(void)
>> goto fail;
>> free_devargs_list();
>>
>> + if (rte_eal_devargs_parse("", &devargs_stack) == 0) {
>> + printf("Error in rte_eal_devargs_parse\n");
>> + goto fail;
>> + }
>> +
>> + if (rte_eal_devargs_parse("08:00.1,foo=bar,bus=pci", &devargs_stack) != 0) {
>> + printf("Error in rte_eal_devargs_parse 08:00.1,bus=pci\n");
>> + goto fail;
>> + }
>> + devargs = TAILQ_FIRST(&devargs_list);
>> + if (strcmp(devargs->name, "08:00.1") != 0)
>> + goto fail;
>> + if (strcmp(devargs->busname, "pci") != 0)
>> + goto fail;
>> + if (!devargs->args || strcmp(devargs->args, "foo=bar,bus=pci") != 0)
>> + goto fail;
>> +
>> + free_devargs_list();
>> devargs_list = save_devargs_list;
>> return 0;
>>
>> --
>> 2.13.2
>>
>
> --
> Gaėtan Rivet
> 6WIND
More information about the dev
mailing list