From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 99580A0547; Tue, 30 Mar 2021 14:16:24 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 87678140DCF; Tue, 30 Mar 2021 14:16:24 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by mails.dpdk.org (Postfix) with ESMTP id 75BE9406B4 for ; Tue, 30 Mar 2021 14:16:23 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from xuemingl@nvidia.com) with SMTP; 30 Mar 2021 15:16:19 +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 12UCFXhe032518; Tue, 30 Mar 2021 15:16:19 +0300 From: Xueming Li To: Thomas Monjalon , Gaetan Rivet Cc: dev@dpdk.org, xuemingl@nvidia.com, Asaf Penso Date: Tue, 30 Mar 2021 12:15:19 +0000 Message-Id: <1617106521-25931-5-git-send-email-xuemingl@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1617106521-25931-1-git-send-email-xuemingl@nvidia.com> References: <1617106521-25931-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 v3 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" To use Global Device Syntax as devargs, name is required for device management. In legacy parsing API, devargs name was extracted after bus name: bus:name,kv_params,,, To parse new Global Device Syntax, this patch introduces new bus API to parse devargs and update name, different bus driver might choose different keys from parameters with unified formating, 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 --- drivers/bus/pci/pci_common.c | 1 + drivers/bus/pci/pci_params.c | 48 ++++++++++++++++++++++ drivers/bus/pci/private.h | 14 +++++++ drivers/bus/vdev/vdev.c | 1 + drivers/bus/vdev/vdev_params.c | 43 +++++++++++++++++++ drivers/bus/vdev/vdev_private.h | 15 +++++++ lib/librte_eal/common/eal_common_devargs.c | 6 +++ lib/librte_eal/include/rte_bus.h | 19 +++++++++ 8 files changed, 147 insertions(+) diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c index 9b8d769287..61d3f51452 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..7ba9e2650f 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,49 @@ 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)); + + /* TODO: class parse -> driver parse */ +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/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c index d075409942..d6f651bff2 100644 --- a/drivers/bus/vdev/vdev.c +++ b/drivers/bus/vdev/vdev.c @@ -634,6 +634,7 @@ static struct rte_bus rte_vdev_bus = { .dma_unmap = vdev_dma_unmap, .get_iommu_class = vdev_get_iommu_class, .dev_iterate = rte_vdev_dev_iterate, + .devargs_parse = rte_vdev_devargs_parse, }; RTE_REGISTER_BUS(vdev, rte_vdev_bus); diff --git a/drivers/bus/vdev/vdev_params.c b/drivers/bus/vdev/vdev_params.c index 6f74704d1c..3e644ade95 100644 --- a/drivers/bus/vdev/vdev_params.c +++ b/drivers/bus/vdev/vdev_params.c @@ -8,6 +8,9 @@ #include #include #include +#include +#include +#include #include "vdev_logs.h" #include "vdev_private.h" @@ -64,3 +67,43 @@ rte_vdev_dev_iterate(const void *start, rte_kvargs_free(kvargs); return dev; } + +int +rte_vdev_devargs_parse(struct rte_devargs *da) +{ + struct rte_kvargs *kvargs; + const char *name; + int ret = 0; + + 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 = -EINVAL; + goto out; + } + + name = rte_kvargs_get(kvargs, vdev_params_keys[RTE_VDEV_PARAM_NAME]); + if (name == NULL) { + RTE_LOG(ERR, EAL, "name not found: %s\n", da->bus_str); + ret = -ENODEV; + goto out; + } + + if (rte_strscpy(da->name, name, sizeof(da->name)) < 0) { + RTE_LOG(ERR, EAL, "device name is too long: %s\n", name); + ret = -E2BIG; + } + + /* TODO: class parse -> driver parse */ +out: + if (kvargs != NULL) + rte_kvargs_free(kvargs); + if (ret != 0) + rte_errno = -ret; + return ret; +} diff --git a/drivers/bus/vdev/vdev_private.h b/drivers/bus/vdev/vdev_private.h index ba6dc48ff3..257682daac 100644 --- a/drivers/bus/vdev/vdev_private.h +++ b/drivers/bus/vdev/vdev_private.h @@ -19,6 +19,21 @@ rte_vdev_dev_iterate(const void *start, const char *str, const struct rte_dev_iterator *it); +/* + * Parse device argument and update name. + * + * @param da + * device argument 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. + * -E2BIG: device name is too long. + */ +int +rte_vdev_devargs_parse(struct rte_devargs *da); + #ifdef __cplusplus } #endif diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c index e40b91ea66..b4dcb0099c 100644 --- a/lib/librte_eal/common/eal_common_devargs.c +++ b/lib/librte_eal/common/eal_common_devargs.c @@ -118,6 +118,8 @@ rte_devargs_layers_parse(struct rte_devargs *devargs, if (layers[i].kvlist == NULL) continue; kv = &layers[i].kvlist->pairs[0]; + if (!kv->key) + continue; if (strcmp(kv->key, "bus") == 0) { bus = rte_bus_find_by_name(kv->value); if (bus == NULL) { @@ -160,6 +162,10 @@ rte_devargs_layers_parse(struct rte_devargs *devargs, } } + /* Parse device name, optional for iterator filter. */ + if (bus && bus->devargs_parse) + bus->devargs_parse(devargs); + 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..e006b514de 100644 --- a/lib/librte_eal/include/rte_bus.h +++ b/lib/librte_eal/include/rte_bus.h @@ -210,6 +210,24 @@ typedef int (*rte_bus_hot_unplug_handler_t)(struct rte_device *dev); */ typedef int (*rte_bus_sigbus_handler_t)(const void *failure_addr); +/** + * Parse device arguments, setting the device name in the devargs as a result. + * A bus could use the class and driver layers to resolve name furthermore. + * + * On error rte_errno is set. + * + * @param da + * Pointer to the devargs to parse. + * The 'bus_str' field must be set. + * + * @return + * 0 on successful parsing. + * -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 +285,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 device arguments */ }; -- 2.25.1