Skip to contentSkip to conversation

dfs:add FUSE based filesystem for DPDK

PATCH Superseded Keith Wiles 2 participants 15 messages Dec 16, 2018 – Dec 27, 2018

Subsystems (2)

v2 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/3 dfs:add FUSE based filesystem for DPDK

DFS stands for DPDK Filesystem, which helps expose data and control files in a FUSE based filesystem. The dfs requires libfuse3 and libjansson to be present in the Linux system.

DFS provides a simplified API on top of the FUSE APIs to simplify creating and using FUSE.

Here is the github repo: https://github.com/akheron/jansson
Here is the github repo: https://github.com/libfuse/libfuse

Please use you system updater tool yum, apt-get, ... to add support for these two libraries. Also read the dfs documentation in the docs directory for more details.

The DFS is only setup for Linux at this time with FreeBSD and windows support coming later.

---
v2
fix checkpath warnings.

 MAINTAINERS                        |   5 +
 config/common_linuxapp             |   5 +
 doc/guides/prog_guide/dfs_lib.rst  | 660 ++++++++++++++++++++++
 doc/guides/prog_guide/index.rst    |   1 +
 examples/Makefile                  |   1 +
 examples/dfs/Makefile              |  70 +++
 examples/dfs/main.c                |  86 +++
 examples/dfs/meson.build           |  13 +
 lib/Makefile                       |   2 +
 lib/librte_dfs/Makefile            |  51 ++
 lib/librte_dfs/dfs.c               | 842 +++++++++++++++++++++++++++++
 lib/librte_dfs/dfs.h               | 768 ++++++++++++++++++++++++++
 lib/librte_dfs/dfs_cryptodev.c     |  53 ++
 lib/librte_dfs/dfs_cryptodev.h     |  25 +
 lib/librte_dfs/dfs_dpdk.c          | 323 +++++++++++
 lib/librte_dfs/dfs_dpdk.h          |  37 ++
 lib/librte_dfs/dfs_eal.c           | 652 ++++++++++++++++++++++
 lib/librte_dfs/dfs_eal.h           | 102 ++++
 lib/librte_dfs/dfs_ethdev.c        | 324 +++++++++++
 lib/librte_dfs/dfs_ethdev.h        |  23 +
 lib/librte_dfs/dfs_mempool.c       | 130 +++++
 lib/librte_dfs/dfs_mempool.h       |  26 +
 lib/librte_dfs/dfs_noop.c          |  35 ++
 lib/librte_dfs/dfs_oper.c          | 836 ++++++++++++++++++++++++++++
 lib/librte_dfs/dfs_oper.h          |  48 ++
 lib/librte_dfs/dfs_rawdev.c        |  54 ++
 lib/librte_dfs/dfs_rawdev.h        |  25 +
 lib/librte_dfs/dfs_ring.c          | 107 ++++
 lib/librte_dfs/dfs_ring.h          |  25 +
 lib/librte_dfs/dfs_search.c        | 203 +++++++
 lib/librte_dfs/dfs_search.h        | 266 +++++++++
 lib/librte_dfs/dfs_timer.c         |  58 ++
 lib/librte_dfs/dfs_timer.h         |  25 +
 lib/librte_dfs/meson.build         |  47 ++
 lib/librte_dfs/rte_dfs_version.map |  29 +
 lib/meson.build                    |   2 +-
 mk/rte.app.mk                      |   3 +
 37 files changed, 5961 insertions(+), 1 deletion(-)
 create mode 100644 doc/guides/prog_guide/dfs_lib.rst
 create mode 100644 examples/dfs/Makefile
 create mode 100644 examples/dfs/main.c
 create mode 100644 examples/dfs/meson.build
 create mode 100644 lib/librte_dfs/Makefile
 create mode 100644 lib/librte_dfs/dfs.c
 create mode 100644 lib/librte_dfs/dfs.h
 create mode 100644 lib/librte_dfs/dfs_cryptodev.c
 create mode 100644 lib/librte_dfs/dfs_cryptodev.h
 create mode 100644 lib/librte_dfs/dfs_dpdk.c
 create mode 100644 lib/librte_dfs/dfs_dpdk.h
 create mode 100644 lib/librte_dfs/dfs_eal.c
 create mode 100644 lib/librte_dfs/dfs_eal.h
 create mode 100644 lib/librte_dfs/dfs_ethdev.c
 create mode 100644 lib/librte_dfs/dfs_ethdev.h
 create mode 100644 lib/librte_dfs/dfs_mempool.c
 create mode 100644 lib/librte_dfs/dfs_mempool.h
 create mode 100644 lib/librte_dfs/dfs_noop.c
 create mode 100644 lib/librte_dfs/dfs_oper.c
 create mode 100644 lib/librte_dfs/dfs_oper.h
 create mode 100644 lib/librte_dfs/dfs_rawdev.c
 create mode 100644 lib/librte_dfs/dfs_rawdev.h
 create mode 100644 lib/librte_dfs/dfs_ring.c
 create mode 100644 lib/librte_dfs/dfs_ring.h
 create mode 100644 lib/librte_dfs/dfs_search.c
 create mode 100644 lib/librte_dfs/dfs_search.h
 create mode 100644 lib/librte_dfs/dfs_timer.c
 create mode 100644 lib/librte_dfs/dfs_timer.h
 create mode 100644 lib/librte_dfs/meson.build
 create mode 100644 lib/librte_dfs/rte_dfs_version.map
MAINTAINERS +5 -0
index 71ba31208..e555ec5b7 100644
@@ -1215,6 +1215,11 @@ F: test/bpf/
 F: test/test/test_bpf.c
 F: doc/guides/prog_guide/bpf_lib.rst
 
+DFS - EXPERIMENTAL
+M: Keith Wiles <[email protected]>
+F: lib/librte_dfs
+F: examples/dfs
+F: doc/guides/prog_guide/dfs_lib.rst
 
 Test Applications
 -----------------
config/common_linuxapp +5 -0
index 6c1c8d0f4..70f55508e 100644
@@ -56,3 +56,8 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=y
 # NXP ENETC PMD Driver
 #
 CONFIG_RTE_LIBRTE_ENETC_PMD=y
+
+#
+# DPDK File System (DFS) enable building.
+#
+CONFIG_RTE_LIBRTE_DFS=n
doc/guides/prog_guide/dfs_lib.rst new file +660 -0

660 lines not on this page · raw message

doc/guides/prog_guide/index.rst +1 -0
index ba8c1f6ad..0f1d21605 100644
@@ -54,6 +54,7 @@ Programmer's Guide
     vhost_lib
     metrics_lib
     bpf_lib
+    dfs_lib
     source_org
     dev_kit_build_system
     dev_kit_root_make_help
examples/Makefile +1 -0
index 33fe0e586..cfe2279e8 100644
@@ -14,6 +14,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_BBDEV) += bbdev_app
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += bond
 DIRS-y += cmdline
 DIRS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += distributor
+DIRS-$(CONFIG_RTE_LIBRTE_DFS) += dfs
 DIRS-y += ethtool
 DIRS-y += exception_path
 DIRS-$(CONFIG_RTE_LIBRTE_EFD) += server_node_efd
examples/dfs/Makefile new file +70 -0

70 lines not on this page · raw message

examples/dfs/main.c new file +86 -0

86 lines not on this page · raw message

examples/dfs/meson.build new file +13 -0
new file mode 100644
index 000000000..5923f8957
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2018 Intel Corporation
+
+# meson file, for building this example as part of a main DPDK build.
+#
+# To build this example as a standalone application with an already-installed
+# DPDK instance, use 'make'
+
+allow_experimental_apis = true
+sources = files(
+	'main.c'
+)
+deps += [ 'dfs' ]
lib/Makefile +2 -0
index b7370ef97..ae6de9bd5 100644
@@ -21,6 +21,8 @@ DEPDIRS-librte_timer := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
 DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline
 DEPDIRS-librte_cmdline := librte_eal
+DIRS-y += librte_dfs
+DEPDIRS-librte_dfs := librte_eal librte_ethdev librte_timer librte_pci
 DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ethdev
 DEPDIRS-librte_ethdev := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ethdev += librte_mbuf
lib/librte_dfs/Makefile new file +51 -0

51 lines not on this page · raw message

lib/librte_dfs/dfs.c new file +842 -0

842 lines not on this page · raw message

lib/librte_dfs/dfs.h new file +768 -0

768 lines not on this page · raw message

lib/librte_dfs/dfs_cryptodev.c new file +53 -0

53 lines not on this page · raw message

lib/librte_dfs/dfs_cryptodev.h new file +25 -0
new file mode 100644
index 000000000..647eba3df
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation.
+ */
+
+#ifndef _DFS_CRYPTODEV_H_
+#define _DFS_CRYPTODEV_H_
+
+/**
+ * @file
+ * RTE DFS Cryptodev Operations
+ *
+ * These routines supply the Crypto usage support routines.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DFS_CRYPTODEV_INFO_FILE "cryptodev-info.tmp"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DFS_CRYPTODEV_H_ */
lib/librte_dfs/dfs_dpdk.c new file +323 -0

323 lines not on this page · raw message

lib/librte_dfs/dfs_dpdk.h new file +37 -0
new file mode 100644
index 000000000..1b0ca9106
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation.
+ */
+
+#ifndef _DFS_DPDK_H_
+#define _DFS_DPDK_H_
+
+/**
+ * @file
+ * RTE DFS DPDK Operations
+ *
+ * These routines supply the DPDK usage support routines.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DFS_DEBUG_FILE      "debug.tmp"
+#define DFS_HASH_FILE       "hash.tmp"
+#define DFS_DEVBIND_FILE    "devbind.tmp"
+
+#define DFS_DEVBIND_CMD     "dpdk-devbind.py"
+
+/**
+ * Initialize the DPDK support for DFS
+ *
+ * @return
+ *  -1 on error or 0 on OK
+ */
+int __rte_experimental dfs_dpdk_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DFS_DPDK_H_ */
lib/librte_dfs/dfs_eal.c new file +652 -0

31 lines not on this page · raw message

lib/librte_dfs/dfs_eal.h new file +102 -0

102 lines not on this page · raw message

lib/librte_dfs/dfs_ethdev.c new file +324 -0

324 lines not on this page · raw message

lib/librte_dfs/dfs_ethdev.h new file +23 -0
new file mode 100644
index 000000000..76f30c1ab

Lines of this file are not shown. View the raw message.

lib/librte_dfs/dfs_mempool.c new file +130 -0

130 lines not on this page · raw message

lib/librte_dfs/dfs_mempool.h new file +26 -0
new file mode 100644
index 000000000..121217588

Lines of this file are not shown. View the raw message.

lib/librte_dfs/dfs_noop.c new file +35 -0
new file mode 100644
index 000000000..2f48d8923

Lines of this file are not shown. View the raw message.

lib/librte_dfs/dfs_oper.c new file +836 -0

836 lines not on this page · raw message

lib/librte_dfs/dfs_oper.h new file +48 -0

48 lines not on this page · raw message

lib/librte_dfs/dfs_rawdev.c new file +54 -0

54 lines not on this page · raw message

lib/librte_dfs/dfs_rawdev.h new file +25 -0
new file mode 100644
index 000000000..69edb7cf0

Lines of this file are not shown. View the raw message.

lib/librte_dfs/dfs_ring.c new file +107 -0

107 lines not on this page · raw message

lib/librte_dfs/dfs_ring.h new file +25 -0
new file mode 100644
index 000000000..4e78c1120

Lines of this file are not shown. View the raw message.

lib/librte_dfs/dfs_search.c new file +203 -0

203 lines not on this page · raw message

lib/librte_dfs/dfs_search.h new file +266 -0

266 lines not on this page · raw message

lib/librte_dfs/dfs_timer.c new file +58 -0

58 lines not on this page · raw message

lib/librte_dfs/dfs_timer.h new file +25 -0
new file mode 100644
index 000000000..cb9fdf38b

Lines of this file are not shown. View the raw message.

lib/librte_dfs/meson.build new file +47 -0

47 lines not on this page · raw message

lib/librte_dfs/rte_dfs_version.map new file +29 -0
new file mode 100644
index 000000000..3f963c830

Lines of this file are not shown. View the raw message.

lib/meson.build +1 -1
index bb7f443f9..9a64f969e 100644

Lines of this file are not shown. View the raw message.

mk/rte.app.mk +3 -0
index 5699d979d..0fb759f79 100644

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Signature · 1 line
2.17.1

Part of the diff is not shown here. View the raw message.

#1 lore raw

PATCH v3 2/3 eal:add tailq walk routine

Add tailq walk routine for debugging and used in DFS.

---
V3
Fix checkpatch warnings adding a commit message.
Must be using a different checkpatch then on my Ubuntu 18.04 system
V2
Fix checkpatch warnings

 lib/librte_eal/common/eal_common_tailqs.c | 19 +++++++++++++++++++
 lib/librte_eal/common/include/rte_tailq.h | 13 +++++++++++++
 lib/librte_eal/rte_eal_version.map        |  1 +
 3 files changed, 33 insertions(+)
lib/librte_eal/common/eal_common_tailqs.c +19 -0
index babd3b30a..791dcc37b 100644
@@ -69,6 +69,25 @@ rte_dump_tailq(FILE *f)
 	rte_rwlock_read_unlock(&mcfg->qlock);
 }
 
+void
+rte_tailq_walk(void (*iter)(const struct rte_tailq_head *, void *), void *arg)
+{
+	struct rte_mem_config *mcfg;
+	unsigned int i = 0;
+
+	if (!iter)
+		return;
+	mcfg = rte_eal_get_configuration()->mem_config;
+
+	rte_rwlock_read_lock(&mcfg->qlock);
+	for (i = 0; i < RTE_MAX_TAILQ; i++) {
+		const struct rte_tailq_head *tailq = &mcfg->tailq_head[i];
+
+		iter(tailq, arg);
+	}
+	rte_rwlock_read_unlock(&mcfg->qlock);
+}
+
 static struct rte_tailq_head *
 rte_eal_tailq_create(const char *name)
 {
lib/librte_eal/common/include/rte_tailq.h +13 -0
index 9b01abb2c..b9b1c6e75 100644
@@ -18,6 +18,7 @@ extern "C" {
 #include <sys/queue.h>
 #include <stdio.h>
 #include <rte_debug.h>
+#include <rte_compat.h>
 
 /** dummy structure type used by the rte_tailq APIs */
 struct rte_tailq_entry {
@@ -85,6 +86,18 @@ struct rte_tailq_elem {
  */
 void rte_dump_tailq(FILE *f);
 
+/**
+ * Walk the tailq list and call the Iterator function given.
+ *
+ * @param func
+ *   Iterator function
+ * @param arg
+ *   pointer to user supplied argument passed to Iterator function
+ */
+void __rte_experimental
+	rte_tailq_walk(void (*iter)(const struct rte_tailq_head *, void *),
+	void *arg);
+
 /**
  * Lookup for a tail queue.
  *
lib/librte_eal/rte_eal_version.map +1 -0
index 3fe78260d..9a7abc778 100644
@@ -360,4 +360,5 @@ EXPERIMENTAL {
 	rte_service_may_be_active;
 	rte_socket_count;
 	rte_socket_id_by_idx;
+	rte_tailq_walk;
 };
Signature · 1 line
2.17.1
#2 lore raw

PATCH v3 3/3 ring:add ring walk routine

In reply to Keith Wiles

Add a ring walk routine for debugging and DFS.

---
V3
Fix checkpatch warnings adding a commit message.
Must be using a different checkpatch then on my Ubuntu 18.04 system
V2
Fix checkpatch warnings.

 lib/librte_ring/rte_ring.c           | 20 ++++++++++++++++++++
 lib/librte_ring/rte_ring.h           | 14 ++++++++++++++
 lib/librte_ring/rte_ring_version.map |  7 +++++++
 3 files changed, 41 insertions(+)
lib/librte_ring/rte_ring.c +20 -0
index d215acecc..fb5819e4b 100644
@@ -280,3 +280,23 @@ rte_ring_lookup(const char *name)
 
 	return r;
 }
+
+void
+rte_ring_walk(void (*func)(struct rte_ring *r, void *arg), void *arg)
+{
+	const struct rte_tailq_entry *te;
+	struct rte_ring_list *ring_list;
+
+	if (!func)
+		return;
+
+	ring_list = RTE_TAILQ_CAST(rte_ring_tailq.head, rte_ring_list);
+
+	rte_rwlock_read_lock(RTE_EAL_TAILQ_RWLOCK);
+
+	TAILQ_FOREACH(te, ring_list, next) {
+		func((struct rte_ring *) te->data, arg);
+	}
+
+	rte_rwlock_read_unlock(RTE_EAL_TAILQ_RWLOCK);
+}
lib/librte_ring/rte_ring.h +14 -0
index af5444a9f..b9391a655 100644
@@ -769,6 +769,20 @@ rte_ring_get_capacity(const struct rte_ring *r)
  */
 void rte_ring_list_dump(FILE *f);
 
+/**
+ * Walk the list of ring entries and call the function provided
+ *
+ * @param func
+ *   The function to call for each ring entry using the following prototype
+ *     void (*func)(struct rte_ring *r, void *arg)
+ * @param arg
+ *   argument for the call to function
+ * @return
+ *   None.
+ */
+void __rte_experimental
+rte_ring_walk(void (*func)(struct rte_ring *r, void *arg), void *arg);
+
 /**
  * Search a ring from its name
  *
lib/librte_ring/rte_ring_version.map +7 -0
index d935efd0d..17c05c1b2 100644
@@ -17,3 +17,10 @@ DPDK_2.2 {
 	rte_ring_free;
 
 } DPDK_2.0;
+
+EXPERIMENTAL {
+	global:
+
+	rte_ring_walk;
+};
+
Signature · 1 line
2.17.1
#3 lore raw

Re: [PATCH v3 3/3] ring:add ring walk routine

Hi,

Quoted 33 lines · Keith Wiles

Add a ring walk routine for debugging and DFS.

---
V3
Fix checkpatch warnings adding a commit message.
Must be using a different checkpatch then on my Ubuntu 18.04 system
V2
Fix checkpatch warnings.

 lib/librte_ring/rte_ring.c           | 20 ++++++++++++++++++++
 lib/librte_ring/rte_ring.h           | 14 ++++++++++++++
 lib/librte_ring/rte_ring_version.map |  7 +++++++
 3 files changed, 41 insertions(+)
lib/librte_ring/rte_ring.c +10 -0
index d215acecc..fb5819e4b 100644
@@ -280,3 +280,23 @@ rte_ring_lookup(const char *name)
 
 	return r;
 }
+
+void
+rte_ring_walk(void (*func)(struct rte_ring *r, void *arg), void *arg)
+{
+	const struct rte_tailq_entry *te;
+	struct rte_ring_list *ring_list;
+
+	if (!func)
+		return;
+

lib/librte_ring/rte_ring.c rte_ring_lookup(const char *name) · line 302

Quoted 10 lines
lib/librte_ring/rte_ring.c +10 -0
+	ring_list = RTE_TAILQ_CAST(rte_ring_tailq.head, rte_ring_list);
+
+	rte_rwlock_read_lock(RTE_EAL_TAILQ_RWLOCK);
+
+	TAILQ_FOREACH(te, ring_list, next) {
+		func((struct rte_ring *) te->data, arg);
+	}
+
+	rte_rwlock_read_unlock(RTE_EAL_TAILQ_RWLOCK);
+}

In mempool, a FOREACH_SAFE() macro is using starting from this commit:
cae54ac47ced ("mempool: fix unsafe removal from list by callback")

Maybe the same should be done for the ring.

Quoted 9 lines
lib/librte_ring/rte_ring.h +1 -0
index af5444a9f..b9391a655 100644
@@ -769,6 +769,20 @@ rte_ring_get_capacity(const struct rte_ring *r)
  */
 void rte_ring_list_dump(FILE *f);
 
+/**

lib/librte_ring/rte_ring.h rte_ring_get_capacity(const struct rte_ring *r) · line 782

Quoted 10 lines
lib/librte_ring/rte_ring.h +10 -0
+ * Walk the list of ring entries and call the function provided
+ *
+ * @param func
+ *   The function to call for each ring entry using the following prototype
+ *     void (*func)(struct rte_ring *r, void *arg)
+ * @param arg
+ *   argument for the call to function
+ * @return
+ *   None.
+ */

I don't think we need to duplicate the prototype in the comment. Please add the dots at the end of the sentences, and remove @return.

Thanks,
Olivier

#4 lore raw

Re: [PATCH v3 3/3] ring:add ring walk routine

Quoted 54 lines · Olivier Matz

Hi,

Quoted 33 lines · Keith Wiles

Add a ring walk routine for debugging and DFS.

---
V3
Fix checkpatch warnings adding a commit message.
Must be using a different checkpatch then on my Ubuntu 18.04 system
V2
Fix checkpatch warnings.

lib/librte_ring/rte_ring.c           | 20 ++++++++++++++++++++
lib/librte_ring/rte_ring.h           | 14 ++++++++++++++
lib/librte_ring/rte_ring_version.map |  7 +++++++
3 files changed, 41 insertions(+)
lib/librte_ring/rte_ring.c +10 -0
index d215acecc..fb5819e4b 100644
@@ -280,3 +280,23 @@ rte_ring_lookup(const char *name)
 
 	return r;
 }
+
+void
+rte_ring_walk(void (*func)(struct rte_ring *r, void *arg), void *arg)
+{
+	const struct rte_tailq_entry *te;
+	struct rte_ring_list *ring_list;
+
+	if (!func)
+		return;
+

lib/librte_ring/rte_ring.c rte_ring_lookup(const char *name) · line 302

Quoted 10 lines
lib/librte_ring/rte_ring.c +10 -0
+	ring_list = RTE_TAILQ_CAST(rte_ring_tailq.head, rte_ring_list);
+
+	rte_rwlock_read_lock(RTE_EAL_TAILQ_RWLOCK);
+
+	TAILQ_FOREACH(te, ring_list, next) {
+		func((struct rte_ring *) te->data, arg);
+	}
+
+	rte_rwlock_read_unlock(RTE_EAL_TAILQ_RWLOCK);
+}

In mempool, a FOREACH_SAFE() macro is using starting from this commit:
cae54ac47ced ("mempool: fix unsafe removal from list by callback")

Quoted 1 line

Maybe the same should be done for the ring.

I am not removing or modifying the ring tailq list here and I have the lock already, why do I need to use _SAFE macro?

Quoted 26 lines
Quoted 11 lines
lib/librte_ring/rte_ring.h +1 -0
index af5444a9f..b9391a655 100644
@@ -769,6 +769,20 @@ rte_ring_get_capacity(const struct rte_ring *r)
 */
 void rte_ring_list_dump(FILE *f);
 
+/**

lib/librte_ring/rte_ring.h rte_ring_get_capacity(const struct rte_ring *r) · line 782

Quoted 10 lines
lib/librte_ring/rte_ring.h +10 -0
+ * Walk the list of ring entries and call the function provided
+ *
+ * @param func
+ *   The function to call for each ring entry using the following prototype
+ *     void (*func)(struct rte_ring *r, void *arg)
+ * @param arg
+ *   argument for the call to function
+ * @return
+ *   None.
+ */

I don't think we need to duplicate the prototype in the comment. Please add the dots at the end of the sentences, and remove @return.

Quoted 2 lines

Thanks,
Olivier

Regards,
Keith

#5 lore raw

Re: [PATCH v3 3/3] ring:add ring walk routine

Quoted 58 lines · Keith
Quoted 55 lines · Olivier Matz

Hi,

Quoted 33 lines · Keith Wiles

Add a ring walk routine for debugging and DFS.

---
V3
Fix checkpatch warnings adding a commit message.
Must be using a different checkpatch then on my Ubuntu 18.04 system
V2
Fix checkpatch warnings.

lib/librte_ring/rte_ring.c           | 20 ++++++++++++++++++++
lib/librte_ring/rte_ring.h           | 14 ++++++++++++++
lib/librte_ring/rte_ring_version.map |  7 +++++++
3 files changed, 41 insertions(+)
lib/librte_ring/rte_ring.c +10 -0
index d215acecc..fb5819e4b 100644
@@ -280,3 +280,23 @@ rte_ring_lookup(const char *name)
 
 	return r;
 }
+
+void
+rte_ring_walk(void (*func)(struct rte_ring *r, void *arg), void *arg)
+{
+	const struct rte_tailq_entry *te;
+	struct rte_ring_list *ring_list;
+
+	if (!func)
+		return;
+

lib/librte_ring/rte_ring.c rte_ring_lookup(const char *name) · line 302

Quoted 10 lines
lib/librte_ring/rte_ring.c +10 -0
+	ring_list = RTE_TAILQ_CAST(rte_ring_tailq.head, rte_ring_list);
+
+	rte_rwlock_read_lock(RTE_EAL_TAILQ_RWLOCK);
+
+	TAILQ_FOREACH(te, ring_list, next) {
+		func((struct rte_ring *) te->data, arg);
+	}
+
+	rte_rwlock_read_unlock(RTE_EAL_TAILQ_RWLOCK);
+}

In mempool, a FOREACH_SAFE() macro is using starting from this commit:
cae54ac47ced ("mempool: fix unsafe removal from list by callback")

Quoted 3 lines
Quoted 1 line

Maybe the same should be done for the ring.

I am not removing or modifying the ring tailq list here and I have the lock already, why do I need to use _SAFE macro?

OK, I do see a possible case. If the function freed the node, but it would mean it would have to grab the lock and walk the list to free the te value and unlink it from the list. The function does not get the ’te’ pointer only the data. To free it they would have to grab the lock.

Quoted 27 lines
Quoted 27 lines
Quoted 12 lines
lib/librte_ring/rte_ring.h +1 -0
index af5444a9f..b9391a655 100644
@@ -769,6 +769,20 @@ rte_ring_get_capacity(const struct rte_ring *r)
 */
 void rte_ring_list_dump(FILE *f);
 
+/**

lib/librte_ring/rte_ring.h rte_ring_get_capacity(const struct rte_ring *r) · line 782

Quoted 10 lines
lib/librte_ring/rte_ring.h +10 -0
+ * Walk the list of ring entries and call the function provided
+ *
+ * @param func
+ *   The function to call for each ring entry using the following prototype
+ *     void (*func)(struct rte_ring *r, void *arg)
+ * @param arg
+ *   argument for the call to function
+ * @return
+ *   None.
+ */

I don't think we need to duplicate the prototype in the comment. Please add the dots at the end of the sentences, and remove @return.

Quoted 5 lines
Quoted 2 lines

Thanks,
Olivier

Regards,
Keith

Regards,
Keith

#6 lore raw

Re: [PATCH v3 3/3] ring:add ring walk routine

Hi,

Quoted 58 lines · Keith
Quoted 58 lines · Keith
Quoted 55 lines · Olivier Matz

Hi,

Quoted 33 lines · Keith Wiles

Add a ring walk routine for debugging and DFS.

---
V3
Fix checkpatch warnings adding a commit message.
Must be using a different checkpatch then on my Ubuntu 18.04 system
V2
Fix checkpatch warnings.

lib/librte_ring/rte_ring.c           | 20 ++++++++++++++++++++
lib/librte_ring/rte_ring.h           | 14 ++++++++++++++
lib/librte_ring/rte_ring_version.map |  7 +++++++
3 files changed, 41 insertions(+)
lib/librte_ring/rte_ring.c +10 -0
index d215acecc..fb5819e4b 100644
@@ -280,3 +280,23 @@ rte_ring_lookup(const char *name)
 
 	return r;
 }
+
+void
+rte_ring_walk(void (*func)(struct rte_ring *r, void *arg), void *arg)
+{
+	const struct rte_tailq_entry *te;
+	struct rte_ring_list *ring_list;
+
+	if (!func)
+		return;
+

lib/librte_ring/rte_ring.c rte_ring_lookup(const char *name) · line 302

Quoted 10 lines
lib/librte_ring/rte_ring.c +10 -0
+	ring_list = RTE_TAILQ_CAST(rte_ring_tailq.head, rte_ring_list);
+
+	rte_rwlock_read_lock(RTE_EAL_TAILQ_RWLOCK);
+
+	TAILQ_FOREACH(te, ring_list, next) {
+		func((struct rte_ring *) te->data, arg);
+	}
+
+	rte_rwlock_read_unlock(RTE_EAL_TAILQ_RWLOCK);
+}

In mempool, a FOREACH_SAFE() macro is using starting from this commit:
cae54ac47ced ("mempool: fix unsafe removal from list by callback")

Quoted 5 lines
Quoted 3 lines
Quoted 1 line

Maybe the same should be done for the ring.

I am not removing or modifying the ring tailq list here and I have the lock already, why do I need to use _SAFE macro?

OK, I do see a possible case. If the function freed the node, but it would mean it would have to grab the lock and walk the list to free the te value and unlink it from the list. The function does not get the ’te’ pointer only the data. To free it they would have to grab the lock.

Unlinking the element from the list looks indeed laborious with only te->data, and I agree there is probably no use case for that. Looking at commit cae54ac47ced, it seems there was one, but I cannot find any usage of this feature in git history.

So ok, let's keep your version.

Thanks,
Olivier

#7 lore raw

Re: [PATCH v3 3/3] ring:add ring walk routine

Quoted 67 lines · Olivier Matz

Hi,

Quoted 60 lines · Keith
Quoted 60 lines · Keith
Quoted 56 lines · Olivier Matz

Hi,

Quoted 33 lines · Keith Wiles

Add a ring walk routine for debugging and DFS.

---
V3
Fix checkpatch warnings adding a commit message.
Must be using a different checkpatch then on my Ubuntu 18.04 system V2
Fix checkpatch warnings.

lib/librte_ring/rte_ring.c           | 20 ++++++++++++++++++++
lib/librte_ring/rte_ring.h           | 14 ++++++++++++++
lib/librte_ring/rte_ring_version.map |  7 +++++++
3 files changed, 41 insertions(+)
lib/librte_ring/rte_ring.c +10 -0
index d215acecc..fb5819e4b 100644
@@ -280,3 +280,23 @@ rte_ring_lookup(const char *name)
 
 	return r;
 }
+
+void
+rte_ring_walk(void (*func)(struct rte_ring *r, void *arg), void *arg)
+{
+	const struct rte_tailq_entry *te;
+	struct rte_ring_list *ring_list;
+
+	if (!func)
+		return;
+

lib/librte_ring/rte_ring.c rte_ring_lookup(const char *name) · line 302

Quoted 10 lines
lib/librte_ring/rte_ring.c +10 -0
+	ring_list = RTE_TAILQ_CAST(rte_ring_tailq.head, rte_ring_list);
+
+	rte_rwlock_read_lock(RTE_EAL_TAILQ_RWLOCK);
+
+	TAILQ_FOREACH(te, ring_list, next) {
+		func((struct rte_ring *) te->data, arg);
+	}
+
+	rte_rwlock_read_unlock(RTE_EAL_TAILQ_RWLOCK);
+}

In mempool, a FOREACH_SAFE() macro is using starting from this commit:
cae54ac47ced ("mempool: fix unsafe removal from list by callback")

Maybe the same should be done for the ring.

Quoted 8 lines
Quoted 3 lines
Quoted 1 line

I am not removing or modifying the ring tailq list here and I have the lock already, why do I need to use _SAFE macro?

OK, I do see a possible case. If the function freed the node, but it would mean it would have to grab the lock and walk the list to free the te value and unlink it from the list. The function does not get the ’te’ pointer only the data. To free it they would have to grab the lock.

Unlinking the element from the list looks indeed laborious with only te->data, and I agree there is probably no use case for that. Looking at commit cae54ac47ced, it seems there was one, but I cannot find any usage of this feature in git history.

I could change the function to return > 0 value to have the entry removed and the ’te’ freed leaving the data value up to the called function to free or do whatever it needs. return of 0 means just step to the next entry and < 0 means stop. What do you think of that change?

Quoted 5 lines

So ok, let's keep your version.

Thanks,
Olivier

Regards,
Keith

#8 lore raw

PATCH v4 1/1 ring:add ring walk routine

In reply to Keith Wiles

---
V4
Add TAILQ_FOREACH_SAFE and have function being called return a value to be used to stop walking, free tailq_entry or continue walking.
V3
Fix checkpatch warnings adding a commit message.
Must be using a different checkpatch then on my Ubuntu 18.04 system
V2
Fix checkpatch warnings.

 lib/librte_ring/rte_ring.c           | 29 ++++++++++++++++++++++++++++
 lib/librte_ring/rte_ring.h           | 17 ++++++++++++++++
 lib/librte_ring/rte_ring_version.map |  7 +++++++
 3 files changed, 53 insertions(+)
lib/librte_ring/rte_ring.c +29 -0
index d215acecc..4b68c0d98 100644
@@ -280,3 +280,32 @@ rte_ring_lookup(const char *name)
 
 	return r;
 }
+
+void
+rte_ring_walk(int (*func)(struct rte_ring *r, void *arg), void *arg)
+{
+	const struct rte_tailq_entry *te, *tv;
+	struct rte_ring_list *ring_list;
+
+	if (!func)
+		return;
+
+	ring_list = RTE_TAILQ_CAST(rte_ring_tailq.head, rte_ring_list);
+
+	rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);
+
+	TAILQ_FOREACH_SAFE(te, ring_list, next, tv) {
+		int ret;
+
+		ret = func((struct rte_ring *) te->data, arg);
+		if (ret < 0)
+			break;
+
+		if (ret > 0) {
+			TAILQ_REMOVE(ring_list, te, next);
+			rte_free(te);
+		}
+	}
+
+	rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
+}
lib/librte_ring/rte_ring.h +17 -0
index af5444a9f..ed6a44773 100644
@@ -769,6 +769,23 @@ rte_ring_get_capacity(const struct rte_ring *r)
  */
 void rte_ring_list_dump(FILE *f);
 
+/**
+ * Walk the list of ring entries and call the function provided.
+ *
+ * @param func
+ *   The function to call for each ring entry using the following prototype.
+ *     If the function returns < 0 then stop walking the list.
+ *     If the function returns > 0 then remove and free the tailq entry.
+ *       and do not free the tailq entry ring pointer. Leave ring pointer
+ *       to the function to handle the ring pointer freeing.
+ *     If the function returns 0 then continue walking the list.
+ *   The RTE_EAL_TAILQ_RWLOCK write lock is taken while walking the list.
+ * @param arg
+ *   argument for the call to function.
+ */
+void __rte_experimental
+rte_ring_walk(int (*func)(struct rte_ring *r, void *arg), void *arg);
+
 /**
  * Search a ring from its name
  *
lib/librte_ring/rte_ring_version.map +7 -0
index d935efd0d..17c05c1b2 100644
@@ -17,3 +17,10 @@ DPDK_2.2 {
 	rte_ring_free;
 
 } DPDK_2.0;
+
+EXPERIMENTAL {
+	global:
+
+	rte_ring_walk;
+};
+
Signature · 1 line
2.17.1
#9 lore raw

PATCH v4 1/1 eal:add tailq walk routine

In reply to Keith Wiles

---
V4
Change function to have a return value.
to be used to stop walking or continue walking.
V3
Fix checkpatch warnings adding a commit message.
Must be using a different checkpatch then on my Ubuntu 18.04 system
V2
Fix checkpatch warnings.

 lib/librte_eal/common/eal_common_tailqs.c | 20 ++++++++++++++++++++
 lib/librte_eal/common/include/rte_tailq.h | 16 ++++++++++++++++
 lib/librte_eal/rte_eal_version.map        |  1 +
 3 files changed, 37 insertions(+)
lib/librte_eal/common/eal_common_tailqs.c +20 -0
index babd3b30a..99e898019 100644
@@ -69,6 +69,26 @@ rte_dump_tailq(FILE *f)
 	rte_rwlock_read_unlock(&mcfg->qlock);
 }
 
+void
+rte_tailq_walk(int (*iter)(const struct rte_tailq_head *, void *), void *arg)
+{
+	struct rte_mem_config *mcfg;
+	unsigned int i = 0;
+
+	if (!iter)
+		return;
+	mcfg = rte_eal_get_configuration()->mem_config;
+
+	rte_rwlock_read_lock(&mcfg->qlock);
+	for (i = 0; i < RTE_MAX_TAILQ; i++) {
+		const struct rte_tailq_head *tailq = &mcfg->tailq_head[i];
+
+		if (iter(tailq, arg) < 0)
+			break;
+	}
+	rte_rwlock_read_unlock(&mcfg->qlock);
+}
+
 static struct rte_tailq_head *
 rte_eal_tailq_create(const char *name)
 {
lib/librte_eal/common/include/rte_tailq.h +16 -0
index 9b01abb2c..25e99658b 100644
@@ -18,6 +18,7 @@ extern "C" {
 #include <sys/queue.h>
 #include <stdio.h>
 #include <rte_debug.h>
+#include <rte_compat.h>
 
 /** dummy structure type used by the rte_tailq APIs */
 struct rte_tailq_entry {
@@ -85,6 +86,21 @@ struct rte_tailq_elem {
  */
 void rte_dump_tailq(FILE *f);
 
+/**
+ * Walk the tailq list and call the Iterator function given.
+ *
+ * @param func
+ *   Iterator function called for each tailq list.
+ *   The rte_eal_get_configuration()->mem_config.qlock read lock is held.
+ *   If Iterator returns < 0 then break out of loop.
+ *   If Iterator returns 0 then continue looping.
+ * @param arg
+ *   pointer to user supplied argument passed to Iterator function.
+ */
+void __rte_experimental
+	rte_tailq_walk(int (*iter)(const struct rte_tailq_head *, void *),
+	void *arg);
+
 /**
  * Lookup for a tail queue.
  *
lib/librte_eal/rte_eal_version.map +1 -0
index eb5f7b9cb..288b20b0e 100644
@@ -364,4 +364,5 @@ EXPERIMENTAL {
 	rte_service_may_be_active;
 	rte_socket_count;
 	rte_socket_id_by_idx;
+	rte_tailq_walk;
 };
Signature · 1 line
2.17.1
#10 lore raw

PATCH v5 1/1 ring:add ring walk routine

In reply to Keith Wiles

Add a ring walk routine for debugging and other uses. This routine walks the list of rings and allows the called function to stop, remove ring from list or continue.

---
V5
Fixup checkpatch warning on commit message
V4
Add TAILQ_FOREACH_SAFE and have function being called return a value to be used to stop walking, free tailq_entry or continue walking.
V3
Fix checkpatch warnings adding a commit message.
Must be using a different checkpatch then on my Ubuntu 18.04 system
V2
Fix checkpatch warnings.

 lib/librte_ring/rte_ring.c           | 29 ++++++++++++++++++++++++++++
 lib/librte_ring/rte_ring.h           | 17 ++++++++++++++++
 lib/librte_ring/rte_ring_version.map |  7 +++++++
 3 files changed, 53 insertions(+)
lib/librte_ring/rte_ring.c +29 -0
index d215acecc..4b68c0d98 100644
@@ -280,3 +280,32 @@ rte_ring_lookup(const char *name)
 
 	return r;
 }
+
+void
+rte_ring_walk(int (*func)(struct rte_ring *r, void *arg), void *arg)
+{
+	const struct rte_tailq_entry *te, *tv;
+	struct rte_ring_list *ring_list;
+
+	if (!func)
+		return;
+
+	ring_list = RTE_TAILQ_CAST(rte_ring_tailq.head, rte_ring_list);
+
+	rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);
+
+	TAILQ_FOREACH_SAFE(te, ring_list, next, tv) {
+		int ret;
+
+		ret = func((struct rte_ring *) te->data, arg);
+		if (ret < 0)
+			break;
+
+		if (ret > 0) {
+			TAILQ_REMOVE(ring_list, te, next);
+			rte_free(te);
+		}
+	}
+
+	rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
+}
lib/librte_ring/rte_ring.h +17 -0
index af5444a9f..ed6a44773 100644
@@ -769,6 +769,23 @@ rte_ring_get_capacity(const struct rte_ring *r)
  */
 void rte_ring_list_dump(FILE *f);
 
+/**
+ * Walk the list of ring entries and call the function provided.
+ *
+ * @param func
+ *   The function to call for each ring entry using the following prototype.
+ *     If the function returns < 0 then stop walking the list.
+ *     If the function returns > 0 then remove and free the tailq entry.
+ *       and do not free the tailq entry ring pointer. Leave ring pointer
+ *       to the function to handle the ring pointer freeing.
+ *     If the function returns 0 then continue walking the list.
+ *   The RTE_EAL_TAILQ_RWLOCK write lock is taken while walking the list.
+ * @param arg
+ *   argument for the call to function.
+ */
+void __rte_experimental
+rte_ring_walk(int (*func)(struct rte_ring *r, void *arg), void *arg);
+
 /**
  * Search a ring from its name
  *
lib/librte_ring/rte_ring_version.map +7 -0
index d935efd0d..17c05c1b2 100644
@@ -17,3 +17,10 @@ DPDK_2.2 {
 	rte_ring_free;
 
 } DPDK_2.0;
+
+EXPERIMENTAL {
+	global:
+
+	rte_ring_walk;
+};
+
Signature · 1 line
2.17.1
#11 lore raw

PATCH v5 1/1 eal:add tailq walk routine

In reply to Keith Wiles

Add the tailq walk routine for debugging and other uses. This routine will hold the read lock while walking the list.

---
V5
Fixup checkpatch warnings.
V4
Change function to have a return value.
to be used to stop walking or continue walking.
V3
Fix checkpatch warnings adding a commit message.
Must be using a different checkpatch then on my Ubuntu 18.04 system
V2
Fix checkpatch warnings.

 lib/librte_eal/common/eal_common_tailqs.c | 20 ++++++++++++++++++++
 lib/librte_eal/common/include/rte_tailq.h | 16 ++++++++++++++++
 lib/librte_eal/rte_eal_version.map        |  1 +
 3 files changed, 37 insertions(+)
lib/librte_eal/common/eal_common_tailqs.c +20 -0
index babd3b30a..99e898019 100644
@@ -69,6 +69,26 @@ rte_dump_tailq(FILE *f)
 	rte_rwlock_read_unlock(&mcfg->qlock);
 }
 
+void
+rte_tailq_walk(int (*iter)(const struct rte_tailq_head *, void *), void *arg)
+{
+	struct rte_mem_config *mcfg;
+	unsigned int i = 0;
+
+	if (!iter)
+		return;
+	mcfg = rte_eal_get_configuration()->mem_config;
+
+	rte_rwlock_read_lock(&mcfg->qlock);
+	for (i = 0; i < RTE_MAX_TAILQ; i++) {
+		const struct rte_tailq_head *tailq = &mcfg->tailq_head[i];
+
+		if (iter(tailq, arg) < 0)
+			break;
+	}
+	rte_rwlock_read_unlock(&mcfg->qlock);
+}
+
 static struct rte_tailq_head *
 rte_eal_tailq_create(const char *name)
 {
lib/librte_eal/common/include/rte_tailq.h +16 -0
index 9b01abb2c..25e99658b 100644
@@ -18,6 +18,7 @@ extern "C" {
 #include <sys/queue.h>
 #include <stdio.h>
 #include <rte_debug.h>
+#include <rte_compat.h>
 
 /** dummy structure type used by the rte_tailq APIs */
 struct rte_tailq_entry {
@@ -85,6 +86,21 @@ struct rte_tailq_elem {
  */
 void rte_dump_tailq(FILE *f);
 
+/**
+ * Walk the tailq list and call the Iterator function given.
+ *
+ * @param func
+ *   Iterator function called for each tailq list.
+ *   The rte_eal_get_configuration()->mem_config.qlock read lock is held.
+ *   If Iterator returns < 0 then break out of loop.
+ *   If Iterator returns 0 then continue looping.
+ * @param arg
+ *   pointer to user supplied argument passed to Iterator function.
+ */
+void __rte_experimental
+	rte_tailq_walk(int (*iter)(const struct rte_tailq_head *, void *),
+	void *arg);
+
 /**
  * Lookup for a tail queue.
  *
lib/librte_eal/rte_eal_version.map +1 -0
index eb5f7b9cb..288b20b0e 100644
@@ -364,4 +364,5 @@ EXPERIMENTAL {
 	rte_service_may_be_active;
 	rte_socket_count;
 	rte_socket_id_by_idx;
+	rte_tailq_walk;
 };
Signature · 1 line
2.17.1
#12 lore raw

PATCH v6 1/1 eal:add tailq walk routine

In reply to Keith Wiles

Add the tailq walk routine for debugging and other uses. This routine will hold the read lock while walking the list.

---
V6
Remove warning
V5
Fixup checkpatch warnings.
V4
Change function to have a return value.
to be used to stop walking or continue walking.
V3
Fix checkpatch warnings adding a commit message.
Must be using a different checkpatch then on my Ubuntu 18.04 system
V2
Fix checkpatch warnings.

 lib/librte_eal/common/eal_common_tailqs.c | 20 ++++++++++++++++++++
 lib/librte_eal/common/include/rte_tailq.h | 16 ++++++++++++++++
 lib/librte_eal/rte_eal_version.map        |  1 +
 3 files changed, 37 insertions(+)
lib/librte_eal/common/eal_common_tailqs.c +20 -0
index babd3b30a..99e898019 100644
@@ -69,6 +69,26 @@ rte_dump_tailq(FILE *f)
 	rte_rwlock_read_unlock(&mcfg->qlock);
 }
 
+void
+rte_tailq_walk(int (*iter)(const struct rte_tailq_head *, void *), void *arg)
+{
+	struct rte_mem_config *mcfg;
+	unsigned int i = 0;
+
+	if (!iter)
+		return;
+	mcfg = rte_eal_get_configuration()->mem_config;
+
+	rte_rwlock_read_lock(&mcfg->qlock);
+	for (i = 0; i < RTE_MAX_TAILQ; i++) {
+		const struct rte_tailq_head *tailq = &mcfg->tailq_head[i];
+
+		if (iter(tailq, arg) < 0)
+			break;
+	}
+	rte_rwlock_read_unlock(&mcfg->qlock);
+}
+
 static struct rte_tailq_head *
 rte_eal_tailq_create(const char *name)
 {
lib/librte_eal/common/include/rte_tailq.h +16 -0
index 9b01abb2c..25e99658b 100644
@@ -18,6 +18,7 @@ extern "C" {
 #include <sys/queue.h>
 #include <stdio.h>
 #include <rte_debug.h>
+#include <rte_compat.h>
 
 /** dummy structure type used by the rte_tailq APIs */
 struct rte_tailq_entry {
@@ -85,6 +86,21 @@ struct rte_tailq_elem {
  */
 void rte_dump_tailq(FILE *f);
 
+/**
+ * Walk the tailq list and call the Iterator function given.
+ *
+ * @param func
+ *   Iterator function called for each tailq list.
+ *   The rte_eal_get_configuration()->mem_config.qlock read lock is held.
+ *   If Iterator returns < 0 then break out of loop.
+ *   If Iterator returns 0 then continue looping.
+ * @param arg
+ *   pointer to user supplied argument passed to Iterator function.
+ */
+void __rte_experimental
+	rte_tailq_walk(int (*iter)(const struct rte_tailq_head *, void *),
+	void *arg);
+
 /**
  * Lookup for a tail queue.
  *
lib/librte_eal/rte_eal_version.map +1 -0
index eb5f7b9cb..288b20b0e 100644
@@ -364,4 +364,5 @@ EXPERIMENTAL {
 	rte_service_may_be_active;
 	rte_socket_count;
 	rte_socket_id_by_idx;
+	rte_tailq_walk;
 };
Signature · 1 line
2.17.1
#13 lore raw

PATCH v5 1/1 ring:add ring walk routine

In reply to Keith Wiles

Add a ring walk routine for debugging and other uses. This routine walks the list of rings and allows the called function to stop, remove ring from list or continue.

---
V6
Remove warning
V5
Fixup checkpatch warning on commit message
V4
Add TAILQ_FOREACH_SAFE and have function being called return a value to be used to stop walking, free tailq_entry or continue walking.
V3
Fix checkpatch warnings adding a commit message.
Must be using a different checkpatch then on my Ubuntu 18.04 system
V2
Fix checkpatch warnings.

 lib/librte_ring/rte_ring.c           | 29 ++++++++++++++++++++++++++++
 lib/librte_ring/rte_ring.h           | 17 ++++++++++++++++
 lib/librte_ring/rte_ring_version.map |  7 +++++++
 3 files changed, 53 insertions(+)
lib/librte_ring/rte_ring.c +29 -0
index d215acecc..17c9780df 100644
@@ -280,3 +280,32 @@ rte_ring_lookup(const char *name)
 
 	return r;
 }
+
+void
+rte_ring_walk(int (*func)(struct rte_ring *r, void *arg), void *arg)
+{
+	const struct rte_tailq_entry *te, *tv;
+	struct rte_ring_list *ring_list;
+
+	if (!func)
+		return;
+
+	ring_list = RTE_TAILQ_CAST(rte_ring_tailq.head, rte_ring_list);
+
+	rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);
+
+	TAILQ_FOREACH_SAFE(te, ring_list, next, tv) {
+		int ret;
+
+		ret = func((struct rte_ring *) te->data, arg);
+		if (ret < 0)
+			break;
+
+		if (ret > 0) {
+			TAILQ_REMOVE(ring_list, te, next);
+			rte_free((void *)(uintptr_t)te);
+		}
+	}
+
+	rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
+}
lib/librte_ring/rte_ring.h +17 -0
index af5444a9f..ed6a44773 100644
@@ -769,6 +769,23 @@ rte_ring_get_capacity(const struct rte_ring *r)
  */
 void rte_ring_list_dump(FILE *f);
 
+/**
+ * Walk the list of ring entries and call the function provided.
+ *
+ * @param func
+ *   The function to call for each ring entry using the following prototype.
+ *     If the function returns < 0 then stop walking the list.
+ *     If the function returns > 0 then remove and free the tailq entry.
+ *       and do not free the tailq entry ring pointer. Leave ring pointer
+ *       to the function to handle the ring pointer freeing.
+ *     If the function returns 0 then continue walking the list.
+ *   The RTE_EAL_TAILQ_RWLOCK write lock is taken while walking the list.
+ * @param arg
+ *   argument for the call to function.
+ */
+void __rte_experimental
+rte_ring_walk(int (*func)(struct rte_ring *r, void *arg), void *arg);
+
 /**
  * Search a ring from its name
  *
lib/librte_ring/rte_ring_version.map +7 -0
index d935efd0d..17c05c1b2 100644
@@ -17,3 +17,10 @@ DPDK_2.2 {
 	rte_ring_free;
 
 } DPDK_2.0;
+
+EXPERIMENTAL {
+	global:
+
+	rte_ring_walk;
+};
+
Signature · 1 line
2.17.1
#14 lore raw

PATCH v6 1/1 ring:add ring walk routine

In reply to Keith Wiles

Add a ring walk routine for debugging and other uses. This routine walks the list of rings and allows the called function to stop, remove ring from list or continue.

---
V6
Remove warning
V5
Fixup checkpatch warning on commit message
V4
Add TAILQ_FOREACH_SAFE and have function being called return a value to be used to stop walking, free tailq_entry or continue walking.
V3
Fix checkpatch warnings adding a commit message.
Must be using a different checkpatch then on my Ubuntu 18.04 system
V2
Fix checkpatch warnings.

 lib/librte_ring/rte_ring.c           | 29 ++++++++++++++++++++++++++++
 lib/librte_ring/rte_ring.h           | 17 ++++++++++++++++
 lib/librte_ring/rte_ring_version.map |  7 +++++++
 3 files changed, 53 insertions(+)
lib/librte_ring/rte_ring.c +29 -0
index d215acecc..17c9780df 100644
@@ -280,3 +280,32 @@ rte_ring_lookup(const char *name)
 
 	return r;
 }
+
+void
+rte_ring_walk(int (*func)(struct rte_ring *r, void *arg), void *arg)
+{
+	const struct rte_tailq_entry *te, *tv;
+	struct rte_ring_list *ring_list;
+
+	if (!func)
+		return;
+
+	ring_list = RTE_TAILQ_CAST(rte_ring_tailq.head, rte_ring_list);
+
+	rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);
+
+	TAILQ_FOREACH_SAFE(te, ring_list, next, tv) {
+		int ret;
+
+		ret = func((struct rte_ring *) te->data, arg);
+		if (ret < 0)
+			break;
+
+		if (ret > 0) {
+			TAILQ_REMOVE(ring_list, te, next);
+			rte_free((void *)(uintptr_t)te);
+		}
+	}
+
+	rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
+}
lib/librte_ring/rte_ring.h +17 -0
index af5444a9f..ed6a44773 100644
@@ -769,6 +769,23 @@ rte_ring_get_capacity(const struct rte_ring *r)
  */
 void rte_ring_list_dump(FILE *f);
 
+/**
+ * Walk the list of ring entries and call the function provided.
+ *
+ * @param func
+ *   The function to call for each ring entry using the following prototype.
+ *     If the function returns < 0 then stop walking the list.
+ *     If the function returns > 0 then remove and free the tailq entry.
+ *       and do not free the tailq entry ring pointer. Leave ring pointer
+ *       to the function to handle the ring pointer freeing.
+ *     If the function returns 0 then continue walking the list.
+ *   The RTE_EAL_TAILQ_RWLOCK write lock is taken while walking the list.
+ * @param arg
+ *   argument for the call to function.
+ */
+void __rte_experimental
+rte_ring_walk(int (*func)(struct rte_ring *r, void *arg), void *arg);
+
 /**
  * Search a ring from its name
  *
lib/librte_ring/rte_ring_version.map +7 -0
index d935efd0d..17c05c1b2 100644
@@ -17,3 +17,10 @@ DPDK_2.2 {
 	rte_ring_free;
 
 } DPDK_2.0;
+
+EXPERIMENTAL {
+	global:
+
+	rte_ring_walk;
+};
+
Signature · 1 line
2.17.1