All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gage Eads <gage.eads@intel.com>
To: dev@dpdk.org
Cc: olivier.matz@6wind.com, arybchenko@solarflare.com,
	bruce.richardson@intel.com, konstantin.ananyev@intel.com,
	gavin.hu@arm.com, Honnappa.Nagarahalli@arm.com, nd@arm.com,
	thomas@monjalon.net
Subject: [PATCH v5 1/8] stack: introduce rte stack library
Date: Sun, 31 Mar 2019 19:12:31 -0500	[thread overview]
Message-ID: <20190401001238.17625-2-gage.eads@intel.com> (raw)
In-Reply-To: <20190401001238.17625-1-gage.eads@intel.com>

The rte_stack library provides an API for configuration and use of a
bounded stack of pointers. Push and pop operations are MT-safe, allowing
concurrent access, and the interface supports pushing and popping multiple
pointers at a time.

The library's interface is modeled after another DPDK data structure,
rte_ring, and its lock-based implementation is derived from the stack
mempool handler. An upcoming commit will migrate the stack mempool handler
to rte_stack.

Signed-off-by: Gage Eads <gage.eads@intel.com>
Reviewed-by: Olivier Matz <olivier.matz@6wind.com>
---
 MAINTAINERS                            |   6 +
 config/common_base                     |   5 +
 doc/api/doxy-api-index.md              |   1 +
 doc/api/doxy-api.conf.in               |   1 +
 doc/guides/prog_guide/index.rst        |   1 +
 doc/guides/prog_guide/stack_lib.rst    |  28 +++++
 doc/guides/rel_notes/release_19_05.rst |   5 +
 lib/Makefile                           |   2 +
 lib/librte_stack/Makefile              |  25 ++++
 lib/librte_stack/meson.build           |   8 ++
 lib/librte_stack/rte_stack.c           | 182 +++++++++++++++++++++++++++++
 lib/librte_stack/rte_stack.h           | 207 +++++++++++++++++++++++++++++++++
 lib/librte_stack/rte_stack_pvt.h       |  34 ++++++
 lib/librte_stack/rte_stack_std.c       |  26 +++++
 lib/librte_stack/rte_stack_std.h       | 119 +++++++++++++++++++
 lib/librte_stack/rte_stack_version.map |   9 ++
 lib/meson.build                        |   2 +-
 mk/rte.app.mk                          |   1 +
 18 files changed, 661 insertions(+), 1 deletion(-)
 create mode 100644 doc/guides/prog_guide/stack_lib.rst
 create mode 100644 lib/librte_stack/Makefile
 create mode 100644 lib/librte_stack/meson.build
 create mode 100644 lib/librte_stack/rte_stack.c
 create mode 100644 lib/librte_stack/rte_stack.h
 create mode 100644 lib/librte_stack/rte_stack_pvt.h
 create mode 100644 lib/librte_stack/rte_stack_std.c
 create mode 100644 lib/librte_stack/rte_stack_std.h
 create mode 100644 lib/librte_stack/rte_stack_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index e9ff2b4c2..09fd99dbf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -416,6 +416,12 @@ F: drivers/raw/skeleton_rawdev/
 F: app/test/test_rawdev.c
 F: doc/guides/prog_guide/rawdev.rst
 
+Stack API - EXPERIMENTAL
+M: Gage Eads <gage.eads@intel.com>
+M: Olivier Matz <olivier.matz@6wind.com>
+F: lib/librte_stack/
+F: doc/guides/prog_guide/stack_lib.rst
+
 
 Memory Pool Drivers
 -------------------
diff --git a/config/common_base b/config/common_base
index 6292bc4af..fc8dba69d 100644
--- a/config/common_base
+++ b/config/common_base
@@ -994,3 +994,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
 # Compile the eventdev application
 #
 CONFIG_RTE_APP_EVENTDEV=y
+
+#
+# Compile librte_stack
+#
+CONFIG_RTE_LIBRTE_STACK=y
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index aacc66bd8..de1e215dd 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -125,6 +125,7 @@ The public API headers are grouped by topics:
   [mbuf]               (@ref rte_mbuf.h),
   [mbuf pool ops]      (@ref rte_mbuf_pool_ops.h),
   [ring]               (@ref rte_ring.h),
+  [stack]              (@ref rte_stack.h),
   [tailq]              (@ref rte_tailq.h),
   [bitmap]             (@ref rte_bitmap.h)
 
diff --git a/doc/api/doxy-api.conf.in b/doc/api/doxy-api.conf.in
index a365e669b..7722fc3e9 100644
--- a/doc/api/doxy-api.conf.in
+++ b/doc/api/doxy-api.conf.in
@@ -55,6 +55,7 @@ INPUT                   = @TOPDIR@/doc/api/doxy-api-index.md \
                           @TOPDIR@/lib/librte_ring \
                           @TOPDIR@/lib/librte_sched \
                           @TOPDIR@/lib/librte_security \
+                          @TOPDIR@/lib/librte_stack \
                           @TOPDIR@/lib/librte_table \
                           @TOPDIR@/lib/librte_telemetry \
                           @TOPDIR@/lib/librte_timer \
diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index 6726b1e8d..f4f60862f 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -55,6 +55,7 @@ Programmer's Guide
     metrics_lib
     bpf_lib
     ipsec_lib
+    stack_lib
     source_org
     dev_kit_build_system
     dev_kit_root_make_help
diff --git a/doc/guides/prog_guide/stack_lib.rst b/doc/guides/prog_guide/stack_lib.rst
new file mode 100644
index 000000000..25a8cc38a
--- /dev/null
+++ b/doc/guides/prog_guide/stack_lib.rst
@@ -0,0 +1,28 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright(c) 2019 Intel Corporation.
+
+Stack Library
+=============
+
+DPDK's stack library provides an API for configuration and use of a bounded
+stack of pointers.
+
+The stack library provides the following basic operations:
+
+*  Create a uniquely named stack of a user-specified size and using a
+   user-specified socket.
+
+*  Push and pop a burst of one or more stack objects (pointers). These function
+   are multi-threading safe.
+
+*  Free a previously created stack.
+
+*  Lookup a pointer to a stack by its name.
+
+*  Query a stack's current depth and number of free entries.
+
+Implementation
+~~~~~~~~~~~~~~
+
+The stack consists of a contiguous array of pointers, a current index, and a
+spinlock. Accesses to the stack are made multi-thread safe by the spinlock.
diff --git a/doc/guides/rel_notes/release_19_05.rst b/doc/guides/rel_notes/release_19_05.rst
index bdad1ddbe..ebfbe36e5 100644
--- a/doc/guides/rel_notes/release_19_05.rst
+++ b/doc/guides/rel_notes/release_19_05.rst
@@ -121,6 +121,11 @@ New Features
   Improved testpmd application performance on ARM platform. For ``macswap``
   forwarding mode, NEON intrinsics were used to do swap to save CPU cycles.
 
+* **Added Stack API.**
+
+  Added a new stack API for configuration and use of a bounded stack of
+  pointers. The API provides MT-safe push and pop operations that can operate
+  on one or more pointers per operation.
 
 Removed Items
 -------------
diff --git a/lib/Makefile b/lib/Makefile
index a358f1c19..9f90e80ad 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -109,6 +109,8 @@ DIRS-$(CONFIG_RTE_LIBRTE_IPSEC) += librte_ipsec
 DEPDIRS-librte_ipsec := librte_eal librte_mbuf librte_cryptodev librte_security
 DIRS-$(CONFIG_RTE_LIBRTE_TELEMETRY) += librte_telemetry
 DEPDIRS-librte_telemetry := librte_eal librte_metrics librte_ethdev
+DIRS-$(CONFIG_RTE_LIBRTE_STACK) += librte_stack
+DEPDIRS-librte_stack := librte_eal
 
 ifeq ($(CONFIG_RTE_EXEC_ENV_LINUX),y)
 DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni
diff --git a/lib/librte_stack/Makefile b/lib/librte_stack/Makefile
new file mode 100644
index 000000000..6db540073
--- /dev/null
+++ b/lib/librte_stack/Makefile
@@ -0,0 +1,25 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# library name
+LIB = librte_stack.a
+
+CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+LDLIBS += -lrte_eal
+
+EXPORT_MAP := rte_stack_version.map
+
+LIBABIVER := 1
+
+# all source are stored in SRCS-y
+SRCS-$(CONFIG_RTE_LIBRTE_STACK) := rte_stack.c \
+				   rte_stack_std.c
+
+# install includes
+SYMLINK-$(CONFIG_RTE_LIBRTE_STACK)-include := rte_stack.h \
+					      rte_stack_std.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_stack/meson.build b/lib/librte_stack/meson.build
new file mode 100644
index 000000000..d2e60ce9b
--- /dev/null
+++ b/lib/librte_stack/meson.build
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+allow_experimental_apis = true
+
+version = 1
+sources = files('rte_stack.c', 'rte_stack_std.c')
+headers = files('rte_stack.h', 'rte_stack_std.h')
diff --git a/lib/librte_stack/rte_stack.c b/lib/librte_stack/rte_stack.c
new file mode 100644
index 000000000..610014b6c
--- /dev/null
+++ b/lib/librte_stack/rte_stack.c
@@ -0,0 +1,182 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#include <string.h>
+
+#include <rte_atomic.h>
+#include <rte_eal.h>
+#include <rte_eal_memconfig.h>
+#include <rte_errno.h>
+#include <rte_malloc.h>
+#include <rte_memzone.h>
+#include <rte_rwlock.h>
+#include <rte_tailq.h>
+
+#include "rte_stack.h"
+#include "rte_stack_pvt.h"
+
+int stack_logtype;
+
+TAILQ_HEAD(rte_stack_list, rte_tailq_entry);
+
+static struct rte_tailq_elem rte_stack_tailq = {
+	.name = RTE_TAILQ_STACK_NAME,
+};
+EAL_REGISTER_TAILQ(rte_stack_tailq)
+
+static void
+rte_stack_init(struct rte_stack *s)
+{
+	memset(s, 0, sizeof(*s));
+
+	rte_stack_std_init(s);
+}
+
+static ssize_t
+rte_stack_get_memsize(unsigned int count)
+{
+	return rte_stack_std_get_memsize(count);
+}
+
+struct rte_stack *
+rte_stack_create(const char *name, unsigned int count, int socket_id,
+		 uint32_t flags)
+{
+	char mz_name[RTE_MEMZONE_NAMESIZE];
+	struct rte_stack_list *stack_list;
+	const struct rte_memzone *mz;
+	struct rte_tailq_entry *te;
+	struct rte_stack *s;
+	unsigned int sz;
+	int ret;
+
+	RTE_SET_USED(flags);
+
+	sz = rte_stack_get_memsize(count);
+
+	ret = snprintf(mz_name, sizeof(mz_name), "%s%s",
+		       RTE_STACK_MZ_PREFIX, name);
+	if (ret < 0 || ret >= (int)sizeof(mz_name)) {
+		rte_errno = ENAMETOOLONG;
+		return NULL;
+	}
+
+	te = rte_zmalloc("STACK_TAILQ_ENTRY", sizeof(*te), 0);
+	if (te == NULL) {
+		STACK_LOG_ERR("Cannot reserve memory for tailq\n");
+		rte_errno = ENOMEM;
+		return NULL;
+	}
+
+	rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);
+
+	mz = rte_memzone_reserve_aligned(mz_name, sz, socket_id,
+					 0, __alignof__(*s));
+	if (mz == NULL) {
+		STACK_LOG_ERR("Cannot reserve stack memzone!\n");
+		rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
+		rte_free(te);
+		return NULL;
+	}
+
+	s = mz->addr;
+
+	rte_stack_init(s);
+
+	/* Store the name for later lookups */
+	ret = snprintf(s->name, sizeof(s->name), "%s", name);
+	if (ret < 0 || ret >= (int)sizeof(s->name)) {
+		rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
+
+		rte_errno = ENAMETOOLONG;
+		rte_free(te);
+		rte_memzone_free(mz);
+		return NULL;
+	}
+
+	s->memzone = mz;
+	s->capacity = count;
+	s->flags = flags;
+
+	te->data = s;
+
+	stack_list = RTE_TAILQ_CAST(rte_stack_tailq.head, rte_stack_list);
+
+	TAILQ_INSERT_TAIL(stack_list, te, next);
+
+	rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
+
+	return s;
+}
+
+void
+rte_stack_free(struct rte_stack *s)
+{
+	struct rte_stack_list *stack_list;
+	struct rte_tailq_entry *te;
+
+	if (s == NULL)
+		return;
+
+	stack_list = RTE_TAILQ_CAST(rte_stack_tailq.head, rte_stack_list);
+	rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);
+
+	/* find out tailq entry */
+	TAILQ_FOREACH(te, stack_list, next) {
+		if (te->data == s)
+			break;
+	}
+
+	if (te == NULL) {
+		rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
+		return;
+	}
+
+	TAILQ_REMOVE(stack_list, te, next);
+
+	rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
+
+	rte_free(te);
+
+	rte_memzone_free(s->memzone);
+}
+
+struct rte_stack *
+rte_stack_lookup(const char *name)
+{
+	struct rte_stack_list *stack_list;
+	struct rte_tailq_entry *te;
+	struct rte_stack *r = NULL;
+
+	if (name == NULL) {
+		rte_errno = EINVAL;
+		return NULL;
+	}
+
+	stack_list = RTE_TAILQ_CAST(rte_stack_tailq.head, rte_stack_list);
+
+	rte_rwlock_read_lock(RTE_EAL_TAILQ_RWLOCK);
+
+	TAILQ_FOREACH(te, stack_list, next) {
+		r = (struct rte_stack *) te->data;
+		if (strncmp(name, r->name, RTE_STACK_NAMESIZE) == 0)
+			break;
+	}
+
+	rte_rwlock_read_unlock(RTE_EAL_TAILQ_RWLOCK);
+
+	if (te == NULL) {
+		rte_errno = ENOENT;
+		return NULL;
+	}
+
+	return r;
+}
+
+RTE_INIT(librte_stack_init_log)
+{
+	stack_logtype = rte_log_register("lib.stack");
+	if (stack_logtype >= 0)
+		rte_log_set_level(stack_logtype, RTE_LOG_NOTICE);
+}
diff --git a/lib/librte_stack/rte_stack.h b/lib/librte_stack/rte_stack.h
new file mode 100644
index 000000000..d9799d747
--- /dev/null
+++ b/lib/librte_stack/rte_stack.h
@@ -0,0 +1,207 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+/**
+ * @file rte_stack.h
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * RTE Stack
+ *
+ * librte_stack provides an API for configuration and use of a bounded stack of
+ * pointers. Push and pop operations are MT-safe, allowing concurrent access,
+ * and the interface supports pushing and popping multiple pointers at a time.
+ */
+
+#ifndef _RTE_STACK_H_
+#define _RTE_STACK_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_errno.h>
+#include <rte_memzone.h>
+#include <rte_spinlock.h>
+
+#define RTE_TAILQ_STACK_NAME "RTE_STACK"
+#define RTE_STACK_MZ_PREFIX "STK_"
+/** The maximum length of a stack name. */
+#define RTE_STACK_NAMESIZE (RTE_MEMZONE_NAMESIZE - \
+			   sizeof(RTE_STACK_MZ_PREFIX) + 1)
+
+/* Structure containing the LIFO, its current length, and a lock for mutual
+ * exclusion.
+ */
+struct rte_stack_std {
+	rte_spinlock_t lock; /**< LIFO lock */
+	uint32_t len; /**< LIFO len */
+	void *objs[]; /**< LIFO pointer table */
+};
+
+/* The RTE stack structure contains the LIFO structure itself, plus metadata
+ * such as its name and memzone pointer.
+ */
+struct rte_stack {
+	/** Name of the stack. */
+	char name[RTE_STACK_NAMESIZE] __rte_cache_aligned;
+	/** Memzone containing the rte_stack structure. */
+	const struct rte_memzone *memzone;
+	uint32_t capacity; /**< Usable size of the stack. */
+	uint32_t flags; /**< Flags supplied at creation. */
+	struct rte_stack_std stack_std; /**< LIFO structure. */
+} __rte_cache_aligned;
+
+#include "rte_stack_std.h"
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Push several objects on the stack (MT-safe).
+ *
+ * @param s
+ *   A pointer to the stack structure.
+ * @param obj_table
+ *   A pointer to a table of void * pointers (objects).
+ * @param n
+ *   The number of objects to push on the stack from the obj_table.
+ * @return
+ *   Actual number of objects pushed (either 0 or *n*).
+ */
+static __rte_always_inline unsigned int __rte_experimental
+rte_stack_push(struct rte_stack *s, void * const *obj_table, unsigned int n)
+{
+	RTE_ASSERT(s != NULL);
+	RTE_ASSERT(obj_table != NULL);
+
+	return __rte_stack_std_push(s, obj_table, n);
+}
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Pop several objects from the stack (MT-safe).
+ *
+ * @param s
+ *   A pointer to the stack structure.
+ * @param obj_table
+ *   A pointer to a table of void * pointers (objects).
+ * @param n
+ *   The number of objects to pull from the stack.
+ * @return
+ *   Actual number of objects popped (either 0 or *n*).
+ */
+static __rte_always_inline unsigned int __rte_experimental
+rte_stack_pop(struct rte_stack *s, void **obj_table, unsigned int n)
+{
+	RTE_ASSERT(s != NULL);
+	RTE_ASSERT(obj_table != NULL);
+
+	return __rte_stack_std_pop(s, obj_table, n);
+}
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Return the number of used entries in a stack.
+ *
+ * @param s
+ *   A pointer to the stack structure.
+ * @return
+ *   The number of used entries in the stack.
+ */
+static __rte_always_inline unsigned int __rte_experimental
+rte_stack_count(struct rte_stack *s)
+{
+	RTE_ASSERT(s != NULL);
+
+	return __rte_stack_std_count(s);
+}
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Return the number of free entries in a stack.
+ *
+ * @param s
+ *   A pointer to the stack structure.
+ * @return
+ *   The number of free entries in the stack.
+ */
+static __rte_always_inline unsigned int __rte_experimental
+rte_stack_free_count(struct rte_stack *s)
+{
+	RTE_ASSERT(s != NULL);
+
+	return s->capacity - rte_stack_count(s);
+}
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Create a new stack named *name* in memory.
+ *
+ * This function uses ``memzone_reserve()`` to allocate memory for a stack of
+ * size *count*. The behavior of the stack is controlled by the *flags*.
+ *
+ * @param name
+ *   The name of the stack.
+ * @param count
+ *   The size of the stack.
+ * @param socket_id
+ *   The *socket_id* argument is the socket identifier in case of
+ *   NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA
+ *   constraint for the reserved zone.
+ * @param flags
+ *   Reserved for future use.
+ * @return
+ *   On success, the pointer to the new allocated stack. NULL on error with
+ *    rte_errno set appropriately. Possible errno values include:
+ *    - ENOSPC - the maximum number of memzones has already been allocated
+ *    - EEXIST - a stack with the same name already exists
+ *    - ENOMEM - insufficient memory to create the stack
+ *    - ENAMETOOLONG - name size exceeds RTE_STACK_NAMESIZE
+ */
+struct rte_stack *__rte_experimental
+rte_stack_create(const char *name, unsigned int count, int socket_id,
+		 uint32_t flags);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Free all memory used by the stack.
+ *
+ * @param s
+ *   Stack to free
+ */
+void __rte_experimental
+rte_stack_free(struct rte_stack *s);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Lookup a stack by its name.
+ *
+ * @param name
+ *   The name of the stack.
+ * @return
+ *   The pointer to the stack matching the name, or NULL if not found,
+ *   with rte_errno set appropriately. Possible rte_errno values include:
+ *    - ENOENT - Stack with name *name* not found.
+ *    - EINVAL - *name* pointer is NULL.
+ */
+struct rte_stack * __rte_experimental
+rte_stack_lookup(const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_STACK_H_ */
diff --git a/lib/librte_stack/rte_stack_pvt.h b/lib/librte_stack/rte_stack_pvt.h
new file mode 100644
index 000000000..4a6a7bdb3
--- /dev/null
+++ b/lib/librte_stack/rte_stack_pvt.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#ifndef _RTE_STACK_PVT_H_
+#define _RTE_STACK_PVT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_log.h>
+
+extern int stack_logtype;
+
+#define STACK_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ##level, stack_logtype, "%s(): "fmt "\n", \
+		__func__, ##args)
+
+#define STACK_LOG_ERR(fmt, args...) \
+	STACK_LOG(ERR, fmt, ## args)
+
+#define STACK_LOG_WARN(fmt, args...) \
+	STACK_LOG(WARNING, fmt, ## args)
+
+#define STACK_LOG_INFO(fmt, args...) \
+	STACK_LOG(INFO, fmt, ## args)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_STACK_PVT_H_ */
diff --git a/lib/librte_stack/rte_stack_std.c b/lib/librte_stack/rte_stack_std.c
new file mode 100644
index 000000000..0a310d7c6
--- /dev/null
+++ b/lib/librte_stack/rte_stack_std.c
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#include "rte_stack.h"
+
+void
+rte_stack_std_init(struct rte_stack *s)
+{
+	rte_spinlock_init(&s->stack_std.lock);
+}
+
+ssize_t
+rte_stack_std_get_memsize(unsigned int count)
+{
+	ssize_t sz = sizeof(struct rte_stack);
+
+	sz += RTE_CACHE_LINE_ROUNDUP(count * sizeof(void *));
+
+	/* Add padding to avoid false sharing conflicts caused by
+	 * next-line hardware prefetchers.
+	 */
+	sz += 2 * RTE_CACHE_LINE_SIZE;
+
+	return sz;
+}
diff --git a/lib/librte_stack/rte_stack_std.h b/lib/librte_stack/rte_stack_std.h
new file mode 100644
index 000000000..f9af087dc
--- /dev/null
+++ b/lib/librte_stack/rte_stack_std.h
@@ -0,0 +1,119 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#ifndef _RTE_STACK_STD_H_
+#define _RTE_STACK_STD_H_
+
+/**
+ * @internal Push several objects on the stack (MT-safe).
+ *
+ * @param s
+ *   A pointer to the stack structure.
+ * @param obj_table
+ *   A pointer to a table of void * pointers (objects).
+ * @param n
+ *   The number of objects to push on the stack from the obj_table.
+ * @return
+ *   Actual number of objects pushed (either 0 or *n*).
+ */
+static __rte_always_inline unsigned int __rte_experimental
+__rte_stack_std_push(struct rte_stack *s, void * const *obj_table,
+		     unsigned int n)
+{
+	struct rte_stack_std *stack = &s->stack_std;
+	unsigned int index;
+	void **cache_objs;
+
+	rte_spinlock_lock(&stack->lock);
+	cache_objs = &stack->objs[stack->len];
+
+	/* Is there sufficient space in the stack? */
+	if ((stack->len + n) > s->capacity) {
+		rte_spinlock_unlock(&stack->lock);
+		return 0;
+	}
+
+	/* Add elements back into the cache */
+	for (index = 0; index < n; ++index, obj_table++)
+		cache_objs[index] = *obj_table;
+
+	stack->len += n;
+
+	rte_spinlock_unlock(&stack->lock);
+	return n;
+}
+
+/**
+ * @internal Pop several objects from the stack (MT-safe).
+ *
+ * @param s
+ *   A pointer to the stack structure.
+ * @param obj_table
+ *   A pointer to a table of void * pointers (objects).
+ * @param n
+ *   The number of objects to pull from the stack.
+ * @return
+ *   Actual number of objects popped (either 0 or *n*).
+ */
+static __rte_always_inline unsigned int __rte_experimental
+__rte_stack_std_pop(struct rte_stack *s, void **obj_table, unsigned int n)
+{
+	struct rte_stack_std *stack = &s->stack_std;
+	unsigned int index, len;
+	void **cache_objs;
+
+	rte_spinlock_lock(&stack->lock);
+
+	if (unlikely(n > stack->len)) {
+		rte_spinlock_unlock(&stack->lock);
+		return 0;
+	}
+
+	cache_objs = stack->objs;
+
+	for (index = 0, len = stack->len - 1; index < n;
+			++index, len--, obj_table++)
+		*obj_table = cache_objs[len];
+
+	stack->len -= n;
+	rte_spinlock_unlock(&stack->lock);
+
+	return n;
+}
+
+/**
+ * @internal Return the number of used entries in a stack.
+ *
+ * @param s
+ *   A pointer to the stack structure.
+ * @return
+ *   The number of used entries in the stack.
+ */
+static __rte_always_inline unsigned int __rte_experimental
+__rte_stack_std_count(struct rte_stack *s)
+{
+	return (unsigned int)s->stack_std.len;
+}
+
+/**
+ * @internal Initialize a standard stack.
+ *
+ * @param s
+ *   A pointer to the stack structure.
+ */
+void
+rte_stack_std_init(struct rte_stack *s);
+
+/**
+ * @internal Return the memory required for a standard stack.
+ *
+ * @param count
+ *   The size of the stack.
+ * @return
+ *   The bytes to allocate for a standard stack.
+ */
+ssize_t
+rte_stack_std_get_memsize(unsigned int count);
+
+#endif /* _RTE_STACK_STD_H_ */
diff --git a/lib/librte_stack/rte_stack_version.map b/lib/librte_stack/rte_stack_version.map
new file mode 100644
index 000000000..6662679c3
--- /dev/null
+++ b/lib/librte_stack/rte_stack_version.map
@@ -0,0 +1,9 @@
+EXPERIMENTAL {
+	global:
+
+	rte_stack_create;
+	rte_stack_free;
+	rte_stack_lookup;
+
+	local: *;
+};
diff --git a/lib/meson.build b/lib/meson.build
index 99957ba7d..90115477f 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -22,7 +22,7 @@ libraries = [
 	'gro', 'gso', 'ip_frag', 'jobstats',
 	'kni', 'latencystats', 'lpm', 'member',
 	'power', 'pdump', 'rawdev',
-	'reorder', 'sched', 'security', 'vhost',
+	'reorder', 'sched', 'security', 'stack', 'vhost',
 	#ipsec lib depends on crypto and security
 	'ipsec',
 	# add pkt framework libs which use other libs from above
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 262132fc6..7e033e78c 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -87,6 +87,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_SECURITY)       += -lrte_security
 _LDLIBS-$(CONFIG_RTE_LIBRTE_COMPRESSDEV)    += -lrte_compressdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV)       += -lrte_eventdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_RAWDEV)         += -lrte_rawdev
+_LDLIBS-$(CONFIG_RTE_LIBRTE_STACK)          += -lrte_stack
 _LDLIBS-$(CONFIG_RTE_LIBRTE_TIMER)          += -lrte_timer
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
 _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring
-- 
2.13.6

  reply	other threads:[~2019-04-01  0:13 UTC|newest]

Thread overview: 133+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-22 16:06 [PATCH 0/7] Subject: [PATCH ...] Add stack library and new mempool handler Gage Eads
2019-02-22 16:06 ` [PATCH 1/7] stack: introduce rte stack library Gage Eads
2019-02-25 10:43   ` Olivier Matz
2019-02-28  5:10     ` Eads, Gage
2019-02-22 16:06 ` [PATCH 2/7] mempool/stack: convert mempool to use rte stack Gage Eads
2019-02-25 10:46   ` Olivier Matz
2019-02-22 16:06 ` [PATCH 3/7] test/stack: add stack test Gage Eads
2019-02-25 10:59   ` Olivier Matz
2019-02-28  5:11     ` Eads, Gage
2019-02-22 16:06 ` [PATCH 4/7] test/stack: add stack perf test Gage Eads
2019-02-25 11:04   ` Olivier Matz
2019-02-22 16:06 ` [PATCH 5/7] stack: add non-blocking stack implementation Gage Eads
2019-02-25 11:28   ` Olivier Matz
     [not found]     ` <2EC44CCD3517A842B44C82651A5557A14AF13386@fmsmsx118.amr.corp.intel.com>
2019-03-01 20:53       ` FW: " Eads, Gage
2019-03-01 21:12         ` Thomas Monjalon
2019-03-01 21:29           ` Eads, Gage
2019-02-22 16:06 ` [PATCH 6/7] test/stack: add non-blocking stack tests Gage Eads
2019-02-25 11:28   ` Olivier Matz
2019-02-22 16:06 ` [PATCH 7/7] mempool/stack: add non-blocking stack mempool handler Gage Eads
2019-02-25 11:29   ` Olivier Matz
2019-03-05 16:42 ` [PATCH v2 0/8] Add stack library and new " Gage Eads
2019-03-05 16:42   ` [PATCH v2 1/8] stack: introduce rte stack library Gage Eads
2019-03-05 16:42   ` [PATCH v2 2/8] mempool/stack: convert mempool to use rte stack Gage Eads
2019-03-05 16:42   ` [PATCH v2 3/8] test/stack: add stack test Gage Eads
2019-03-05 16:42   ` [PATCH v2 4/8] test/stack: add stack perf test Gage Eads
2019-03-05 16:42   ` [PATCH v2 5/8] stack: add lock-free stack implementation Gage Eads
2019-03-05 16:42   ` [PATCH v2 6/8] stack: add C11 atomic implementation Gage Eads
2019-03-05 16:42   ` [PATCH v2 7/8] test/stack: add lock-free stack tests Gage Eads
2019-03-05 16:42   ` [PATCH v2 8/8] mempool/stack: add lock-free stack mempool handler Gage Eads
2019-03-06 14:45   ` [PATCH v3 0/8] Add stack library and new " Gage Eads
2019-03-06 14:45     ` [PATCH v3 1/8] stack: introduce rte stack library Gage Eads
2019-03-14  8:00       ` Olivier Matz
2019-03-28 23:26       ` Honnappa Nagarahalli
2019-03-29 19:23         ` Eads, Gage
2019-03-29 21:07           ` Thomas Monjalon
2019-04-01 17:41           ` Honnappa Nagarahalli
2019-04-01 19:34             ` Eads, Gage
2019-03-06 14:45     ` [PATCH v3 2/8] mempool/stack: convert mempool to use rte stack Gage Eads
2019-03-06 14:45     ` [PATCH v3 3/8] test/stack: add stack test Gage Eads
2019-03-14  8:00       ` Olivier Matz
2019-03-06 14:45     ` [PATCH v3 4/8] test/stack: add stack perf test Gage Eads
2019-03-06 14:45     ` [PATCH v3 5/8] stack: add lock-free stack implementation Gage Eads
2019-03-14  8:01       ` Olivier Matz
2019-03-28 23:27       ` Honnappa Nagarahalli
2019-03-29 19:25         ` Eads, Gage
2019-03-06 14:45     ` [PATCH v3 6/8] stack: add C11 atomic implementation Gage Eads
2019-03-14  8:04       ` Olivier Matz
2019-03-28 23:27       ` Honnappa Nagarahalli
2019-03-29 19:24         ` Eads, Gage
2019-04-01  0:06           ` Eads, Gage
2019-04-01 19:06             ` Honnappa Nagarahalli
2019-04-01 20:21               ` Eads, Gage
2019-03-06 14:45     ` [PATCH v3 7/8] test/stack: add lock-free stack tests Gage Eads
2019-03-06 14:45     ` [PATCH v3 8/8] mempool/stack: add lock-free stack mempool handler Gage Eads
2019-03-28 18:00     ` [PATCH v4 0/8] Add stack library and new " Gage Eads
2019-03-28 18:00       ` [PATCH v4 1/8] stack: introduce rte stack library Gage Eads
2019-03-28 18:00       ` [PATCH v4 2/8] mempool/stack: convert mempool to use rte stack Gage Eads
2019-03-28 18:00       ` [PATCH v4 3/8] test/stack: add stack test Gage Eads
2019-03-28 18:00       ` [PATCH v4 4/8] test/stack: add stack perf test Gage Eads
2019-03-28 18:00       ` [PATCH v4 5/8] stack: add lock-free stack implementation Gage Eads
2019-03-28 18:00       ` [PATCH v4 6/8] stack: add C11 atomic implementation Gage Eads
2019-03-28 18:00       ` [PATCH v4 7/8] test/stack: add lock-free stack tests Gage Eads
2019-03-28 18:00       ` [PATCH v4 8/8] mempool/stack: add lock-free stack mempool handler Gage Eads
2019-04-01  0:12       ` [PATCH v5 0/8] Add stack library and new " Gage Eads
2019-04-01  0:12         ` Gage Eads [this message]
2019-04-01  0:12         ` [PATCH v5 2/8] mempool/stack: convert mempool to use rte stack Gage Eads
2019-04-01  0:12         ` [PATCH v5 3/8] test/stack: add stack test Gage Eads
2019-04-01  0:12         ` [PATCH v5 4/8] test/stack: add stack perf test Gage Eads
2019-04-01  0:12         ` [PATCH v5 5/8] stack: add lock-free stack implementation Gage Eads
2019-04-01 18:08           ` Honnappa Nagarahalli
2019-04-01  0:12         ` [PATCH v5 6/8] stack: add C11 atomic implementation Gage Eads
2019-04-01  0:12         ` [PATCH v5 7/8] test/stack: add lock-free stack tests Gage Eads
2019-04-01  0:12         ` [PATCH v5 8/8] mempool/stack: add lock-free stack mempool handler Gage Eads
2019-04-01 21:14         ` [PATCH v6 0/8] Add stack library and new " Gage Eads
2019-04-01 21:14           ` [PATCH v6 1/8] stack: introduce rte stack library Gage Eads
2019-04-02 11:14             ` Honnappa Nagarahalli
2019-04-03 17:06               ` Thomas Monjalon
2019-04-03 17:13                 ` Eads, Gage
2019-04-03 17:23                   ` Thomas Monjalon
2019-04-01 21:14           ` [PATCH v6 2/8] mempool/stack: convert mempool to use rte stack Gage Eads
2019-04-01 21:14           ` [PATCH v6 3/8] test/stack: add stack test Gage Eads
2019-04-01 21:14           ` [PATCH v6 4/8] test/stack: add stack perf test Gage Eads
2019-04-01 21:14           ` [PATCH v6 5/8] stack: add lock-free stack implementation Gage Eads
2019-04-01 21:14           ` [PATCH v6 6/8] stack: add C11 atomic implementation Gage Eads
2019-04-02 11:11             ` Honnappa Nagarahalli
2019-04-01 21:14           ` [PATCH v6 7/8] test/stack: add lock-free stack tests Gage Eads
2019-04-01 21:14           ` [PATCH v6 8/8] mempool/stack: add lock-free stack mempool handler Gage Eads
2019-04-03 17:04           ` [PATCH v6 0/8] Add stack library and new " Thomas Monjalon
2019-04-03 17:10             ` Eads, Gage
2019-04-03 20:09           ` [PATCH v7 " Gage Eads
2019-04-03 20:09             ` [PATCH v7 1/8] stack: introduce rte stack library Gage Eads
2019-04-03 20:09             ` [PATCH v7 2/8] mempool/stack: convert mempool to use rte stack Gage Eads
2019-04-03 20:09             ` [PATCH v7 3/8] test/stack: add stack test Gage Eads
2019-04-03 20:09             ` [PATCH v7 4/8] test/stack: add stack perf test Gage Eads
2019-04-03 20:09             ` [PATCH v7 5/8] stack: add lock-free stack implementation Gage Eads
2019-04-03 20:09             ` [PATCH v7 6/8] stack: add C11 atomic implementation Gage Eads
2019-04-03 20:09             ` [PATCH v7 7/8] test/stack: add lock-free stack tests Gage Eads
2019-04-03 20:09             ` [PATCH v7 8/8] mempool/stack: add lock-free stack mempool handler Gage Eads
2019-04-03 20:39             ` [PATCH v7 0/8] Add stack library and new " Thomas Monjalon
2019-04-03 20:49               ` Eads, Gage
2019-04-03 20:50             ` [PATCH v8 " Gage Eads
2019-04-03 20:50               ` [PATCH v8 1/8] stack: introduce rte stack library Gage Eads
2019-04-03 20:50               ` [PATCH v8 2/8] mempool/stack: convert mempool to use rte stack Gage Eads
2019-04-03 20:50               ` [PATCH v8 3/8] test/stack: add stack test Gage Eads
2019-04-03 22:41                 ` Thomas Monjalon
2019-04-03 23:05                   ` Eads, Gage
2019-04-03 20:50               ` [PATCH v8 4/8] test/stack: add stack perf test Gage Eads
2019-04-03 20:50               ` [PATCH v8 5/8] stack: add lock-free stack implementation Gage Eads
2019-04-03 20:50               ` [PATCH v8 6/8] stack: add C11 atomic implementation Gage Eads
2019-04-03 20:50               ` [PATCH v8 7/8] test/stack: add lock-free stack tests Gage Eads
2019-04-03 20:50               ` [PATCH v8 8/8] mempool/stack: add lock-free stack mempool handler Gage Eads
2019-04-03 23:20               ` [PATCH v9 0/8] Add stack library and new " Gage Eads
2019-04-03 23:20                 ` [PATCH v9 1/8] stack: introduce rte stack library Gage Eads
2019-04-04 13:30                   ` Thomas Monjalon
2019-04-04 14:14                     ` Eads, Gage
2019-04-03 23:20                 ` [PATCH v9 2/8] mempool/stack: convert mempool to use rte stack Gage Eads
2019-04-03 23:20                 ` [PATCH v9 3/8] test/stack: add stack test Gage Eads
2019-04-04  7:34                   ` Thomas Monjalon
2019-04-03 23:20                 ` [PATCH v9 4/8] test/stack: add stack perf test Gage Eads
2019-04-03 23:20                 ` [PATCH v9 5/8] stack: add lock-free stack implementation Gage Eads
2019-04-03 23:20                 ` [PATCH v9 6/8] stack: add C11 atomic implementation Gage Eads
2019-04-03 23:20                 ` [PATCH v9 7/8] test/stack: add lock-free stack tests Gage Eads
2019-04-03 23:20                 ` [PATCH v9 8/8] mempool/stack: add lock-free stack mempool handler Gage Eads
2019-04-04 10:01                 ` [PATCH v10 0/8] Add stack library and new " Gage Eads
2019-04-04 10:01                   ` [PATCH v10 1/8] stack: introduce rte stack library Gage Eads
2019-04-04 10:01                   ` [PATCH v10 2/8] mempool/stack: convert mempool to use rte stack Gage Eads
2019-04-04 10:01                   ` [PATCH v10 3/8] test/stack: add stack test Gage Eads
2019-04-04 10:01                   ` [PATCH v10 4/8] test/stack: add stack perf test Gage Eads
2019-04-04 10:01                   ` [PATCH v10 5/8] stack: add lock-free stack implementation Gage Eads
2019-04-04 10:01                   ` [PATCH v10 6/8] stack: add C11 atomic implementation Gage Eads
2019-04-04 10:01                   ` [PATCH v10 7/8] test/stack: add lock-free stack tests Gage Eads
2019-04-04 10:01                   ` [PATCH v10 8/8] mempool/stack: add lock-free stack mempool handler Gage Eads
2019-04-04 15:42                   ` [PATCH v10 0/8] Add stack library and new " Thomas Monjalon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190401001238.17625-2-gage.eads@intel.com \
    --to=gage.eads@intel.com \
    --cc=Honnappa.Nagarahalli@arm.com \
    --cc=arybchenko@solarflare.com \
    --cc=bruce.richardson@intel.com \
    --cc=dev@dpdk.org \
    --cc=gavin.hu@arm.com \
    --cc=konstantin.ananyev@intel.com \
    --cc=nd@arm.com \
    --cc=olivier.matz@6wind.com \
    --cc=thomas@monjalon.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.