From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr0-f193.google.com (mail-wr0-f193.google.com [209.85.128.193]) by dpdk.org (Postfix) with ESMTP id 454C61BAC6 for ; Wed, 11 Apr 2018 02:04:53 +0200 (CEST) Received: by mail-wr0-f193.google.com with SMTP id m13so37919wrj.5 for ; Tue, 10 Apr 2018 17:04:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=Wyco99sQq79qUpnzc/55cP/R5bVwKntIz/JYAi0+Nxw=; b=wuP0Otj2ZSLol/Jojk+53fywJyLMNUXfQxQMFTrjBeyp1U4x8l2ZL7sSCS5TFzdIoP frdRAw1+lJYVoh9IkRtlE8CogTtyAQdLmC4Yvy4Qm2u0sf1aEuDUY+HL1GiRkWHAwVNC JhM9Kh+O9TbuKOL4/0aYu8E7Ae/3qLe8fgVFBGnJ0XBED8wof/6/CLwbNaG6/koIijAk oAWkA1CJxPtzS1Pe9wYP1mTyPp1yeSQp6vH1T9gUri3yN8ytyAgyEUWYnho1mPSw6ZUA Bu/7yD+mt75Aqmdjr2Kdr0chSPYHy6BiZoAs/9s9XoxqmiEAVVhONcNF5p4SZMi//YAu Z4xQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=Wyco99sQq79qUpnzc/55cP/R5bVwKntIz/JYAi0+Nxw=; b=UVBnrUNsqhv+vqBY7TPSXtODcXIXLf5tf6jXtU6itzEC9toHwBBGOm0iHRqr3zsUA3 I1REoXnKKqXziqs4+JpInz5V8tAtfcKnIUHmphiLHzP8DVO/WT/YQT9ihi7hNhvcZVai 7afh7Opt/FmdXusCYaaK8lGqTCoP1s1n/+RELLdXxvx77h3ns3XPbBjz0QKw+KwVjLTr PuzcRXCSV/RwVkuMF+9v35khDFxr+984TSjI+hWzfpFMEwPHvCjkH7xlPYZGUrENVN0h 0MG86KYAUtGVe87gOYFL+ch726g6NVyaeil5c4qEHfyR23jl8eJDvKlOQjL0YXxlyiBn 3UQg== X-Gm-Message-State: ALQs6tDg5i4mdfcJNr15HSaj7g/Zb+IlD0TFNo3xkw7BuX3dRn770GOz 0xM+Tk1piUhC6kl4EwjzBKxJEmDW X-Google-Smtp-Source: AIpwx4/Z4atT/4fvx17sxdl/ORzbB5i/GiovdFNz3UqdTvbcYNK6JM+/rUW4FzOVCIdzu5v0iyUFTA== X-Received: by 10.223.225.198 with SMTP id l6mr1766542wri.111.1523405092578; Tue, 10 Apr 2018 17:04:52 -0700 (PDT) Received: from bidouze.dev.6wind.com. (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id 39sm7626563wry.89.2018.04.10.17.04.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 10 Apr 2018 17:04:51 -0700 (PDT) From: Gaetan Rivet To: dev@dpdk.org Cc: Gaetan Rivet Date: Wed, 11 Apr 2018 02:04:10 +0200 Message-Id: <241cc22846c0e19c10afaaa4f87ee7a85b86ebd1.1523404469.git.gaetan.rivet@6wind.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: References: In-Reply-To: References: Subject: [dpdk-dev] [PATCH v5 09/21] eal/dev: implement device iteration initialization 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: Wed, 11 Apr 2018 00:04:53 -0000 Parse a device description. Split this description in their relevant part for each layers. No dynamic allocation is performed. Signed-off-by: Gaetan Rivet --- lib/Makefile | 1 + lib/librte_eal/bsdapp/eal/Makefile | 1 + lib/librte_eal/common/eal_common_dev.c | 148 ++++++++++++++++++++++++++++++++ lib/librte_eal/common/include/rte_dev.h | 24 ++++++ lib/librte_eal/linuxapp/eal/Makefile | 1 + lib/librte_eal/rte_eal_version.map | 1 + 6 files changed, 176 insertions(+) diff --git a/lib/Makefile b/lib/Makefile index fc7a55a37..1b17526f7 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -6,6 +6,7 @@ include $(RTE_SDK)/mk/rte.vars.mk DIRS-y += librte_compat DIRS-$(CONFIG_RTE_LIBRTE_KVARGS) += librte_kvargs DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal +DEPDIRS-librte_eal := librte_kvargs DIRS-$(CONFIG_RTE_LIBRTE_PCI) += librte_pci DEPDIRS-librte_pci := librte_eal DIRS-$(CONFIG_RTE_LIBRTE_RING) += librte_ring diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile index c7d5abcd9..c13b08ed1 100644 --- a/lib/librte_eal/bsdapp/eal/Makefile +++ b/lib/librte_eal/bsdapp/eal/Makefile @@ -18,6 +18,7 @@ CFLAGS += $(WERROR_FLAGS) -O3 LDLIBS += -lexecinfo LDLIBS += -lpthread LDLIBS += -lgcc_s +LDLIBS += -lrte_kvargs EXPORT_MAP := ../../rte_eal_version.map diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c index cd071442f..1a671758a 100644 --- a/lib/librte_eal/common/eal_common_dev.c +++ b/lib/librte_eal/common/eal_common_dev.c @@ -10,9 +10,12 @@ #include #include +#include #include #include #include +#include +#include #include #include "eal_private.h" @@ -207,3 +210,148 @@ rte_eal_hotplug_remove(const char *busname, const char *devname) rte_eal_devargs_remove(busname, devname); return ret; } + +static size_t +dev_layer_count(const char *s) +{ + size_t i = s ? 1 : 0; + + while (s != NULL && s[0] != '\0') { + i += s[0] == '/'; + s++; + } + return i; +} + +__rte_experimental +int +rte_dev_iterator_init(struct rte_dev_iterator *it, + const char *devstr) +{ + struct { + const char *key; + const char *str; + struct rte_kvargs *kvlist; + } layers[] = { + { "bus=", NULL, NULL, }, + { "class=", NULL, NULL, }, + { "driver=", NULL, NULL, }, + }; + struct rte_kvargs_pair *kv = NULL; + struct rte_class *cls = NULL; + struct rte_bus *bus = NULL; + const char *s = devstr; + size_t nblayer; + size_t i = 0; + + /* Having both busstr and clsstr NULL is illegal, + * marking this iterator as invalid unless + * everything goes well. + */ + it->busstr = NULL; + it->clsstr = NULL; + /* Split each sub-lists. */ + nblayer = dev_layer_count(devstr); + if (nblayer > RTE_DIM(layers)) { + RTE_LOG(ERR, EAL, "Invalid query: too many layers (%zu)\n", + nblayer); + rte_errno = EINVAL; + goto get_out; + } + while (s != NULL) { + char *copy; + char *end; + + if (strncmp(layers[i].key, s, + strlen(layers[i].key))) + goto next_layer; + layers[i].str = s; + copy = strdup(s); + if (copy == NULL) { + RTE_LOG(ERR, EAL, "OOM\n"); + rte_errno = ENOMEM; + goto get_out; + } + end = strchr(copy, '/'); + end = end ? end : strchr(copy, '\0'); + end[0] = '\0'; + layers[i].kvlist = rte_kvargs_parse(copy, NULL); + free(copy); + if (layers[i].kvlist == NULL) { + RTE_LOG(ERR, EAL, "Could not parse %s\n", s); + rte_errno = EINVAL; + goto get_out; + } + s = strchr(s, '/'); + if (s != NULL) + s++; +next_layer: + if (i >= RTE_DIM(layers)) { + RTE_LOG(ERR, EAL, "Unrecognized layer %s\n", s); + rte_errno = EINVAL; + goto get_out; + } + i++; + } + /* Parse each sub-list. */ + for (i = 0; i < RTE_DIM(layers); i++) { + if (layers[i].kvlist == NULL) + continue; + kv = &layers[i].kvlist->pairs[0]; + if (strcmp(kv->key, "bus") == 0) { + bus = rte_bus_find_by_name(kv->value); + if (bus == NULL) { + RTE_LOG(ERR, EAL, "Could not find bus \"%s\"\n", + kv->value); + rte_errno = EFAULT; + goto get_out; + } + } else if (strcmp(kv->key, "class") == 0) { + cls = rte_class_find_by_name(kv->value); + if (cls == NULL) { + RTE_LOG(ERR, EAL, "Could not find class \"%s\"\n", + kv->value); + rte_errno = EFAULT; + goto get_out; + } + } else if (strcmp(kv->key, "driver") == 0) { + /* Ignore */ + continue; + } + } + /* The string should have at least + * one layer specified. + */ + if (bus == NULL && cls == NULL) { + RTE_LOG(ERR, EAL, + "Either bus or class must be specified.\n"); + rte_errno = EINVAL; + goto get_out; + } + if (bus != NULL && bus->dev_iterate == NULL) { + RTE_LOG(ERR, EAL, "Bus %s not supported\n", bus->name); + rte_errno = ENOTSUP; + goto get_out; + } + if (cls != NULL && cls->dev_iterate == NULL) { + RTE_LOG(ERR, EAL, "Class %s not supported\n", cls->name); + rte_errno = ENOTSUP; + goto get_out; + } + /* Fill iterator fields. */ + if (bus != NULL) + it->busstr = layers[0].str; + if (cls != NULL) + it->clsstr = layers[1].str; + it->devstr = devstr; + it->bus = bus; + it->cls = cls; + it->device = NULL; + it->class_device = NULL; +get_out: + for (i = 0; i < RTE_DIM(layers); i++) { + if (layers[i].kvlist) + rte_kvargs_free(layers[i].kvlist); + } + return -rte_errno; +} diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h index 937ff6079..f84128e5c 100644 --- a/lib/librte_eal/common/include/rte_dev.h +++ b/lib/librte_eal/common/include/rte_dev.h @@ -310,6 +310,30 @@ typedef void *(*rte_dev_iterate_t)(const void *start, const char *devstr, const struct rte_dev_iterator *it); +/** + * Initializes a device iterator. + * + * This iterator allows accessing a list of devices matching a criteria. + * The device matching is made among all buses and classes currently registered, + * filtered by the device description given as parameter. + * + * This function will not allocate any memory. It is safe to stop the + * iteration at any moment and let the iterator go out of context. + * + * @param it + * Device iterator handle. + * + * @param str + * Device description string. + * + * @return + * 0 on successful initialization. + * <0 on error. + */ +__rte_experimental +int +rte_dev_iterator_init(struct rte_dev_iterator *it, const char *str); + #ifdef __cplusplus } #endif diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile index 06ab30cad..6fb67bf7f 100644 --- a/lib/librte_eal/linuxapp/eal/Makefile +++ b/lib/librte_eal/linuxapp/eal/Makefile @@ -27,6 +27,7 @@ LDLIBS += -lrt ifeq ($(CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES),y) LDLIBS += -lnuma endif +LDLIBS += -lrte_kvargs # specific to linuxapp exec-env SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) := eal.c diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index afe6ce1b9..cad24376f 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -220,6 +220,7 @@ EXPERIMENTAL { rte_eal_devargs_remove; rte_class_register; rte_class_unregister; + rte_dev_iterator_init; rte_eal_hotplug_add; rte_eal_hotplug_remove; rte_eal_mbuf_user_pool_ops; -- 2.11.0