From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by dpdk.org (Postfix) with ESMTP id 777DEAAE8 for ; Fri, 20 Apr 2018 15:16:47 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Apr 2018 06:16:46 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,301,1520924400"; d="scan'208";a="35747831" Received: from irsmsx154.ger.corp.intel.com ([163.33.192.96]) by orsmga006.jf.intel.com with ESMTP; 20 Apr 2018 06:16:44 -0700 Received: from irsmsx102.ger.corp.intel.com ([169.254.2.164]) by IRSMSX154.ger.corp.intel.com ([169.254.12.234]) with mapi id 14.03.0319.002; Fri, 20 Apr 2018 14:16:43 +0100 From: "Ananyev, Konstantin" To: "Doherty, Declan" , "dev@dpdk.org" CC: Adrien Mazarguil , "Yigit, Ferruh" , Thomas Monjalon , "Shahaf Shuler" , "Horton, Remy" , "Doherty, Declan" Thread-Topic: [dpdk-dev] [PATCH v7 6/9] ethdev: add common devargs parser Thread-Index: AQHT1YUvMSSgqoeDik+h3g5uObe7Z6QJpHig Date: Fri, 20 Apr 2018 13:16:43 +0000 Message-ID: <2601191342CEEE43887BDE71AB977258AE918C32@IRSMSX102.ger.corp.intel.com> References: <20180328135433.20203-1-declan.doherty@intel.com> <20180416130605.6509-1-declan.doherty@intel.com> <20180416130605.6509-7-declan.doherty@intel.com> In-Reply-To: <20180416130605.6509-7-declan.doherty@intel.com> Accept-Language: en-IE, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiZDdiNGY3NzctNzFkMi00YTJiLWFhYmItOWY5ODFhYzc3YzhkIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE2LjUuOS4zIiwiVHJ1c3RlZExhYmVsSGFzaCI6Ik1hZThXb1ozZ1hYV3J6a01qSUhqTE94VWdaZkdvTjhrTGozR3NCN3Fwa1k9In0= x-ctpclassification: CTP_NT dlp-product: dlpe-windows dlp-version: 11.0.200.100 dlp-reaction: no-action x-originating-ip: [163.33.239.181] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dpdk-dev] [PATCH v7 6/9] ethdev: add common devargs parser X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Apr 2018 13:16:48 -0000 > Introduces a new structure, rte_eth_devargs, to support generic > ethdev arguments common across NET PMDs, with a new API > rte_eth_devargs_parse API to support PMD parsing these arguments. >=20 > Signed-off-by: Remy Horton > Signed-off-by: Declan Doherty > --- > lib/Makefile | 1 + > lib/librte_ether/rte_ethdev.c | 195 ++++++++++++++++++++++++++= ++++++ > lib/librte_ether/rte_ethdev_driver.h | 30 +++++ > lib/librte_ether/rte_ethdev_version.map | 1 + > 4 files changed, 227 insertions(+) >=20 > diff --git a/lib/Makefile b/lib/Makefile > index ec965a606..4144d99f9 100644 > --- a/lib/Makefile > +++ b/lib/Makefile > @@ -21,6 +21,7 @@ DEPDIRS-librte_cmdline :=3D librte_eal > DIRS-$(CONFIG_RTE_LIBRTE_ETHER) +=3D librte_ether > DEPDIRS-librte_ether :=3D librte_net librte_eal librte_mempool librte_ri= ng > DEPDIRS-librte_ether +=3D librte_mbuf > +DEPDIRS-librte_ether +=3D librte_kvargs > DIRS-$(CONFIG_RTE_LIBRTE_BBDEV) +=3D librte_bbdev > DEPDIRS-librte_bbdev :=3D librte_eal librte_mempool librte_mbuf > DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) +=3D librte_cryptodev > diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.= c > index 1d38d8e75..a082b211c 100644 > --- a/lib/librte_ether/rte_ethdev.c > +++ b/lib/librte_ether/rte_ethdev.c > @@ -34,6 +34,7 @@ > #include > #include > #include > ++#include >=20 > #include "rte_ether.h" > #include "rte_ethdev.h" > @@ -4149,6 +4150,200 @@ rte_eth_dev_pool_ops_supported(uint16_t port_id, = const char *pool) > return (*dev->dev_ops->pool_ops_supported)(dev, pool); > } >=20 > +typedef int (*rte_eth_devargs_callback_t)(char *str, void *data); > + > +static int > +rte_eth_devargs_tokenise(struct rte_kvargs *arglist, const char *str_in) > +{ > + int state; > + struct rte_kvargs_pair *pair; > + char *letter; Hmm, so that extends rte_kvarrgs to be able to parse something like: "key= =3D[val1,val2,...,valn]", right? If so shouldn't it be in rte_kvargs then? BTW, as I remember rte_kvargs allows you to have multiple identical key, i.= e: "key=3Dval1,key=3Dval2,...,key=3Dvaln". I suppose that approach would allow you to avoid rte_kvargs modifications. > + > + arglist->str =3D strdup(str_in); Who is going to free it? > + if (arglist->str =3D=3D NULL) > + return -ENOMEM; > + > + letter =3D arglist->str; > + state =3D 0; > + arglist->count =3D 0; > + pair =3D &arglist->pairs[0]; > + while (1) { > + switch (state) { > + case 0: /* Initial */ > + if (*letter =3D=3D '=3D') > + return -EINVAL; > + else if (*letter =3D=3D '\0') > + return 0; > + > + state =3D 1; > + pair->key =3D letter; > + /* fall-thru */ > + > + case 1: /* Parsing key */ > + if (*letter =3D=3D '=3D') { > + *letter =3D '\0'; > + pair->value =3D letter + 1; > + state =3D 2; > + } else if (*letter =3D=3D ',' || *letter =3D=3D '\0') > + return -EINVAL; > + break; > + > + > + case 2: /* Parsing value */ > + if (*letter =3D=3D '[') > + state =3D 3; > + else if (*letter =3D=3D ',') { > + *letter =3D '\0'; > + arglist->count++; > + pair =3D &arglist->pairs[arglist->count]; > + state =3D 0; > + } else if (*letter =3D=3D '\0') { > + letter--; > + arglist->count++; > + pair =3D &arglist->pairs[arglist->count]; > + state =3D 0; > + } > + break; > + > + case 3: /* Parsing list */ > + if (*letter =3D=3D ']') > + state =3D 2; > + else if (*letter =3D=3D '\0') > + return -EINVAL; > + break; > + } > + letter++; > + } > +} > + > +static int > +rte_eth_devargs_parse_list(char *str, rte_eth_devargs_callback_t callbac= k, > + void *data) > +{ > + char *str_start; > + int state; > + int result; > + > + if (*str !=3D '[') > + /* Single element, not a list */ > + return callback(str, data); > + > + /* Sanity check, then strip the brackets */ > + str_start =3D &str[strlen(str) - 1]; > + if (*str_start !=3D ']') { > + RTE_LOG(ERR, EAL, "(%s): List does not end with ']'", str); > + return -EINVAL; > + } > + str++; > + *str_start =3D '\0'; > + > + /* Process list elements */ > + state =3D 0; > + while (1) { > + if (state =3D=3D 0) { > + if (*str =3D=3D '\0') > + break; > + if (*str !=3D ',') { > + str_start =3D str; > + state =3D 1; > + } > + } else if (state =3D=3D 1) { > + if (*str =3D=3D ',' || *str =3D=3D '\0') { > + if (str > str_start) { > + /* Non-empty string fragment */ > + *str =3D '\0'; > + result =3D callback(str_start, data); > + if (result < 0) > + return result; > + } > + state =3D 0; > + } > + } > + str++; > + } > + return 0; > +} > + > +static int > +rte_eth_devargs_process_range(char *str, uint16_t *list, uint16_t *len_l= ist, > + const uint16_t max_list) > +{ > + unsigned int lo; > + unsigned int hi; > + unsigned int value; > + int result; > + > + result =3D sscanf(str, "%u-%u", &lo, &hi); Should probably be %hu. And probably check that lo and hi values are less than MAX_PORTS. > + if (result =3D=3D 1) { > + if (*len_list >=3D max_list) > + return -ENOMEM; > + list[(*len_list)++] =3D lo; > + } else if (result =3D=3D 2) { > + if (lo >=3D hi) > + return -EINVAL; > + for (value =3D lo; value <=3D hi; value++) { > + if (*len_list >=3D max_list) > + return -ENOMEM; > + list[(*len_list)++] =3D value; > + } > + } else > + return -EINVAL; > + return 0; > +} > + > +static int > +rte_eth_devargs_parse_ports(char *str, void *data) > +{ > + struct rte_eth_devargs *eth_da =3D data; > + > + return rte_eth_devargs_process_range(str, eth_da->ports, > + ð_da->nb_ports, RTE_MAX_ETHPORTS); > +} > + > + > +static int > +rte_eth_devargs_parse_representor_ports(char *str, void *data) > +{ > + struct rte_eth_devargs *eth_da =3D data; > + > + return rte_eth_devargs_process_range(str, eth_da->representor_ports, > + ð_da->nb_representor_ports, RTE_MAX_ETHPORTS); > +} > + > +int __rte_experimental > +rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_da) > +{ > + struct rte_kvargs args; > + struct rte_kvargs_pair *pair; > + unsigned int i; > + int result; > + > + memset(eth_da, 0, sizeof(*eth_da)); > + > + result =3D rte_eth_devargs_tokenise(&args, dargs); > + if (result < 0) > + return result; > + > + for (i =3D 0; i < args.count; i++) { > + pair =3D &args.pairs[i]; > + > + if (strcmp("port", pair->key) =3D=3D 0) { > + result =3D rte_eth_devargs_parse_list(pair->value, > + rte_eth_devargs_parse_ports, eth_da); > + if (result < 0) > + return result; > + } else if (strcmp("representor", pair->key) =3D=3D 0) { > + result =3D rte_eth_devargs_parse_list(pair->value, > + rte_eth_devargs_parse_representor_ports, > + eth_da); > + if (result < 0) > + return result; > + } > + } > + > + return 0; > +} > + > RTE_INIT(ethdev_init_log); > static void > ethdev_init_log(void) > diff --git a/lib/librte_ether/rte_ethdev_driver.h b/lib/librte_ether/rte_= ethdev_driver.h > index e52add0ad..3bce5747d 100644 > --- a/lib/librte_ether/rte_ethdev_driver.h > +++ b/lib/librte_ether/rte_ethdev_driver.h > @@ -189,6 +189,36 @@ rte_eth_linkstatus_get(const struct rte_eth_dev *dev= , > } >=20 >=20 > +/** Generic Ethernet device arguments */ > +struct rte_eth_devargs { > + uint16_t ports[RTE_MAX_ETHPORTS]; > + /** port/s number to enable on a multi-port single function */ > + uint16_t nb_ports; > + /** number of ports in ports field */ > + uint16_t representor_ports[RTE_MAX_ETHPORTS]; > + /** representor port/s identifier to enable on device */ > + uint16_t nb_representor_ports; > + /** number of ports in representor port field */ > +}; > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change without prior notice. > + * > + * PMD helper function to parse ethdev arguments > + * > + * @param devargs > + * device arguments > + * @param eth_devargs > + * parsed ethdev specific arguments. > + * > + * @return > + * Negative errno value on error, 0 on success. > + */ > +int __rte_experimental > +rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_dev= args); > + > + > typedef int (*ethdev_init_t)(struct rte_eth_dev *ethdev, void *init_para= ms); > typedef int (*ethdev_bus_specific_init)(struct rte_eth_dev *ethdev, > void *bus_specific_init_params); > diff --git a/lib/librte_ether/rte_ethdev_version.map b/lib/librte_ether/r= te_ethdev_version.map > index bd7232923..62ecbdb8a 100644 > --- a/lib/librte_ether/rte_ethdev_version.map > +++ b/lib/librte_ether/rte_ethdev_version.map > @@ -233,6 +233,7 @@ EXPERIMENTAL { > EXPERIMENTAL { > global: >=20 > + rt_eth_devargs_parse; > rte_eth_dev_create; > rte_eth_dev_destroy; >=20 > -- > 2.14.3