get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/86808/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 86808,
    "url": "https://patches.dpdk.org/api/patches/86808/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1610983002-7630-3-git-send-email-xuemingl@nvidia.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1610983002-7630-3-git-send-email-xuemingl@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1610983002-7630-3-git-send-email-xuemingl@nvidia.com",
    "date": "2021-01-18T15:16:39",
    "name": "[v2,2/5] devargs: refactor scratch buffer storage",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "9c2f5b66650a7e399ecaf3c13179a79a7f617d94",
    "submitter": {
        "id": 1904,
        "url": "https://patches.dpdk.org/api/people/1904/?format=api",
        "name": "Xueming Li",
        "email": "xuemingl@nvidia.com"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1610983002-7630-3-git-send-email-xuemingl@nvidia.com/mbox/",
    "series": [
        {
            "id": 14815,
            "url": "https://patches.dpdk.org/api/series/14815/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=14815",
            "date": "2021-01-18T15:16:38",
            "name": "eal: enable global device syntax",
            "version": 2,
            "mbox": "https://patches.dpdk.org/series/14815/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/86808/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/86808/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id DCA8EA0A03;\n\tMon, 18 Jan 2021 16:17:05 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 5E9D6140F37;\n\tMon, 18 Jan 2021 16:16:55 +0100 (CET)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by mails.dpdk.org (Postfix) with ESMTP id AD0A7140F2C\n for <dev@dpdk.org>; Mon, 18 Jan 2021 16:16:50 +0100 (CET)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n xuemingl@nvidia.com) with SMTP; 18 Jan 2021 17:16:49 +0200",
            "from nvidia.com (pegasus05.mtr.labs.mlnx [10.210.16.100])\n by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 10IFGmBn002238;\n Mon, 18 Jan 2021 17:16:48 +0200"
        ],
        "From": "Xueming Li <xuemingl@nvidia.com>",
        "To": "Thomas Monjalon <thomas@monjalon.net>,\n Ferruh Yigit <ferruh.yigit@intel.com>,\n Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>,\n Olivier Matz <olivier.matz@6wind.com>",
        "Cc": "dev@dpdk.org, Viacheslav Ovsiienko <viacheslavo@nvidia.com>,\n xuemingl@nvidia.com, Asaf Penso <asafp@nvidia.com>",
        "Date": "Mon, 18 Jan 2021 15:16:39 +0000",
        "Message-Id": "<1610983002-7630-3-git-send-email-xuemingl@nvidia.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": [
            "<1610983002-7630-1-git-send-email-xuemingl@nvidia.com>",
            "<1608304614-13908-2-git-send-email-xuemingl@nvidia.com>"
        ],
        "References": [
            "<1610983002-7630-1-git-send-email-xuemingl@nvidia.com>",
            "<1608304614-13908-2-git-send-email-xuemingl@nvidia.com>"
        ],
        "Subject": "[dpdk-dev] [PATCH v2 2/5] devargs: refactor scratch buffer storage",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "In current design, legacy parser rte_devargs_parse() saved scratch\nbuffer to devargs.args while new parser rte_devargs_layers_parse() saved\nto devargs.data. Code using devargs had to know the difference and\ncleaned up memory accordingly - error prone.\n\nThis patch unifies data the dedicate scratch buffer, introduces\nrte_devargs_free() function to wrap the memory memory clean up.\n\nSigned-off-by: Xueming Li <xuemingl@nvidia.com>\n---\n app/test-pmd/config.c                        |  7 ++--\n app/test-pmd/testpmd.c                       |  5 ++-\n drivers/bus/vdev/vdev.c                      |  9 ++--\n drivers/net/failsafe/failsafe_args.c         |  3 +-\n drivers/net/failsafe/failsafe_eal.c          |  2 +-\n examples/multi_process/hotplug_mp/commands.c |  6 +--\n lib/librte_eal/common/eal_common_dev.c       |  9 ++--\n lib/librte_eal/common/eal_common_devargs.c   | 43 +++++++++++---------\n lib/librte_eal/common/hotplug_mp.c           |  6 +--\n lib/librte_eal/include/rte_devargs.h         | 18 ++++++--\n lib/librte_eal/rte_eal_exports.def           |  1 +\n lib/librte_eal/version.map                   |  1 +\n lib/librte_ethdev/rte_ethdev.c               |  7 ++--\n 13 files changed, 64 insertions(+), 53 deletions(-)",
    "diff": "diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c\nindex 3f6c8642b1..21bdece399 100644\n--- a/app/test-pmd/config.c\n+++ b/app/test-pmd/config.c\n@@ -509,8 +509,6 @@ device_infos_display(const char *identifier)\n \n \tif (rte_devargs_parsef(&da, \"%s\", identifier)) {\n \t\tprintf(\"cannot parse identifier\\n\");\n-\t\tif (da.args)\n-\t\t\tfree(da.args);\n \t\treturn;\n \t}\n \n@@ -558,6 +556,7 @@ device_infos_display(const char *identifier)\n \t\t\t}\n \t\t}\n \t};\n+\trte_devargs_free(&da);\n }\n \n void\n@@ -602,8 +601,8 @@ port_infos_display(portid_t port_id)\n \telse\n \t\tprintf(\"\\nFirmware-version: %s\", \"not available\");\n \n-\tif (dev_info.device->devargs && dev_info.device->devargs->args)\n-\t\tprintf(\"\\nDevargs: %s\", dev_info.device->devargs->args);\n+\tif (dev_info.device->devargs && dev_info.device->devargs->src)\n+\t\tprintf(\"\\nDevargs: %s\", dev_info.device->devargs->src);\n \tprintf(\"\\nConnect to socket: %u\", port->socket_id);\n \n \tif (port_numa[port_id] != NUMA_NO_CONFIG) {\ndiff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c\nindex 2b60f6c5d3..ea27779bfd 100644\n--- a/app/test-pmd/testpmd.c\n+++ b/app/test-pmd/testpmd.c\n@@ -2987,8 +2987,6 @@ detach_devargs(char *identifier)\n \tmemset(&da, 0, sizeof(da));\n \tif (rte_devargs_parsef(&da, \"%s\", identifier)) {\n \t\tprintf(\"cannot parse identifier\\n\");\n-\t\tif (da.args)\n-\t\t\tfree(da.args);\n \t\treturn;\n \t}\n \n@@ -2997,6 +2995,7 @@ detach_devargs(char *identifier)\n \t\t\tif (ports[port_id].port_status != RTE_PORT_STOPPED) {\n \t\t\t\tprintf(\"Port %u not stopped\\n\", port_id);\n \t\t\t\trte_eth_iterator_cleanup(&iterator);\n+\t\t\t\trte_devargs_free(&da);\n \t\t\t\treturn;\n \t\t\t}\n \t\t\tport_flow_flush(port_id);\n@@ -3006,6 +3005,7 @@ detach_devargs(char *identifier)\n \tif (rte_eal_hotplug_remove(da.bus->name, da.name) != 0) {\n \t\tTESTPMD_LOG(ERR, \"Failed to detach device %s(%s)\\n\",\n \t\t\t    da.name, da.bus->name);\n+\t\trte_devargs_free(&da);\n \t\treturn;\n \t}\n \n@@ -3014,6 +3014,7 @@ detach_devargs(char *identifier)\n \tprintf(\"Device %s is detached\\n\", identifier);\n \tprintf(\"Now total ports is %d\\n\", nb_ports);\n \tprintf(\"Done\\n\");\n+\trte_devargs_free(&da);\n }\n \n void\ndiff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c\nindex acfd78828f..012326d809 100644\n--- a/drivers/bus/vdev/vdev.c\n+++ b/drivers/bus/vdev/vdev.c\n@@ -236,13 +236,14 @@ alloc_devargs(const char *name, const char *args)\n \n \tdevargs->bus = &rte_vdev_bus;\n \tif (args)\n-\t\tdevargs->args = strdup(args);\n+\t\tdevargs->data = strdup(args);\n \telse\n-\t\tdevargs->args = strdup(\"\");\n+\t\tdevargs->data = strdup(\"\");\n+\tdevargs->args = devargs->data;\n \n \tret = strlcpy(devargs->name, name, sizeof(devargs->name));\n \tif (ret < 0 || ret >= (int)sizeof(devargs->name)) {\n-\t\tfree(devargs->args);\n+\t\trte_devargs_free(devargs);\n \t\tfree(devargs);\n \t\treturn NULL;\n \t}\n@@ -296,7 +297,7 @@ insert_vdev(const char *name, const char *args,\n \n \treturn 0;\n fail:\n-\tfree(devargs->args);\n+\trte_devargs_free(devargs);\n \tfree(devargs);\n \tfree(dev);\n \treturn ret;\ndiff --git a/drivers/net/failsafe/failsafe_args.c b/drivers/net/failsafe/failsafe_args.c\nindex 707490b94c..52fdcb977f 100644\n--- a/drivers/net/failsafe/failsafe_args.c\n+++ b/drivers/net/failsafe/failsafe_args.c\n@@ -451,8 +451,7 @@ failsafe_args_free(struct rte_eth_dev *dev)\n \t\tsdev->cmdline = NULL;\n \t\tfree(sdev->fd_str);\n \t\tsdev->fd_str = NULL;\n-\t\tfree(sdev->devargs.args);\n-\t\tsdev->devargs.args = NULL;\n+\t\trte_devargs_free(&sdev->devargs);\n \t}\n }\n \ndiff --git a/drivers/net/failsafe/failsafe_eal.c b/drivers/net/failsafe/failsafe_eal.c\nindex b9fc508673..3a4d8c835a 100644\n--- a/drivers/net/failsafe/failsafe_eal.c\n+++ b/drivers/net/failsafe/failsafe_eal.c\n@@ -79,7 +79,7 @@ fs_bus_init(struct rte_eth_dev *dev)\n \t\t\t\t\trte_eth_devices[pid].device->devargs;\n \n \t\t\t/* Take control of probed device. */\n-\t\t\tfree(da->args);\n+\t\t\trte_devargs_free(da);\n \t\t\tmemset(da, 0, sizeof(*da));\n \t\t\tif (probed_da != NULL)\n \t\t\t\tsnprintf(devstr, sizeof(devstr), \"%s,%s\",\ndiff --git a/examples/multi_process/hotplug_mp/commands.c b/examples/multi_process/hotplug_mp/commands.c\nindex a8a39d07f7..e593cad56c 100644\n--- a/examples/multi_process/hotplug_mp/commands.c\n+++ b/examples/multi_process/hotplug_mp/commands.c\n@@ -121,8 +121,6 @@ static void cmd_dev_attach_parsed(void *parsed_result,\n \n \tif (rte_devargs_parsef(&da, \"%s\", res->devargs)) {\n \t\tcmdline_printf(cl, \"cannot parse devargs\\n\");\n-\t\tif (da.args)\n-\t\t\tfree(da.args);\n \t\treturn;\n \t}\n \n@@ -131,6 +129,7 @@ static void cmd_dev_attach_parsed(void *parsed_result,\n \telse\n \t\tcmdline_printf(cl, \"failed to attached device %s\\n\",\n \t\t\t\tda.name);\n+\trte_devargs_free(&da);\n }\n \n cmdline_parse_token_string_t cmd_dev_attach_attach =\n@@ -168,8 +167,6 @@ static void cmd_dev_detach_parsed(void *parsed_result,\n \n \tif (rte_devargs_parsef(&da, \"%s\", res->devargs)) {\n \t\tcmdline_printf(cl, \"cannot parse devargs\\n\");\n-\t\tif (da.args)\n-\t\t\tfree(da.args);\n \t\treturn;\n \t}\n \n@@ -180,6 +177,7 @@ static void cmd_dev_detach_parsed(void *parsed_result,\n \telse\n \t\tcmdline_printf(cl, \"failed to dettach device %s\\n\",\n \t\t\tda.name);\n+\trte_devargs_free(&da);\n }\n \n cmdline_parse_token_string_t cmd_dev_detach_detach =\ndiff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c\nindex 8a3bd3100a..4b4d589f64 100644\n--- a/lib/librte_eal/common/eal_common_dev.c\n+++ b/lib/librte_eal/common/eal_common_dev.c\n@@ -185,10 +185,8 @@ local_dev_probe(const char *devargs, struct rte_device **new_dev)\n \treturn ret;\n \n err_devarg:\n-\tif (rte_devargs_remove(da) != 0) {\n-\t\tfree(da->args);\n-\t\tfree(da);\n-\t}\n+\tif (rte_devargs_remove(da) != 0)\n+\t\trte_devargs_free(da);\n \treturn ret;\n }\n \n@@ -586,7 +584,7 @@ rte_dev_iterator_init(struct rte_dev_iterator *it,\n \tit->bus_str = NULL;\n \tit->cls_str = NULL;\n \n-\tdevargs.data = dev_str;\n+\tdevargs.data = (void *)(intptr_t)dev_str;\n \tif (rte_devargs_layers_parse(&devargs, dev_str))\n \t\tgoto get_out;\n \n@@ -619,6 +617,7 @@ rte_dev_iterator_init(struct rte_dev_iterator *it,\n \tit->device = NULL;\n \tit->class_device = NULL;\n get_out:\n+\trte_devargs_free(&devargs);\n \treturn -rte_errno;\n }\n \ndiff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c\nindex c3969ff158..9c7a7de30e 100644\n--- a/lib/librte_eal/common/eal_common_devargs.c\n+++ b/lib/librte_eal/common/eal_common_devargs.c\n@@ -144,13 +144,14 @@ rte_devargs_layers_parse(struct rte_devargs *devargs,\n \tdevargs->drv_str = layers[2].str;\n \tdevargs->bus = bus;\n \tdevargs->cls = cls;\n+\tdevargs->src = devstr;\n \n \t/* If we own the data, clean up a bit\n \t * the several layers string, to ease\n \t * their parsing afterward.\n \t */\n \tif (devargs->data != devstr) {\n-\t\tchar *s = (void *)(intptr_t)(devargs->data);\n+\t\tchar *s = devargs->data;\n \n \t\twhile ((s = strchr(s, '/'))) {\n \t\t\t*s = '\\0';\n@@ -164,12 +165,8 @@ rte_devargs_layers_parse(struct rte_devargs *devargs,\n \t\t\trte_kvargs_free(layers[i].kvlist);\n \t}\n \tif (ret != 0) {\n-\t\tif (devargs->data && devargs->data != devstr) {\n-\t\t\t/* Free duplicated data. */\n-\t\t\tfree(devargs->data);\n-\t\t\tdevargs->data = NULL;\n-\t\t}\n \t\trte_errno = -ret;\n+\t\trte_devargs_free(devargs);\n \t}\n \treturn ret;\n }\n@@ -225,13 +222,17 @@ rte_devargs_parse(struct rte_devargs *da, const char *dev)\n \tda->bus = bus;\n \t/* Parse eventual device arguments */\n \tif (devname[i] == ',')\n-\t\tda->args = strdup(&devname[i + 1]);\n+\t\tda->data = strdup(&devname[i + 1]);\n \telse\n-\t\tda->args = strdup(\"\");\n-\tif (da->args == NULL) {\n+\t\tda->data = strdup(\"\");\n+\tif (da->data == NULL) {\n \t\tRTE_LOG(ERR, EAL, \"not enough memory to parse arguments\\n\");\n \t\treturn -ENOMEM;\n \t}\n+\tda->drv_str = da->data;\n+\n+\tda->src = dev;\n+\n \treturn 0;\n }\n \n@@ -266,6 +267,15 @@ rte_devargs_parsef(struct rte_devargs *da, const char *format, ...)\n \treturn ret;\n }\n \n+void\n+rte_devargs_free(struct rte_devargs *da)\n+{\n+\tif (da && da->data && da->data != da->src)\n+\t\tfree(da->data);\n+\tda->data = NULL;\n+\tda->src = NULL;\n+}\n+\n int\n rte_devargs_insert(struct rte_devargs **da)\n {\n@@ -282,15 +292,8 @@ rte_devargs_insert(struct rte_devargs **da)\n \t\tif (strcmp(listed_da->bus->name, (*da)->bus->name) == 0 &&\n \t\t\t\tstrcmp(listed_da->name, (*da)->name) == 0) {\n \t\t\t/* device already in devargs list, must be updated */\n-\t\t\tlisted_da->type = (*da)->type;\n-\t\t\tlisted_da->policy = (*da)->policy;\n-\t\t\tfree(listed_da->args);\n-\t\t\tlisted_da->args = (*da)->args;\n-\t\t\tlisted_da->bus = (*da)->bus;\n-\t\t\tlisted_da->cls = (*da)->cls;\n-\t\t\tlisted_da->bus_str = (*da)->bus_str;\n-\t\t\tlisted_da->cls_str = (*da)->cls_str;\n-\t\t\tlisted_da->data = (*da)->data;\n+\t\t\trte_devargs_free(listed_da);\n+\t\t\t*listed_da = **da;\n \t\t\t/* replace provided devargs with found one */\n \t\t\tfree(*da);\n \t\t\t*da = listed_da;\n@@ -332,7 +335,7 @@ rte_devargs_add(enum rte_devtype devtype, const char *devargs_str)\n \n fail:\n \tif (devargs) {\n-\t\tfree(devargs->args);\n+\t\trte_devargs_free(devargs);\n \t\tfree(devargs);\n \t}\n \n@@ -352,7 +355,7 @@ rte_devargs_remove(struct rte_devargs *devargs)\n \t\tif (strcmp(d->bus->name, devargs->bus->name) == 0 &&\n \t\t    strcmp(d->name, devargs->name) == 0) {\n \t\t\tTAILQ_REMOVE(&devargs_list, d, next);\n-\t\t\tfree(d->args);\n+\t\t\trte_devargs_free(d);\n \t\t\tfree(d);\n \t\t\treturn 0;\n \t\t}\ndiff --git a/lib/librte_eal/common/hotplug_mp.c b/lib/librte_eal/common/hotplug_mp.c\nindex ee791903b3..13f2a427cf 100644\n--- a/lib/librte_eal/common/hotplug_mp.c\n+++ b/lib/librte_eal/common/hotplug_mp.c\n@@ -95,6 +95,7 @@ __handle_secondary_request(void *param)\n \n \ttmp_req = *req;\n \n+\tmemset(&da, 0, sizeof(da));\n \tif (req->t == EAL_DEV_REQ_TYPE_ATTACH) {\n \t\tret = local_dev_probe(req->devargs, &dev);\n \t\tif (ret != 0) {\n@@ -118,8 +119,6 @@ __handle_secondary_request(void *param)\n \t\tret = rte_devargs_parse(&da, req->devargs);\n \t\tif (ret != 0)\n \t\t\tgoto finish;\n-\t\tfree(da.args); /* we don't need those */\n-\t\tda.args = NULL;\n \n \t\tret = eal_dev_hotplug_request_to_secondary(&tmp_req);\n \t\tif (ret != 0) {\n@@ -176,6 +175,7 @@ __handle_secondary_request(void *param)\n \tif (ret)\n \t\tRTE_LOG(ERR, EAL, \"failed to send response to secondary\\n\");\n \n+\trte_devargs_free(&da);\n \tfree(bundle->peer);\n \tfree(bundle);\n }\n@@ -283,7 +283,7 @@ static void __handle_primary_request(void *param)\n \n \t\tret = local_dev_remove(dev);\n quit:\n-\t\tfree(da->args);\n+\t\trte_devargs_free(da);\n \t\tfree(da);\n \t\tbreak;\n \tdefault:\ndiff --git a/lib/librte_eal/include/rte_devargs.h b/lib/librte_eal/include/rte_devargs.h\nindex 296f19324f..4a917a266b 100644\n--- a/lib/librte_eal/include/rte_devargs.h\n+++ b/lib/librte_eal/include/rte_devargs.h\n@@ -60,16 +60,16 @@ struct rte_devargs {\n \t/** Name of the device. */\n \tchar name[RTE_DEV_NAME_MAX_LEN];\n \tRTE_STD_C11\n-\tunion {\n-\t/** Arguments string as given by user or \"\" for no argument. */\n-\t\tchar *args;\n+\tunion { /**< driver-related part of device string. */\n+\t\tconst char *args; /**< legacy name. */\n \t\tconst char *drv_str;\n \t};\n \tstruct rte_bus *bus; /**< bus handle. */\n \tstruct rte_class *cls; /**< class handle. */\n \tconst char *bus_str; /**< bus-related part of device string. */\n \tconst char *cls_str; /**< class-related part of device string. */\n-\tconst char *data; /**< Device string storage. */\n+\tchar *data; /**< Scratch buffer. */\n+\tconst char *src; /**< Arguments given by user. */\n };\n \n /**\n@@ -145,6 +145,16 @@ rte_devargs_parsef(struct rte_devargs *da,\n \t\t   const char *format, ...)\n __rte_format_printf(2, 0);\n \n+/**\n+ * Free resources in devargs.\n+ *\n+ * @param da\n+ *   The devargs structure holding the device information.\n+ */\n+__rte_experimental\n+void\n+rte_devargs_free(struct rte_devargs *da);\n+\n /**\n  * Insert an rte_devargs in the global list.\n  *\ndiff --git a/lib/librte_eal/rte_eal_exports.def b/lib/librte_eal/rte_eal_exports.def\nindex fe27bffe45..6fb1aaf8a8 100644\n--- a/lib/librte_eal/rte_eal_exports.def\n+++ b/lib/librte_eal/rte_eal_exports.def\n@@ -29,6 +29,7 @@ EXPORTS\n \trte_devargs_next\n \trte_devargs_parse\n \trte_devargs_parsef\n+\trte_devargs_free\n \trte_devargs_remove\n \trte_devargs_type_count\n \trte_dump_physmem_layout\ndiff --git a/lib/librte_eal/version.map b/lib/librte_eal/version.map\nindex b1db7ec795..ef388a30a1 100644\n--- a/lib/librte_eal/version.map\n+++ b/lib/librte_eal/version.map\n@@ -409,6 +409,7 @@ EXPERIMENTAL {\n \trte_thread_tls_key_delete;\n \trte_thread_tls_value_get;\n \trte_thread_tls_value_set;\n+\trte_devargs_free;\n };\n \n INTERNAL {\ndiff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c\nindex 17ddacc78d..325e7693eb 100644\n--- a/lib/librte_ethdev/rte_ethdev.c\n+++ b/lib/librte_ethdev/rte_ethdev.c\n@@ -193,13 +193,14 @@ int\n rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)\n {\n \tint ret;\n-\tstruct rte_devargs devargs = {.args = NULL};\n+\tstruct rte_devargs devargs;\n \tconst char *bus_param_key;\n \tchar *bus_str = NULL;\n \tchar *cls_str = NULL;\n \tint str_size;\n \n \tmemset(iter, 0, sizeof(*iter));\n+\tmemset(&devargs, 0, sizeof(devargs));\n \n \t/*\n \t * The devargs string may use various syntaxes:\n@@ -244,8 +245,6 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)\n \t\tgoto error;\n \t}\n \titer->cls_str = cls_str;\n-\tfree(devargs.args); /* allocated by rte_devargs_parse() */\n-\tdevargs.args = NULL;\n \n \titer->bus = devargs.bus;\n \tif (iter->bus->dev_iterate == NULL) {\n@@ -284,7 +283,7 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)\n \tif (ret == -ENOTSUP)\n \t\tRTE_ETHDEV_LOG(ERR, \"Bus %s does not support iterating.\\n\",\n \t\t\t\titer->bus->name);\n-\tfree(devargs.args);\n+\trte_devargs_free(&devargs);\n \tfree(bus_str);\n \tfree(cls_str);\n \treturn ret;\n",
    "prefixes": [
        "v2",
        "2/5"
    ]
}