From patchwork Tue Apr 13 03:14:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xueming Li X-Patchwork-Id: 91158 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: 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]) by inbox.dpdk.org (Postfix) with ESMTP id 74FB6A0524; Tue, 13 Apr 2021 05:15:16 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 602C81609D1; Tue, 13 Apr 2021 05:15:16 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by mails.dpdk.org (Postfix) with ESMTP id 2AB9A1609CE for ; Tue, 13 Apr 2021 05:15:15 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from xuemingl@nvidia.com) with SMTP; 13 Apr 2021 06:15:12 +0300 Received: from nvidia.com (pegasus05.mtr.labs.mlnx [10.210.16.100]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 13D3EQxs015492; Tue, 13 Apr 2021 06:15:12 +0300 From: Xueming Li To: Thomas Monjalon , Gaetan Rivet Cc: dev@dpdk.org, xuemingl@nvidia.com, Asaf Penso Date: Tue, 13 Apr 2021 03:14:11 +0000 Message-Id: <1618283653-16510-5-git-send-email-xuemingl@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1618283653-16510-1-git-send-email-xuemingl@nvidia.com> References: <1618283653-16510-1-git-send-email-xuemingl@nvidia.com> In-Reply-To: <1608304614-13908-2-git-send-email-xuemingl@nvidia.com> References: <1608304614-13908-2-git-send-email-xuemingl@nvidia.com> Subject: [dpdk-dev] [PATCH v5 4/5] bus: add device arguments name parsing API X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" For device probe and iterator, devargs name was key information, parsed by rte_devargs_parse. In legacy parser, devargs name was extracted after bus name: bus:name,kv_arguments,,, Example: pci:83:00.0,arguments,... vdev:pcap0,... To be compatible with legacy parser, this patch introduces new bus driver API devargs_parse to parse devargs and update devargs name. If devargs_parse not implemented by bus driver, the new syntax parser rte_devargs_layers_parse default will resolve devargs name from bus's "name" argument. Different bus driver might choose different keys from arguments with unified format. The PCI bus implementation fills the devargs name with the "addr" argument, example: -a bus=pci,addr=83:00.0/class=eth/driver=mlx5,... name: 0000:03:00.0 -a bus=vdev,name=pcap0/class=eth/driver=pcap,... name:pcap0 Signed-off-by: Xueming Li Reviewed-by: Gaetan Rivet --- drivers/bus/pci/pci_common.c | 1 + drivers/bus/pci/pci_params.c | 47 ++++++++++++++++++++++ drivers/bus/pci/private.h | 14 +++++++ lib/librte_eal/common/eal_common_devargs.c | 31 ++++++++++++++ lib/librte_eal/include/rte_bus.h | 17 ++++++++ 5 files changed, 110 insertions(+) diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c index ee7f966358..30630809bb 100644 --- a/drivers/bus/pci/pci_common.c +++ b/drivers/bus/pci/pci_common.c @@ -760,6 +760,7 @@ struct rte_pci_bus rte_pci_bus = { .dev_iterate = rte_pci_dev_iterate, .hot_unplug_handler = pci_hot_unplug_handler, .sigbus_handler = pci_sigbus_handler, + .devargs_parse = rte_pci_devargs_parse, }, .device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list), .driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list), diff --git a/drivers/bus/pci/pci_params.c b/drivers/bus/pci/pci_params.c index 3192e9c967..c0c282e948 100644 --- a/drivers/bus/pci/pci_params.c +++ b/drivers/bus/pci/pci_params.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include "private.h" @@ -76,3 +78,48 @@ rte_pci_dev_iterate(const void *start, rte_kvargs_free(kvargs); return dev; } + +int +rte_pci_devargs_parse(struct rte_devargs *da) +{ + struct rte_kvargs *kvargs; + const char *addr_str; + struct rte_pci_addr addr; + int ret; + + if (da == NULL) + return 0; + RTE_ASSERT(da->bus_str != NULL); + + kvargs = rte_kvargs_parse(da->bus_str, NULL); + if (kvargs == NULL) { + RTE_LOG(ERR, EAL, "cannot parse argument list: %s\n", + da->bus_str); + ret = -ENODEV; + goto out; + } + + addr_str = rte_kvargs_get(kvargs, pci_params_keys[RTE_PCI_PARAM_ADDR]); + if (addr_str == NULL) { + RTE_LOG(ERR, EAL, "No PCI address specified using '%s=' in: %s\n", + pci_params_keys[RTE_PCI_PARAM_ADDR], da->bus_str); + ret = -ENODEV; + goto out; + } + + ret = rte_pci_addr_parse(addr_str, &addr); + if (ret != 0) { + RTE_LOG(ERR, EAL, "PCI address invalid: %s\n", da->bus_str); + ret = -EINVAL; + goto out; + } + + rte_pci_device_name(&addr, da->name, sizeof(da->name)); + +out: + if (kvargs != NULL) + rte_kvargs_free(kvargs); + if (ret != 0) + rte_errno = -ret; + return ret; +} diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h index f566943f5e..8bc5140e97 100644 --- a/drivers/bus/pci/private.h +++ b/drivers/bus/pci/private.h @@ -267,4 +267,18 @@ rte_pci_dev_iterate(const void *start, const char *str, const struct rte_dev_iterator *it); +/* + * Parse device arguments and update name. + * + * @param da + * device arguments to parse. + * + * @return + * 0 on success. + * -EINVAL: kvargs string is invalid and cannot be parsed. + * -ENODEV: no key matching a device ID is found in the kv list. + */ +int +rte_pci_devargs_parse(struct rte_devargs *da); + #endif /* _PCI_PRIVATE_H_ */ diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c index e40b91ea66..2d87e63d2a 100644 --- a/lib/librte_eal/common/eal_common_devargs.c +++ b/lib/librte_eal/common/eal_common_devargs.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "eal_private.h" /** user device double-linked queue type definition */ @@ -40,6 +41,28 @@ devargs_layer_count(const char *s) return i; } +/* Resolve devargs name from bus arguments. */ +static int +devargs_bus_parse_default(struct rte_devargs *devargs, + struct rte_kvargs *bus_args) +{ + const char *name; + + /* Parse devargs name from bus key-value list. */ + name = rte_kvargs_get(bus_args, "name"); + if (name == NULL) { + RTE_LOG(INFO, EAL, "devargs name not found: %s\n", + devargs->data); + return 0; + } + if (rte_strscpy(devargs->name, name, sizeof(devargs->name)) < 0) { + RTE_LOG(ERR, EAL, "devargs name too long: %s\n", + devargs->data); + return -E2BIG; + } + return 0; +} + int rte_devargs_layers_parse(struct rte_devargs *devargs, const char *devstr) @@ -118,6 +141,8 @@ rte_devargs_layers_parse(struct rte_devargs *devargs, if (layers[i].kvlist == NULL) continue; kv = &layers[i].kvlist->pairs[0]; + if (kv->key == NULL) + continue; if (strcmp(kv->key, "bus") == 0) { bus = rte_bus_find_by_name(kv->value); if (bus == NULL) { @@ -160,6 +185,12 @@ rte_devargs_layers_parse(struct rte_devargs *devargs, } } + /* Resolve devargs name. */ + if (bus != NULL && bus->devargs_parse != NULL) + ret = bus->devargs_parse(devargs); + else if (layers[0].kvlist != NULL) + ret = devargs_bus_parse_default(devargs, layers[0].kvlist); + get_out: for (i = 0; i < RTE_DIM(layers); i++) { if (layers[i].kvlist) diff --git a/lib/librte_eal/include/rte_bus.h b/lib/librte_eal/include/rte_bus.h index 80b154fb98..bfa8dc0200 100644 --- a/lib/librte_eal/include/rte_bus.h +++ b/lib/librte_eal/include/rte_bus.h @@ -210,6 +210,22 @@ typedef int (*rte_bus_hot_unplug_handler_t)(struct rte_device *dev); */ typedef int (*rte_bus_sigbus_handler_t)(const void *failure_addr); +/** + * Parse bus part of the device arguments. + * + * The field name of the struct rte_devargs will be set. + * + * @param da + * Pointer to the devargs to parse. + * + * @return + * 0 on successful parsing, otherwise rte_errno is set. + * -EINVAL: on parsing error. + * -ENODEV: if no key matching a device argument is specified. + * -E2BIG: device name is too long. + */ +typedef int (*rte_bus_devargs_parse_t)(struct rte_devargs *da); + /** * Bus scan policies */ @@ -267,6 +283,7 @@ struct rte_bus { /**< handle hot-unplug failure on the bus */ rte_bus_sigbus_handler_t sigbus_handler; /**< handle sigbus error on the bus */ + rte_bus_devargs_parse_t devargs_parse; /**< Parse bus devargs */ };