From: Xueming Li Date: Thu, 11 Mar 2021 13:13:25 +0000 (+0000) Subject: ethdev: refactor representor port list parsing X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=83a675177fdcf8f6cb2f6a65450a71e5424b80fb;p=dpdk.git ethdev: refactor representor port list parsing To the extended representor syntax which need to reuse the value parsing function for controller and PF section, this patch refactors the port list parsing. Signed-off-by: Xueming Li Acked-by: Viacheslav Ovsiienko Acked-by: Thomas Monjalon Acked-by: Andrew Rybchenko --- diff --git a/lib/librte_ethdev/ethdev_private.c b/lib/librte_ethdev/ethdev_private.c index 2d51e3857a..d5ef05ea6f 100644 --- a/lib/librte_ethdev/ethdev_private.c +++ b/lib/librte_ethdev/ethdev_private.c @@ -38,82 +38,91 @@ eth_find_device(const struct rte_eth_dev *start, rte_eth_cmp_t cmp, return NULL; } -int -rte_eth_devargs_parse_list(char *str, rte_eth_devargs_callback_t callback, - void *data) +/* Put new value into list. */ +static int +rte_eth_devargs_enlist(uint16_t *list, uint16_t *len_list, + const uint16_t max_list, uint16_t val) { - char *str_start; - int state; - int result; - - if (*str != '[') - /* Single element, not a list */ - return callback(str, data); - - /* Sanity check, then strip the brackets */ - str_start = &str[strlen(str) - 1]; - if (*str_start != ']') { - RTE_LOG(ERR, EAL, "(%s): List does not end with ']'\n", str); - return -EINVAL; - } - str++; - *str_start = '\0'; + uint16_t i; - /* Process list elements */ - state = 0; - while (1) { - if (state == 0) { - if (*str == '\0') - break; - if (*str != ',') { - str_start = str; - state = 1; - } - } else if (state == 1) { - if (*str == ',' || *str == '\0') { - if (str > str_start) { - /* Non-empty string fragment */ - *str = '\0'; - result = callback(str_start, data); - if (result < 0) - return result; - } - state = 0; - } - } - str++; + for (i = 0; i < *len_list; i++) { + if (list[i] == val) + return 0; } + if (*len_list >= max_list) + return -1; + list[(*len_list)++] = val; return 0; } -static int +/* Parse and enlist a range expression of "min-max" or a single value. */ +static char * rte_eth_devargs_process_range(char *str, uint16_t *list, uint16_t *len_list, const uint16_t max_list) { uint16_t lo, hi, val; - int result; + int result, n = 0; + char *pos = str; - result = sscanf(str, "%hu-%hu", &lo, &hi); + result = sscanf(str, "%hu%n-%hu%n", &lo, &n, &hi, &n); if (result == 1) { - if (*len_list >= max_list) - return -ENOMEM; - list[(*len_list)++] = lo; + if (rte_eth_devargs_enlist(list, len_list, max_list, lo) != 0) + return NULL; } else if (result == 2) { - if (lo >= hi || lo > RTE_MAX_ETHPORTS || hi > RTE_MAX_ETHPORTS) - return -EINVAL; + if (lo > hi) + return NULL; for (val = lo; val <= hi; val++) { - if (*len_list >= max_list) - return -ENOMEM; - list[(*len_list)++] = val; + if (rte_eth_devargs_enlist(list, len_list, max_list, + val) != 0) + return NULL; } } else - return -EINVAL; - return 0; + return NULL; + return pos + n; +} + +/* + * Parse list of values separated by ",". + * Each value could be a range [min-max] or single number. + * Examples: + * 2 - single + * [1,2,3] - single list + * [1,3-5,7,9-11] - list with singles and ranges + */ +static char * +rte_eth_devargs_process_list(char *str, uint16_t *list, uint16_t *len_list, + const uint16_t max_list) +{ + char *pos = str; + + if (*pos == '[') + pos++; + while (1) { + pos = rte_eth_devargs_process_range(pos, list, len_list, + max_list); + if (pos == NULL) + return NULL; + if (*pos != ',') /* end of list */ + break; + pos++; + } + if (*str == '[' && *pos != ']') + return NULL; + if (*pos == ']') + pos++; + return pos; } /* - * representor format: + * Parse representor ports from a single value or lists. + * + * Representor format: * #: range or single number of VF representor + * + * Examples of #: + * 2 - single + * [1,2,3] - single list + * [1,3-5,7,9-11] - list with singles and ranges */ int rte_eth_devargs_parse_representor_ports(char *str, void *data) @@ -121,6 +130,10 @@ rte_eth_devargs_parse_representor_ports(char *str, void *data) struct rte_eth_devargs *eth_da = data; eth_da->type = RTE_ETH_REPRESENTOR_VF; - return rte_eth_devargs_process_range(str, eth_da->representor_ports, - ð_da->nb_representor_ports, RTE_MAX_ETHPORTS); + str = rte_eth_devargs_process_list(str, eth_da->representor_ports, + ð_da->nb_representor_ports, + RTE_DIM(eth_da->representor_ports)); + if (str == NULL) + RTE_LOG(ERR, EAL, "wrong representor format: %s\n", str); + return str == NULL ? -1 : 0; } diff --git a/lib/librte_ethdev/ethdev_private.h b/lib/librte_ethdev/ethdev_private.h index 905a45c337..220ddd4408 100644 --- a/lib/librte_ethdev/ethdev_private.h +++ b/lib/librte_ethdev/ethdev_private.h @@ -26,9 +26,6 @@ eth_find_device(const struct rte_eth_dev *_start, rte_eth_cmp_t cmp, const void *data); /* Parse devargs value for representor parameter. */ -typedef int (*rte_eth_devargs_callback_t)(char *str, void *data); -int rte_eth_devargs_parse_list(char *str, rte_eth_devargs_callback_t callback, - void *data); int rte_eth_devargs_parse_representor_ports(char *str, void *data); #ifdef __cplusplus diff --git a/lib/librte_ethdev/rte_class_eth.c b/lib/librte_ethdev/rte_class_eth.c index ca2ce87f7a..051c892b40 100644 --- a/lib/librte_ethdev/rte_class_eth.c +++ b/lib/librte_ethdev/rte_class_eth.c @@ -77,9 +77,7 @@ eth_representor_cmp(const char *key __rte_unused, if (values == NULL) return -1; memset(&representors, 0, sizeof(representors)); - ret = rte_eth_devargs_parse_list(values, - rte_eth_devargs_parse_representor_ports, - &representors); + ret = rte_eth_devargs_parse_representor_ports(values, &representors); free(values); if (ret != 0) return -1; /* invalid devargs value */ diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c index 6f514c388b..fe9466a03e 100644 --- a/lib/librte_ethdev/rte_ethdev.c +++ b/lib/librte_ethdev/rte_ethdev.c @@ -5589,9 +5589,8 @@ rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_da) for (i = 0; i < args.count; i++) { pair = &args.pairs[i]; if (strcmp("representor", pair->key) == 0) { - result = rte_eth_devargs_parse_list(pair->value, - rte_eth_devargs_parse_representor_ports, - eth_da); + result = rte_eth_devargs_parse_representor_ports( + pair->value, eth_da); if (result < 0) goto parse_cleanup; }