DPDK patches and discussions
 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: [dpdk-dev] [PATCH v5 5/8] stack: add lock-free stack implementation
Date: Sun, 31 Mar 2019 19:12:35 -0500	[thread overview]
Message-ID: <20190401001238.17625-6-gage.eads@intel.com> (raw)
Message-ID: <20190401001235.xrJxbslYzhRJVwtG8stO96A0eXKco_x6d6TNLhBkCWE@z> (raw)
In-Reply-To: <20190401001238.17625-1-gage.eads@intel.com>

This commit adds support for a lock-free (linked list based) stack to the
stack API. This behavior is selected through a new rte_stack_create() flag,
RTE_STACK_F_LF.

The stack consists of a linked list of elements, each containing a data
pointer and a next pointer, and an atomic stack depth counter.

The lock-free push operation enqueues a linked list of pointers by pointing
the tail of the list to the current stack head, and using a CAS to swing
the stack head pointer to the head of the list. The operation retries if it
is unsuccessful (i.e. the list changed between reading the head and
modifying it), else it adjusts the stack length and returns.

The lock-free pop operation first reserves num elements by adjusting the
stack length, to ensure the dequeue operation will succeed without
blocking. It then dequeues pointers by walking the list -- starting from
the head -- then swinging the head pointer (using a CAS as well). While
walking the list, the data pointers are recorded in an object table.

This algorithm stack uses a 128-bit compare-and-swap instruction, which
atomically updates the stack top pointer and a modification counter, to
protect against the ABA problem.

The linked list elements themselves are maintained in a lock-free LIFO
list, and are allocated before stack pushes and freed after stack pops.
Since the stack has a fixed maximum depth, these elements do not need to be
dynamically created.

Signed-off-by: Gage Eads <gage.eads@intel.com>
Reviewed-by: Olivier Matz <olivier.matz@6wind.com>
---
 doc/guides/prog_guide/stack_lib.rst     |  61 ++++++++++++-
 doc/guides/rel_notes/release_19_05.rst  |   3 +
 lib/librte_stack/Makefile               |   7 +-
 lib/librte_stack/meson.build            |   7 +-
 lib/librte_stack/rte_stack.c            |  28 ++++--
 lib/librte_stack/rte_stack.h            |  62 +++++++++++--
 lib/librte_stack/rte_stack_lf.c         |  31 +++++++
 lib/librte_stack/rte_stack_lf.h         | 102 +++++++++++++++++++++
 lib/librte_stack/rte_stack_lf_generic.h | 151 ++++++++++++++++++++++++++++++++
 9 files changed, 433 insertions(+), 19 deletions(-)
 create mode 100644 lib/librte_stack/rte_stack_lf.c
 create mode 100644 lib/librte_stack/rte_stack_lf.h
 create mode 100644 lib/librte_stack/rte_stack_lf_generic.h

diff --git a/doc/guides/prog_guide/stack_lib.rst b/doc/guides/prog_guide/stack_lib.rst
index 25a8cc38a..8fe8804e3 100644
--- a/doc/guides/prog_guide/stack_lib.rst
+++ b/doc/guides/prog_guide/stack_lib.rst
@@ -10,7 +10,8 @@ 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.
+   user-specified socket, with either standard (lock-based) or lock-free
+   behavior.
 
 *  Push and pop a burst of one or more stack objects (pointers). These function
    are multi-threading safe.
@@ -24,5 +25,59 @@ The stack library provides the following basic operations:
 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.
+The library supports two types of stacks: standard (lock-based) and lock-free.
+Both types use the same set of interfaces, but their implementations differ.
+
+Lock-based Stack
+----------------
+
+The lock-based 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.
+
+Lock-free Stack
+------------------
+
+The lock-free stack consists of a linked list of elements, each containing a
+data pointer and a next pointer, and an atomic stack depth counter. The
+lock-free property means that multiple threads can push and pop simultaneously,
+and one thread being preempted/delayed in a push or pop operation will not
+impede the forward progress of any other thread.
+
+The lock-free push operation enqueues a linked list of pointers by pointing the
+list's tail to the current stack head, and using a CAS to swing the stack head
+pointer to the head of the list. The operation retries if it is unsuccessful
+(i.e. the list changed between reading the head and modifying it), else it
+adjusts the stack length and returns.
+
+The lock-free pop operation first reserves one or more list elements by
+adjusting the stack length, to ensure the dequeue operation will succeed
+without blocking. It then dequeues pointers by walking the list -- starting
+from the head -- then swinging the head pointer (using a CAS as well). While
+walking the list, the data pointers are recorded in an object table.
+
+The linked list elements themselves are maintained in a lock-free LIFO, and are
+allocated before stack pushes and freed after stack pops. Since the stack has a
+fixed maximum depth, these elements do not need to be dynamically created.
+
+The lock-free behavior is selected by passing the *RTE_STACK_F_LF* flag to
+rte_stack_create().
+
+Preventing the ABA Problem
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To prevent the ABA problem, this algorithm stack uses a 128-bit
+compare-and-swap instruction to atomically update both the stack top pointer
+and a modification counter. The ABA problem can occur without a modification
+counter if, for example:
+
+1. Thread A reads head pointer X and stores the pointed-to list element.
+2. Other threads modify the list such that the head pointer is once again X,
+   but its pointed-to data is different than what thread A read.
+3. Thread A changes the head pointer with a compare-and-swap and succeeds.
+
+In this case thread A would not detect that the list had changed, and would
+both pop stale data and incorrect change the head pointer. By adding a
+modification counter that is updated on every push and pop as part of the
+compare-and-swap, the algorithm can detect when the list changes even if the
+head pointer remains the same.
diff --git a/doc/guides/rel_notes/release_19_05.rst b/doc/guides/rel_notes/release_19_05.rst
index ebfbe36e5..3b115b5f6 100644
--- a/doc/guides/rel_notes/release_19_05.rst
+++ b/doc/guides/rel_notes/release_19_05.rst
@@ -127,6 +127,9 @@ New Features
   pointers. The API provides MT-safe push and pop operations that can operate
   on one or more pointers per operation.
 
+  The library supports two stack implementations: standard (lock-based) and lock-free.
+  The lock-free implementation is currently limited to x86-64 platforms.
+
 Removed Items
 -------------
 
diff --git a/lib/librte_stack/Makefile b/lib/librte_stack/Makefile
index 6db540073..311edd997 100644
--- a/lib/librte_stack/Makefile
+++ b/lib/librte_stack/Makefile
@@ -16,10 +16,13 @@ LIBABIVER := 1
 
 # all source are stored in SRCS-y
 SRCS-$(CONFIG_RTE_LIBRTE_STACK) := rte_stack.c \
-				   rte_stack_std.c
+				   rte_stack_std.c \
+				   rte_stack_lf.c
 
 # install includes
 SYMLINK-$(CONFIG_RTE_LIBRTE_STACK)-include := rte_stack.h \
-					      rte_stack_std.h
+					      rte_stack_std.h \
+					      rte_stack_lf.h \
+					      rte_stack_lf_generic.h
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_stack/meson.build b/lib/librte_stack/meson.build
index d2e60ce9b..7a09a5d66 100644
--- a/lib/librte_stack/meson.build
+++ b/lib/librte_stack/meson.build
@@ -4,5 +4,8 @@
 allow_experimental_apis = true
 
 version = 1
-sources = files('rte_stack.c', 'rte_stack_std.c')
-headers = files('rte_stack.h', 'rte_stack_std.h')
+sources = files('rte_stack.c', 'rte_stack_std.c', 'rte_stack_lf.c')
+headers = files('rte_stack.h',
+		'rte_stack_std.h',
+		'rte_stack_lf.h',
+		'rte_stack_lf_generic.h')
diff --git a/lib/librte_stack/rte_stack.c b/lib/librte_stack/rte_stack.c
index 610014b6c..1a4d9bd1e 100644
--- a/lib/librte_stack/rte_stack.c
+++ b/lib/librte_stack/rte_stack.c
@@ -25,18 +25,25 @@ static struct rte_tailq_elem rte_stack_tailq = {
 };
 EAL_REGISTER_TAILQ(rte_stack_tailq)
 
+
 static void
-rte_stack_init(struct rte_stack *s)
+rte_stack_init(struct rte_stack *s, unsigned int count, uint32_t flags)
 {
 	memset(s, 0, sizeof(*s));
 
-	rte_stack_std_init(s);
+	if (flags & RTE_STACK_F_LF)
+		rte_stack_lf_init(s, count);
+	else
+		rte_stack_std_init(s);
 }
 
 static ssize_t
-rte_stack_get_memsize(unsigned int count)
+rte_stack_get_memsize(unsigned int count, uint32_t flags)
 {
-	return rte_stack_std_get_memsize(count);
+	if (flags & RTE_STACK_F_LF)
+		return rte_stack_lf_get_memsize(count);
+	else
+		return rte_stack_std_get_memsize(count);
 }
 
 struct rte_stack *
@@ -51,9 +58,16 @@ rte_stack_create(const char *name, unsigned int count, int socket_id,
 	unsigned int sz;
 	int ret;
 
-	RTE_SET_USED(flags);
+#ifdef RTE_ARCH_64
+	RTE_BUILD_BUG_ON(sizeof(struct rte_stack_lf_head) != 16);
+#else
+	if (flags & RTE_STACK_F_LF) {
+		STACK_LOG_ERR("Lock-free stack is not supported on your platform\n");
+		return NULL;
+	}
+#endif
 
-	sz = rte_stack_get_memsize(count);
+	sz = rte_stack_get_memsize(count, flags);
 
 	ret = snprintf(mz_name, sizeof(mz_name), "%s%s",
 		       RTE_STACK_MZ_PREFIX, name);
@@ -82,7 +96,7 @@ rte_stack_create(const char *name, unsigned int count, int socket_id,
 
 	s = mz->addr;
 
-	rte_stack_init(s);
+	rte_stack_init(s, count, flags);
 
 	/* Store the name for later lookups */
 	ret = snprintf(s->name, sizeof(s->name), "%s", name);
diff --git a/lib/librte_stack/rte_stack.h b/lib/librte_stack/rte_stack.h
index d9799d747..e0f9e9cff 100644
--- a/lib/librte_stack/rte_stack.h
+++ b/lib/librte_stack/rte_stack.h
@@ -30,6 +30,35 @@ extern "C" {
 #define RTE_STACK_NAMESIZE (RTE_MEMZONE_NAMESIZE - \
 			   sizeof(RTE_STACK_MZ_PREFIX) + 1)
 
+struct rte_stack_lf_elem {
+	void *data;			/**< Data pointer */
+	struct rte_stack_lf_elem *next;	/**< Next pointer */
+};
+
+struct rte_stack_lf_head {
+	struct rte_stack_lf_elem *top; /**< Stack top */
+	uint64_t cnt; /**< Modification counter for avoiding ABA problem */
+};
+
+struct rte_stack_lf_list {
+	/** List head */
+	struct rte_stack_lf_head head __rte_aligned(16);
+	/** List len */
+	rte_atomic64_t len;
+};
+
+/* Structure containing two lock-free LIFO lists: the stack itself and a list
+ * of free linked-list elements.
+ */
+struct rte_stack_lf {
+	/** LIFO list of elements */
+	struct rte_stack_lf_list used __rte_cache_aligned;
+	/** LIFO list of free elements */
+	struct rte_stack_lf_list free __rte_cache_aligned;
+	/** LIFO elements */
+	struct rte_stack_lf_elem elems[] __rte_cache_aligned;
+};
+
 /* Structure containing the LIFO, its current length, and a lock for mutual
  * exclusion.
  */
@@ -49,10 +78,21 @@ struct rte_stack {
 	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_STD_C11
+	union {
+		struct rte_stack_lf stack_lf; /**< Lock-free LIFO structure. */
+		struct rte_stack_std stack_std;	/**< LIFO structure. */
+	};
 } __rte_cache_aligned;
 
+/**
+ * The stack uses lock-free push and pop functions. This flag is only
+ * supported on x86_64 platforms, currently.
+ */
+#define RTE_STACK_F_LF 0x0001
+
 #include "rte_stack_std.h"
+#include "rte_stack_lf.h"
 
 /**
  * @warning
@@ -75,7 +115,10 @@ 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);
+	if (s->flags & RTE_STACK_F_LF)
+		return __rte_stack_lf_push(s, obj_table, n);
+	else
+		return __rte_stack_std_push(s, obj_table, n);
 }
 
 /**
@@ -99,7 +142,10 @@ 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);
+	if (s->flags & RTE_STACK_F_LF)
+		return __rte_stack_lf_pop(s, obj_table, n);
+	else
+		return __rte_stack_std_pop(s, obj_table, n);
 }
 
 /**
@@ -118,7 +164,10 @@ rte_stack_count(struct rte_stack *s)
 {
 	RTE_ASSERT(s != NULL);
 
-	return __rte_stack_std_count(s);
+	if (s->flags & RTE_STACK_F_LF)
+		return __rte_stack_lf_count(s);
+	else
+		return __rte_stack_std_count(s);
 }
 
 /**
@@ -158,7 +207,10 @@ rte_stack_free_count(struct rte_stack *s)
  *   NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA
  *   constraint for the reserved zone.
  * @param flags
- *   Reserved for future use.
+ *   An OR of the following:
+ *    - RTE_STACK_F_LF: If this flag is set, the stack uses lock-free
+ *      variants of the push and pop functions. Otherwise, it achieves
+ *      thread-safety using a lock.
  * @return
  *   On success, the pointer to the new allocated stack. NULL on error with
  *    rte_errno set appropriately. Possible errno values include:
diff --git a/lib/librte_stack/rte_stack_lf.c b/lib/librte_stack/rte_stack_lf.c
new file mode 100644
index 000000000..0adcc263e
--- /dev/null
+++ b/lib/librte_stack/rte_stack_lf.c
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#include "rte_stack.h"
+
+void
+rte_stack_lf_init(struct rte_stack *s, unsigned int count)
+{
+	struct rte_stack_lf_elem *elems = s->stack_lf.elems;
+	unsigned int i;
+
+	for (i = 0; i < count; i++)
+		__rte_stack_lf_push_elems(&s->stack_lf.free,
+					  &elems[i], &elems[i], 1);
+}
+
+ssize_t
+rte_stack_lf_get_memsize(unsigned int count)
+{
+	ssize_t sz = sizeof(struct rte_stack);
+
+	sz += RTE_CACHE_LINE_ROUNDUP(count * sizeof(struct rte_stack_lf_elem));
+
+	/* 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_lf.h b/lib/librte_stack/rte_stack_lf.h
new file mode 100644
index 000000000..bfd680133
--- /dev/null
+++ b/lib/librte_stack/rte_stack_lf.h
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#ifndef _RTE_STACK_LF_H_
+#define _RTE_STACK_LF_H_
+
+#include "rte_stack_lf_generic.h"
+
+/**
+ * @internal Push several objects on the lock-free 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 enqueued.
+ */
+static __rte_always_inline unsigned int __rte_experimental
+__rte_stack_lf_push(struct rte_stack *s,
+		    void * const *obj_table,
+		    unsigned int n)
+{
+	struct rte_stack_lf_elem *tmp, *first, *last = NULL;
+	unsigned int i;
+
+	if (unlikely(n == 0))
+		return 0;
+
+	/* Pop n free elements */
+	first = __rte_stack_lf_pop_elems(&s->stack_lf.free, n, NULL, &last);
+	if (unlikely(first == NULL))
+		return 0;
+
+	/* Construct the list elements */
+	for (tmp = first, i = 0; i < n; i++, tmp = tmp->next)
+		tmp->data = obj_table[n - i - 1];
+
+	/* Push them to the used list */
+	__rte_stack_lf_push_elems(&s->stack_lf.used, first, last, n);
+
+	return n;
+}
+
+/**
+ * @internal Pop several objects from the lock-free 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.
+ */
+static __rte_always_inline unsigned int __rte_experimental
+__rte_stack_lf_pop(struct rte_stack *s, void **obj_table, unsigned int n)
+{
+	struct rte_stack_lf_elem *first, *last = NULL;
+
+	if (unlikely(n == 0))
+		return 0;
+
+	/* Pop n used elements */
+	first = __rte_stack_lf_pop_elems(&s->stack_lf.used,
+					 n, obj_table, &last);
+	if (unlikely(first == NULL))
+		return 0;
+
+	/* Push the list elements to the free list */
+	__rte_stack_lf_push_elems(&s->stack_lf.free, first, last, n);
+
+	return n;
+}
+
+/**
+ * @internal Initialize a lock-free stack.
+ *
+ * @param s
+ *   A pointer to the stack structure.
+ * @param count
+ *   The size of the stack.
+ */
+void
+rte_stack_lf_init(struct rte_stack *s, unsigned int count);
+
+/**
+ * @internal Return the memory required for a lock-free stack.
+ *
+ * @param count
+ *   The size of the stack.
+ * @return
+ *   The bytes to allocate for a lock-free stack.
+ */
+ssize_t
+rte_stack_lf_get_memsize(unsigned int count);
+
+#endif /* _RTE_STACK_LF_H_ */
diff --git a/lib/librte_stack/rte_stack_lf_generic.h b/lib/librte_stack/rte_stack_lf_generic.h
new file mode 100644
index 000000000..0ce282226
--- /dev/null
+++ b/lib/librte_stack/rte_stack_lf_generic.h
@@ -0,0 +1,151 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#ifndef _RTE_STACK_LF_GENERIC_H_
+#define _RTE_STACK_LF_GENERIC_H_
+
+#include <rte_branch_prediction.h>
+#include <rte_prefetch.h>
+
+static __rte_always_inline unsigned int
+__rte_stack_lf_count(struct rte_stack *s)
+{
+	/* stack_lf_push() and stack_lf_pop() do not update the list's contents
+	 * and stack_lf->len atomically, which can cause the list to appear
+	 * shorter than it actually is if this function is called while other
+	 * threads are modifying the list.
+	 *
+	 * However, given the inherently approximate nature of the get_count
+	 * callback -- even if the list and its size were updated atomically,
+	 * the size could change between when get_count executes and when the
+	 * value is returned to the caller -- this is acceptable.
+	 *
+	 * The stack_lf->len updates are placed such that the list may appear to
+	 * have fewer elements than it does, but will never appear to have more
+	 * elements. If the mempool is near-empty to the point that this is a
+	 * concern, the user should consider increasing the mempool size.
+	 */
+	return (unsigned int)rte_atomic64_read(&s->stack_lf.used.len);
+}
+
+static __rte_always_inline void
+__rte_stack_lf_push_elems(struct rte_stack_lf_list *list,
+			  struct rte_stack_lf_elem *first,
+			  struct rte_stack_lf_elem *last,
+			  unsigned int num)
+{
+#ifndef RTE_ARCH_X86_64
+	RTE_SET_USED(first);
+	RTE_SET_USED(last);
+	RTE_SET_USED(list);
+	RTE_SET_USED(num);
+#else
+	struct rte_stack_lf_head old_head;
+	int success;
+
+	old_head = list->head;
+
+	do {
+		struct rte_stack_lf_head new_head;
+
+		/* Swing the top pointer to the first element in the list and
+		 * make the last element point to the old top.
+		 */
+		new_head.top = first;
+		new_head.cnt = old_head.cnt + 1;
+
+		last->next = old_head.top;
+
+		/* old_head is updated on failure */
+		success = rte_atomic128_cmp_exchange(
+				(rte_int128_t *)&list->head,
+				(rte_int128_t *)&old_head,
+				(rte_int128_t *)&new_head,
+				1, __ATOMIC_RELEASE,
+				__ATOMIC_RELAXED);
+	} while (success == 0);
+
+	rte_atomic64_add(&list->len, num);
+#endif
+}
+
+static __rte_always_inline struct rte_stack_lf_elem *
+__rte_stack_lf_pop_elems(struct rte_stack_lf_list *list,
+			 unsigned int num,
+			 void **obj_table,
+			 struct rte_stack_lf_elem **last)
+{
+#ifndef RTE_ARCH_X86_64
+	RTE_SET_USED(obj_table);
+	RTE_SET_USED(last);
+	RTE_SET_USED(list);
+	RTE_SET_USED(num);
+
+	return NULL;
+#else
+	struct rte_stack_lf_head old_head;
+	int success;
+
+	/* Reserve num elements, if available */
+	while (1) {
+		uint64_t len = rte_atomic64_read(&list->len);
+
+		/* Does the list contain enough elements? */
+		if (unlikely(len < num))
+			return NULL;
+
+		if (rte_atomic64_cmpset((volatile uint64_t *)&list->len,
+					len, len - num))
+			break;
+	}
+
+	old_head = list->head;
+
+	/* Pop num elements */
+	do {
+		struct rte_stack_lf_head new_head;
+		struct rte_stack_lf_elem *tmp;
+		unsigned int i;
+
+		rte_prefetch0(old_head.top);
+
+		tmp = old_head.top;
+
+		/* Traverse the list to find the new head. A next pointer will
+		 * either point to another element or NULL; if a thread
+		 * encounters a pointer that has already been popped, the CAS
+		 * will fail.
+		 */
+		for (i = 0; i < num && tmp != NULL; i++) {
+			rte_prefetch0(tmp->next);
+			if (obj_table)
+				obj_table[i] = tmp->data;
+			if (last)
+				*last = tmp;
+			tmp = tmp->next;
+		}
+
+		/* If NULL was encountered, the list was modified while
+		 * traversing it. Retry.
+		 */
+		if (i != num)
+			continue;
+
+		new_head.top = tmp;
+		new_head.cnt = old_head.cnt + 1;
+
+		/* old_head is updated on failure */
+		success = rte_atomic128_cmp_exchange(
+				(rte_int128_t *)&list->head,
+				(rte_int128_t *)&old_head,
+				(rte_int128_t *)&new_head,
+				1, __ATOMIC_ACQUIRE,
+				__ATOMIC_ACQUIRE);
+	} while (success == 0);
+
+	return old_head.top;
+#endif
+}
+
+#endif /* _RTE_STACK_LF_GENERIC_H_ */
-- 
2.13.6


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

Thread overview: 228+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-22 16:06 [dpdk-dev] [PATCH 0/7] Subject: [PATCH ...] Add stack library and new mempool handler Gage Eads
2019-02-22 16:06 ` [dpdk-dev] [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 ` [dpdk-dev] [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 ` [dpdk-dev] [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 ` [dpdk-dev] [PATCH 4/7] test/stack: add stack perf test Gage Eads
2019-02-25 11:04   ` Olivier Matz
2019-02-22 16:06 ` [dpdk-dev] [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       ` [dpdk-dev] FW: " Eads, Gage
2019-03-01 21:12         ` Thomas Monjalon
2019-03-01 21:29           ` Eads, Gage
2019-02-22 16:06 ` [dpdk-dev] [PATCH 6/7] test/stack: add non-blocking stack tests Gage Eads
2019-02-25 11:28   ` Olivier Matz
2019-02-22 16:06 ` [dpdk-dev] [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 ` [dpdk-dev] [PATCH v2 0/8] Add stack library and new " Gage Eads
2019-03-05 16:42   ` [dpdk-dev] [PATCH v2 1/8] stack: introduce rte stack library Gage Eads
2019-03-05 16:42   ` [dpdk-dev] [PATCH v2 2/8] mempool/stack: convert mempool to use rte stack Gage Eads
2019-03-05 16:42   ` [dpdk-dev] [PATCH v2 3/8] test/stack: add stack test Gage Eads
2019-03-05 16:42   ` [dpdk-dev] [PATCH v2 4/8] test/stack: add stack perf test Gage Eads
2019-03-05 16:42   ` [dpdk-dev] [PATCH v2 5/8] stack: add lock-free stack implementation Gage Eads
2019-03-05 16:42   ` [dpdk-dev] [PATCH v2 6/8] stack: add C11 atomic implementation Gage Eads
2019-03-05 16:42   ` [dpdk-dev] [PATCH v2 7/8] test/stack: add lock-free stack tests Gage Eads
2019-03-05 16:42   ` [dpdk-dev] [PATCH v2 8/8] mempool/stack: add lock-free stack mempool handler Gage Eads
2019-03-06 14:45   ` [dpdk-dev] [PATCH v3 0/8] Add stack library and new " Gage Eads
2019-03-06 14:45     ` [dpdk-dev] [PATCH v3 1/8] stack: introduce rte stack library Gage Eads
2019-03-14  8:00       ` Olivier Matz
2019-03-14  8:00         ` Olivier Matz
2019-03-28 23:26       ` Honnappa Nagarahalli
2019-03-28 23:26         ` Honnappa Nagarahalli
2019-03-29 19:23         ` Eads, Gage
2019-03-29 19:23           ` Eads, Gage
2019-03-29 21:07           ` Thomas Monjalon
2019-03-29 21:07             ` Thomas Monjalon
2019-04-01 17:41           ` Honnappa Nagarahalli
2019-04-01 17:41             ` Honnappa Nagarahalli
2019-04-01 19:34             ` Eads, Gage
2019-04-01 19:34               ` Eads, Gage
2019-03-06 14:45     ` [dpdk-dev] [PATCH v3 2/8] mempool/stack: convert mempool to use rte stack Gage Eads
2019-03-06 14:45     ` [dpdk-dev] [PATCH v3 3/8] test/stack: add stack test Gage Eads
2019-03-14  8:00       ` Olivier Matz
2019-03-14  8:00         ` Olivier Matz
2019-03-06 14:45     ` [dpdk-dev] [PATCH v3 4/8] test/stack: add stack perf test Gage Eads
2019-03-06 14:45     ` [dpdk-dev] [PATCH v3 5/8] stack: add lock-free stack implementation Gage Eads
2019-03-14  8:01       ` Olivier Matz
2019-03-14  8:01         ` Olivier Matz
2019-03-28 23:27       ` Honnappa Nagarahalli
2019-03-28 23:27         ` Honnappa Nagarahalli
2019-03-29 19:25         ` Eads, Gage
2019-03-29 19:25           ` Eads, Gage
2019-03-06 14:45     ` [dpdk-dev] [PATCH v3 6/8] stack: add C11 atomic implementation Gage Eads
2019-03-14  8:04       ` Olivier Matz
2019-03-14  8:04         ` Olivier Matz
2019-03-28 23:27       ` Honnappa Nagarahalli
2019-03-28 23:27         ` Honnappa Nagarahalli
2019-03-29 19:24         ` Eads, Gage
2019-03-29 19:24           ` Eads, Gage
2019-04-01  0:06           ` Eads, Gage
2019-04-01  0:06             ` Eads, Gage
2019-04-01 19:06             ` Honnappa Nagarahalli
2019-04-01 19:06               ` Honnappa Nagarahalli
2019-04-01 20:21               ` Eads, Gage
2019-04-01 20:21                 ` Eads, Gage
2019-03-06 14:45     ` [dpdk-dev] [PATCH v3 7/8] test/stack: add lock-free stack tests Gage Eads
2019-03-06 14:45     ` [dpdk-dev] [PATCH v3 8/8] mempool/stack: add lock-free stack mempool handler Gage Eads
2019-03-28 18:00     ` [dpdk-dev] [PATCH v4 0/8] Add stack library and new " Gage Eads
2019-03-28 18:00       ` Gage Eads
2019-03-28 18:00       ` [dpdk-dev] [PATCH v4 1/8] stack: introduce rte stack library Gage Eads
2019-03-28 18:00         ` Gage Eads
2019-03-28 18:00       ` [dpdk-dev] [PATCH v4 2/8] mempool/stack: convert mempool to use rte stack Gage Eads
2019-03-28 18:00         ` Gage Eads
2019-03-28 18:00       ` [dpdk-dev] [PATCH v4 3/8] test/stack: add stack test Gage Eads
2019-03-28 18:00         ` Gage Eads
2019-03-28 18:00       ` [dpdk-dev] [PATCH v4 4/8] test/stack: add stack perf test Gage Eads
2019-03-28 18:00         ` Gage Eads
2019-03-28 18:00       ` [dpdk-dev] [PATCH v4 5/8] stack: add lock-free stack implementation Gage Eads
2019-03-28 18:00         ` Gage Eads
2019-03-28 18:00       ` [dpdk-dev] [PATCH v4 6/8] stack: add C11 atomic implementation Gage Eads
2019-03-28 18:00         ` Gage Eads
2019-03-28 18:00       ` [dpdk-dev] [PATCH v4 7/8] test/stack: add lock-free stack tests Gage Eads
2019-03-28 18:00         ` Gage Eads
2019-03-28 18:00       ` [dpdk-dev] [PATCH v4 8/8] mempool/stack: add lock-free stack mempool handler Gage Eads
2019-03-28 18:00         ` Gage Eads
2019-04-01  0:12       ` [dpdk-dev] [PATCH v5 0/8] Add stack library and new " Gage Eads
2019-04-01  0:12         ` Gage Eads
2019-04-01  0:12         ` [dpdk-dev] [PATCH v5 1/8] stack: introduce rte stack library Gage Eads
2019-04-01  0:12           ` Gage Eads
2019-04-01  0:12         ` [dpdk-dev] [PATCH v5 2/8] mempool/stack: convert mempool to use rte stack Gage Eads
2019-04-01  0:12           ` Gage Eads
2019-04-01  0:12         ` [dpdk-dev] [PATCH v5 3/8] test/stack: add stack test Gage Eads
2019-04-01  0:12           ` Gage Eads
2019-04-01  0:12         ` [dpdk-dev] [PATCH v5 4/8] test/stack: add stack perf test Gage Eads
2019-04-01  0:12           ` Gage Eads
2019-04-01  0:12         ` Gage Eads [this message]
2019-04-01  0:12           ` [dpdk-dev] [PATCH v5 5/8] stack: add lock-free stack implementation Gage Eads
2019-04-01 18:08           ` Honnappa Nagarahalli
2019-04-01 18:08             ` Honnappa Nagarahalli
2019-04-01  0:12         ` [dpdk-dev] [PATCH v5 6/8] stack: add C11 atomic implementation Gage Eads
2019-04-01  0:12           ` Gage Eads
2019-04-01  0:12         ` [dpdk-dev] [PATCH v5 7/8] test/stack: add lock-free stack tests Gage Eads
2019-04-01  0:12           ` Gage Eads
2019-04-01  0:12         ` [dpdk-dev] [PATCH v5 8/8] mempool/stack: add lock-free stack mempool handler Gage Eads
2019-04-01  0:12           ` Gage Eads
2019-04-01 21:14         ` [dpdk-dev] [PATCH v6 0/8] Add stack library and new " Gage Eads
2019-04-01 21:14           ` Gage Eads
2019-04-01 21:14           ` [dpdk-dev] [PATCH v6 1/8] stack: introduce rte stack library Gage Eads
2019-04-01 21:14             ` Gage Eads
2019-04-02 11:14             ` Honnappa Nagarahalli
2019-04-02 11:14               ` Honnappa Nagarahalli
2019-04-03 17:06               ` Thomas Monjalon
2019-04-03 17:06                 ` Thomas Monjalon
2019-04-03 17:13                 ` Eads, Gage
2019-04-03 17:13                   ` Eads, Gage
2019-04-03 17:23                   ` Thomas Monjalon
2019-04-03 17:23                     ` Thomas Monjalon
2019-04-01 21:14           ` [dpdk-dev] [PATCH v6 2/8] mempool/stack: convert mempool to use rte stack Gage Eads
2019-04-01 21:14             ` Gage Eads
2019-04-01 21:14           ` [dpdk-dev] [PATCH v6 3/8] test/stack: add stack test Gage Eads
2019-04-01 21:14             ` Gage Eads
2019-04-01 21:14           ` [dpdk-dev] [PATCH v6 4/8] test/stack: add stack perf test Gage Eads
2019-04-01 21:14             ` Gage Eads
2019-04-01 21:14           ` [dpdk-dev] [PATCH v6 5/8] stack: add lock-free stack implementation Gage Eads
2019-04-01 21:14             ` Gage Eads
2019-04-01 21:14           ` [dpdk-dev] [PATCH v6 6/8] stack: add C11 atomic implementation Gage Eads
2019-04-01 21:14             ` Gage Eads
2019-04-02 11:11             ` Honnappa Nagarahalli
2019-04-02 11:11               ` Honnappa Nagarahalli
2019-04-01 21:14           ` [dpdk-dev] [PATCH v6 7/8] test/stack: add lock-free stack tests Gage Eads
2019-04-01 21:14             ` Gage Eads
2019-04-01 21:14           ` [dpdk-dev] [PATCH v6 8/8] mempool/stack: add lock-free stack mempool handler Gage Eads
2019-04-01 21:14             ` Gage Eads
2019-04-03 17:04           ` [dpdk-dev] [PATCH v6 0/8] Add stack library and new " Thomas Monjalon
2019-04-03 17:04             ` Thomas Monjalon
2019-04-03 17:10             ` Eads, Gage
2019-04-03 17:10               ` Eads, Gage
2019-04-03 20:09           ` [dpdk-dev] [PATCH v7 " Gage Eads
2019-04-03 20:09             ` Gage Eads
2019-04-03 20:09             ` [dpdk-dev] [PATCH v7 1/8] stack: introduce rte stack library Gage Eads
2019-04-03 20:09               ` Gage Eads
2019-04-03 20:09             ` [dpdk-dev] [PATCH v7 2/8] mempool/stack: convert mempool to use rte stack Gage Eads
2019-04-03 20:09               ` Gage Eads
2019-04-03 20:09             ` [dpdk-dev] [PATCH v7 3/8] test/stack: add stack test Gage Eads
2019-04-03 20:09               ` Gage Eads
2019-04-03 20:09             ` [dpdk-dev] [PATCH v7 4/8] test/stack: add stack perf test Gage Eads
2019-04-03 20:09               ` Gage Eads
2019-04-03 20:09             ` [dpdk-dev] [PATCH v7 5/8] stack: add lock-free stack implementation Gage Eads
2019-04-03 20:09               ` Gage Eads
2019-04-03 20:09             ` [dpdk-dev] [PATCH v7 6/8] stack: add C11 atomic implementation Gage Eads
2019-04-03 20:09               ` Gage Eads
2019-04-03 20:09             ` [dpdk-dev] [PATCH v7 7/8] test/stack: add lock-free stack tests Gage Eads
2019-04-03 20:09               ` Gage Eads
2019-04-03 20:09             ` [dpdk-dev] [PATCH v7 8/8] mempool/stack: add lock-free stack mempool handler Gage Eads
2019-04-03 20:09               ` Gage Eads
2019-04-03 20:39             ` [dpdk-dev] [PATCH v7 0/8] Add stack library and new " Thomas Monjalon
2019-04-03 20:39               ` Thomas Monjalon
2019-04-03 20:49               ` Eads, Gage
2019-04-03 20:49                 ` Eads, Gage
2019-04-03 20:50             ` [dpdk-dev] [PATCH v8 " Gage Eads
2019-04-03 20:50               ` Gage Eads
2019-04-03 20:50               ` [dpdk-dev] [PATCH v8 1/8] stack: introduce rte stack library Gage Eads
2019-04-03 20:50                 ` Gage Eads
2019-04-03 20:50               ` [dpdk-dev] [PATCH v8 2/8] mempool/stack: convert mempool to use rte stack Gage Eads
2019-04-03 20:50                 ` Gage Eads
2019-04-03 20:50               ` [dpdk-dev] [PATCH v8 3/8] test/stack: add stack test Gage Eads
2019-04-03 20:50                 ` Gage Eads
2019-04-03 22:41                 ` Thomas Monjalon
2019-04-03 22:41                   ` Thomas Monjalon
2019-04-03 23:05                   ` Eads, Gage
2019-04-03 23:05                     ` Eads, Gage
2019-04-03 20:50               ` [dpdk-dev] [PATCH v8 4/8] test/stack: add stack perf test Gage Eads
2019-04-03 20:50                 ` Gage Eads
2019-04-03 20:50               ` [dpdk-dev] [PATCH v8 5/8] stack: add lock-free stack implementation Gage Eads
2019-04-03 20:50                 ` Gage Eads
2019-04-03 20:50               ` [dpdk-dev] [PATCH v8 6/8] stack: add C11 atomic implementation Gage Eads
2019-04-03 20:50                 ` Gage Eads
2019-04-03 20:50               ` [dpdk-dev] [PATCH v8 7/8] test/stack: add lock-free stack tests Gage Eads
2019-04-03 20:50                 ` Gage Eads
2019-04-03 20:50               ` [dpdk-dev] [PATCH v8 8/8] mempool/stack: add lock-free stack mempool handler Gage Eads
2019-04-03 20:50                 ` Gage Eads
2019-04-03 23:20               ` [dpdk-dev] [PATCH v9 0/8] Add stack library and new " Gage Eads
2019-04-03 23:20                 ` Gage Eads
2019-04-03 23:20                 ` [dpdk-dev] [PATCH v9 1/8] stack: introduce rte stack library Gage Eads
2019-04-03 23:20                   ` Gage Eads
2019-04-04 13:30                   ` Thomas Monjalon
2019-04-04 13:30                     ` Thomas Monjalon
2019-04-04 14:14                     ` Eads, Gage
2019-04-04 14:14                       ` Eads, Gage
2019-04-03 23:20                 ` [dpdk-dev] [PATCH v9 2/8] mempool/stack: convert mempool to use rte stack Gage Eads
2019-04-03 23:20                   ` Gage Eads
2019-04-03 23:20                 ` [dpdk-dev] [PATCH v9 3/8] test/stack: add stack test Gage Eads
2019-04-03 23:20                   ` Gage Eads
2019-04-04  7:34                   ` Thomas Monjalon
2019-04-04  7:34                     ` Thomas Monjalon
2019-04-03 23:20                 ` [dpdk-dev] [PATCH v9 4/8] test/stack: add stack perf test Gage Eads
2019-04-03 23:20                   ` Gage Eads
2019-04-03 23:20                 ` [dpdk-dev] [PATCH v9 5/8] stack: add lock-free stack implementation Gage Eads
2019-04-03 23:20                   ` Gage Eads
2019-04-03 23:20                 ` [dpdk-dev] [PATCH v9 6/8] stack: add C11 atomic implementation Gage Eads
2019-04-03 23:20                   ` Gage Eads
2019-04-03 23:20                 ` [dpdk-dev] [PATCH v9 7/8] test/stack: add lock-free stack tests Gage Eads
2019-04-03 23:20                   ` Gage Eads
2019-04-03 23:20                 ` [dpdk-dev] [PATCH v9 8/8] mempool/stack: add lock-free stack mempool handler Gage Eads
2019-04-03 23:20                   ` Gage Eads
2019-04-04 10:01                 ` [dpdk-dev] [PATCH v10 0/8] Add stack library and new " Gage Eads
2019-04-04 10:01                   ` Gage Eads
2019-04-04 10:01                   ` [dpdk-dev] [PATCH v10 1/8] stack: introduce rte stack library Gage Eads
2019-04-04 10:01                     ` Gage Eads
2019-04-04 10:01                   ` [dpdk-dev] [PATCH v10 2/8] mempool/stack: convert mempool to use rte stack Gage Eads
2019-04-04 10:01                     ` Gage Eads
2019-04-04 10:01                   ` [dpdk-dev] [PATCH v10 3/8] test/stack: add stack test Gage Eads
2019-04-04 10:01                     ` Gage Eads
2019-04-04 10:01                   ` [dpdk-dev] [PATCH v10 4/8] test/stack: add stack perf test Gage Eads
2019-04-04 10:01                     ` Gage Eads
2019-04-04 10:01                   ` [dpdk-dev] [PATCH v10 5/8] stack: add lock-free stack implementation Gage Eads
2019-04-04 10:01                     ` Gage Eads
2019-04-04 10:01                   ` [dpdk-dev] [PATCH v10 6/8] stack: add C11 atomic implementation Gage Eads
2019-04-04 10:01                     ` Gage Eads
2019-04-04 10:01                   ` [dpdk-dev] [PATCH v10 7/8] test/stack: add lock-free stack tests Gage Eads
2019-04-04 10:01                     ` Gage Eads
2019-04-04 10:01                   ` [dpdk-dev] [PATCH v10 8/8] mempool/stack: add lock-free stack mempool handler Gage Eads
2019-04-04 10:01                     ` Gage Eads
2019-04-04 15:42                   ` [dpdk-dev] [PATCH v10 0/8] Add stack library and new " Thomas Monjalon
2019-04-04 15:42                     ` 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-6-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).