From: Stephen Hemminger <stephen@networkplumber.org>
To: dev@dpdk.org
Cc: Stephen Hemminger <stephen@networkplumber.org>
Subject: [RFC 12/32] stack: always use C11 memory model implementation
Date: Wed, 29 Jul 2026 10:54:05 -0700 [thread overview]
Message-ID: <20260729175715.165120-13-stephen@networkplumber.org> (raw)
In-Reply-To: <20260729175715.165120-1-stephen@networkplumber.org>
The generic and C11 lock-free stack implementations differ only in
memory ordering. The generic version uses a full barrier where its
own comments state an acquire fence is sufficient, and seq_cst for
all length counter operations.
Only x86 and ThunderX still used the generic version. On x86 the
switch removes a locked add per CAS attempt in push and pop; TSO
provides the acquire semantics. On ThunderX the pop fence weakens
from dmb ish to dmb ishld and the push fence goes away. Unlike the
ring, no platform selected the generic stack for measured
performance reasons.
Remove it and use the C11 implementation everywhere.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/stack/meson.build | 1 -
lib/stack/rte_stack_lf.h | 4 -
lib/stack/rte_stack_lf_generic.h | 153 -------------------------------
3 files changed, 158 deletions(-)
delete mode 100644 lib/stack/rte_stack_lf_generic.h
diff --git a/lib/stack/meson.build b/lib/stack/meson.build
index 18177a742f..1fab46208f 100644
--- a/lib/stack/meson.build
+++ b/lib/stack/meson.build
@@ -7,7 +7,6 @@ headers = files('rte_stack.h')
indirect_headers += files(
'rte_stack_std.h',
'rte_stack_lf.h',
- 'rte_stack_lf_generic.h',
'rte_stack_lf_c11.h',
'rte_stack_lf_stubs.h',
)
diff --git a/lib/stack/rte_stack_lf.h b/lib/stack/rte_stack_lf.h
index f2b012cd0e..1bc6ee8f40 100644
--- a/lib/stack/rte_stack_lf.h
+++ b/lib/stack/rte_stack_lf.h
@@ -8,11 +8,7 @@
#if !(defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_ARM64))
#include "rte_stack_lf_stubs.h"
#else
-#ifdef RTE_USE_C11_MEM_MODEL
#include "rte_stack_lf_c11.h"
-#else
-#include "rte_stack_lf_generic.h"
-#endif
/**
* Indicates that RTE_STACK_F_LF is supported.
diff --git a/lib/stack/rte_stack_lf_generic.h b/lib/stack/rte_stack_lf_generic.h
deleted file mode 100644
index cc69e4d168..0000000000
--- a/lib/stack/rte_stack_lf_generic.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/* 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.
- */
- /* NOTE: review for potential ordering optimization */
- return rte_atomic_load_explicit(&s->stack_lf.used.len, rte_memory_order_seq_cst);
-}
-
-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)
-{
- struct rte_stack_lf_head old_head;
- int success;
-
- old_head = list->head;
-
- do {
- struct rte_stack_lf_head new_head;
-
- /* An acquire fence (or stronger) is needed for weak memory
- * models to establish a synchronized-with relationship between
- * the list->head load and store-release operations (as part of
- * the rte_atomic128_cmp_exchange()).
- */
- rte_smp_mb();
-
- /* 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, rte_memory_order_release,
- rte_memory_order_relaxed);
- } while (success == 0);
- /* NOTE: review for potential ordering optimization */
- rte_atomic_fetch_add_explicit(&list->len, num, rte_memory_order_seq_cst);
-}
-
-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)
-{
- struct rte_stack_lf_head old_head;
- int success = 0;
-
- /* Reserve num elements, if available */
- while (1) {
- /* NOTE: review for potential ordering optimization */
- uint64_t len = rte_atomic_load_explicit(&list->len, rte_memory_order_seq_cst);
-
- /* Does the list contain enough elements? */
- if (unlikely(len < num))
- return NULL;
-
- /* NOTE: review for potential ordering optimization */
- if (rte_atomic_compare_exchange_strong_explicit(&list->len, &len, len - num,
- rte_memory_order_seq_cst, rte_memory_order_seq_cst))
- 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;
-
- /* An acquire fence (or stronger) is needed for weak memory
- * models to ensure the LF LIFO element reads are properly
- * ordered with respect to the head pointer read.
- */
- rte_smp_mb();
-
- 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) {
- old_head = list->head;
- 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, rte_memory_order_release,
- rte_memory_order_relaxed);
- } while (success == 0);
-
- return old_head.top;
-}
-
-#endif /* _RTE_STACK_LF_GENERIC_H_ */
--
2.53.0
next prev parent reply other threads:[~2026-07-29 17:58 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-29 17:53 [RFC 00/32] remove rte_smp barrier functions Stephen Hemminger
2026-07-29 17:53 ` [RFC 01/32] bpf: replace deprecated SMP barriers with C11 fences Stephen Hemminger
2026-07-29 17:53 ` [RFC 02/32] test: remove test for rte_smp_mb Stephen Hemminger
2026-07-29 17:53 ` [RFC 03/32] bus/vmbus: fix ring buffer ordering on weakly ordered CPUs Stephen Hemminger
2026-07-29 17:53 ` [RFC 04/32] bus/vmbus: fix missing acquire on receive ring index Stephen Hemminger
2026-07-29 17:53 ` [RFC 05/32] bus/vmbus: replace SMP barriers with C11 memory fences Stephen Hemminger
2026-07-29 17:53 ` [RFC 06/32] baseband: convert rte_smp_rmb to fence Stephen Hemminger
2026-07-29 17:54 ` [RFC 07/32] net/hinic: replace rte_smp_rmb Stephen Hemminger
2026-07-29 17:54 ` [RFC 08/32] net/intel: " Stephen Hemminger
2026-07-29 17:54 ` [RFC 09/32] crypto_caam_jr: " Stephen Hemminger
2026-07-29 17:54 ` [RFC 10/32] net/virtio: replcae rte_smp_rmb Stephen Hemminger
2026-07-29 17:54 ` [RFC 11/32] net/thunderx: replace rte_smp_rmb Stephen Hemminger
2026-07-29 17:54 ` Stephen Hemminger [this message]
2026-07-29 17:54 ` [RFC 13/32] ring: replace SMP read barrier with C11 acquire fence Stephen Hemminger
2026-07-29 17:54 ` [RFC 14/32] crypto/virtio: update comment reference to rte_smp_rmb Stephen Hemminger
2026-07-29 17:54 ` [RFC 15/32] event/sw: fix unlinks in progress counter races Stephen Hemminger
2026-07-29 17:54 ` [RFC 16/32] event/sw: replace SMP barriers with C11 atomics Stephen Hemminger
2026-07-29 17:54 ` [RFC 17/32] eal/x86: move optimized fence out of SMP barrier Stephen Hemminger
2026-07-29 17:54 ` [RFC 18/32] common/octeontx: remove redundant barrier in mbox Stephen Hemminger
2026-07-29 17:54 ` [RFC 19/32] crypto/caam_jr: use IO barrier before job ring doorbell Stephen Hemminger
2026-07-29 17:54 ` [RFC 20/32] crypto/octeontx: use IO barrier before doorbell Stephen Hemminger
2026-07-29 17:54 ` [RFC 21/32] mempool/octeontx: use IO barrier in pool destroy Stephen Hemminger
2026-07-29 17:54 ` [RFC 22/32] event/octeontx: replace deprecated SMP barriers Stephen Hemminger
2026-07-29 17:54 ` [RFC 23/32] event/dpaa2: replace deprecated barrier in selftest Stephen Hemminger
2026-07-29 17:54 ` [RFC 24/32] event/dsw: replace SMP barriers with release fences Stephen Hemminger
2026-07-29 17:54 ` [RFC 25/32] event/opdl: replace SMP barriers with C11 atomics Stephen Hemminger
2026-07-29 17:54 ` [RFC 26/32] net/netvsc: replace SMP barrier in RNDIS response Stephen Hemminger
2026-07-29 17:54 ` [RFC 27/32] net/thunderx: replace deprecated SMP barriers Stephen Hemminger
2026-07-29 17:54 ` [RFC 28/32] net/virtio: replace deprecated barrier in avail index update Stephen Hemminger
2026-07-29 17:54 ` [RFC 29/32] eal: remove stale SMP barrier in rte_service Stephen Hemminger
2026-07-29 17:54 ` [RFC 30/32] eal: remove rte_smp_XX Stephen Hemminger
2026-07-29 17:54 ` [RFC 31/32] checkpatches: no longer warn about rte_smp_XX Stephen Hemminger
2026-07-29 17:54 ` [RFC 32/32] doc: update release notes about rte_smp_XX removal Stephen Hemminger
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=20260729175715.165120-13-stephen@networkplumber.org \
--to=stephen@networkplumber.org \
--cc=dev@dpdk.org \
/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