[dpdk-dev] [PATCH v2 08/18] eal/dev: implement device iteration initialization

Gaetan Rivet gaetan.rivet at 6wind.com
Wed Mar 21 18:15:29 CET 2018


Parse a device description.

Split this description in their relevant part for both abstraction
layer.

No dynamic allocation is performed.

Signed-off-by: Gaetan Rivet <gaetan.rivet at 6wind.com>
---
 lib/librte_eal/common/eal_common_dev.c  | 58 +++++++++++++++++++++++++++++++++
 lib/librte_eal/common/include/rte_dev.h | 23 +++++++++++++
 lib/librte_eal/rte_eal_version.map      |  1 +
 3 files changed, 82 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 4032f1bd8..bdab1423a 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -10,6 +10,7 @@
 
 #include <rte_compat.h>
 #include <rte_bus.h>
+#include <rte_class.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_debug.h>
@@ -245,3 +246,60 @@ rte_eal_hotplug_remove(const char *busname, const char *devname)
 	rte_eal_devargs_remove(busname, devname);
 	return ret;
 }
+
+int __rte_experimental
+rte_dev_iterator_init(struct rte_dev_iterator *it, const char *str)
+{
+	struct rte_bus *bus = NULL;
+	struct rte_class *cls = NULL;
+	struct rte_kvarg kv;
+
+	/* Having both busstr and clsstr NULL is illegal,
+	 * marking this iterator as invalid unless
+	 * everything goes well.
+	 */
+	it->busstr = NULL;
+	it->clsstr = NULL;
+	/* Safety checks and prep-work */
+	if (rte_parse_kv(str, &kv)) {
+		RTE_LOG(ERR, EAL, "Could not parse: %s\n", str);
+		return -1;
+	}
+	it->device = NULL;
+	it->class_device = NULL;
+	if (strcmp(kv.key, "bus") == 0) {
+		char *slash;
+
+		bus = rte_bus_find_by_name(kv.value);
+		it->busstr = str;
+		slash = strchr(str, '/');
+		if (slash != NULL) {
+			if (rte_parse_kv(slash + 1, &kv))
+				return -1;
+			cls = rte_class_find_by_name(kv.value);
+			it->clsstr = slash + 1;
+		}
+	} else if (strcmp(kv.key, "class") == 0) {
+		cls = rte_class_find_by_name(kv.value);
+		it->clsstr = str;
+	} else {
+		rte_errno = EINVAL;
+		return -rte_errno;
+	}
+	/* The string should have at least
+	 * one layer specified.
+	 */
+	if (bus == NULL && cls == NULL) {
+		rte_errno = EINVAL;
+		return -rte_errno;
+	}
+	if ((bus != NULL && bus->dev_iterate == NULL) ||
+	    (cls != NULL && cls->dev_iterate == NULL)) {
+		rte_errno = ENOTSUP;
+		return -rte_errno;
+	}
+	it->devstr = str;
+	it->bus = bus;
+	it->cls = cls;
+	return 0;
+}
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 937ff6079..7ce13e068 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -310,6 +310,29 @@ 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.
+ */
+int __rte_experimental
+rte_dev_iterator_init(struct rte_dev_iterator *it, const char *str);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 910cb23c9..921da3075 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -228,6 +228,7 @@ EXPERIMENTAL {
 	rte_mp_sendmsg;
 	rte_mp_request;
 	rte_mp_reply;
+	rte_dev_iterator_init;
 	rte_service_attr_get;
 	rte_service_attr_reset_all;
 	rte_service_component_register;
-- 
2.11.0



More information about the dev mailing list