* [PATCH] spinlock: remove volatile qualifier
@ 2026-05-04 8:37 Thomas Monjalon
2026-05-04 9:06 ` Thomas Monjalon
` (3 more replies)
0 siblings, 4 replies; 25+ messages in thread
From: Thomas Monjalon @ 2026-05-04 8:37 UTC (permalink / raw)
To: dev; +Cc: stable
The user and count fields of rte_spinlock_recursive_t
do not need the volatile qualifier
because they are only accessed by the thread holding the lock,
which already provides the necessary memory ordering.
Removing volatile aligns with a C++20 deprecation
for increment and decrement of volatile variables.
This issue was seen with GCC 16 which changes the default C++ version
from -std=gnu++17 to -std=gnu++20.
Fixes: af75078fece3 ("first public release")
Cc: stable@dpdk.org
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
lib/eal/include/generic/rte_spinlock.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/eal/include/generic/rte_spinlock.h b/lib/eal/include/generic/rte_spinlock.h
index c907d4e45c..19c0e34f0a 100644
--- a/lib/eal/include/generic/rte_spinlock.h
+++ b/lib/eal/include/generic/rte_spinlock.h
@@ -197,8 +197,8 @@ rte_spinlock_trylock_tm(rte_spinlock_t *sl)
*/
typedef struct {
rte_spinlock_t sl; /**< the actual spinlock */
- volatile int user; /**< core id using lock, -1 for unused */
- volatile int count; /**< count of time this lock has been called */
+ int user; /**< core id using lock, -1 for unused */
+ int count; /**< count of time this lock has been called */
} rte_spinlock_recursive_t;
/**
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH] spinlock: remove volatile qualifier
2026-05-04 8:37 [PATCH] spinlock: remove volatile qualifier Thomas Monjalon
@ 2026-05-04 9:06 ` Thomas Monjalon
2026-05-04 9:12 ` [PATCH] spinlock: fix API comments Thomas Monjalon
2026-05-18 13:57 ` [PATCH] spinlock: remove volatile qualifier Thomas Monjalon
2026-05-04 17:02 ` Stephen Hemminger
` (2 subsequent siblings)
3 siblings, 2 replies; 25+ messages in thread
From: Thomas Monjalon @ 2026-05-04 9:06 UTC (permalink / raw)
To: dev; +Cc: stable, Stephen Hemminger, Konstantin Ananyev
04/05/2026 10:37, Thomas Monjalon:
> The user and count fields of rte_spinlock_recursive_t
> do not need the volatile qualifier
> because they are only accessed by the thread holding the lock,
> which already provides the necessary memory ordering.
>
> Removing volatile aligns with a C++20 deprecation
> for increment and decrement of volatile variables.
>
> This issue was seen with GCC 16 which changes the default C++ version
> from -std=gnu++17 to -std=gnu++20.
>
> Fixes: af75078fece3 ("first public release")
> Cc: stable@dpdk.org
>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
I've just found this has been discussed 4 years ago:
https://inbox.dpdk.org/dev/20221221083717.135c3f81@hermes.local
Stephen had found some comments issues that I will fix in another patch.
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH] spinlock: fix API comments
2026-05-04 9:06 ` Thomas Monjalon
@ 2026-05-04 9:12 ` Thomas Monjalon
2026-05-04 12:46 ` Thomas Monjalon
2026-05-18 13:57 ` [PATCH] spinlock: remove volatile qualifier Thomas Monjalon
1 sibling, 1 reply; 25+ messages in thread
From: Thomas Monjalon @ 2026-05-04 9:12 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
This is not a read-write lock.
The user field stores the thread ID, not the core ID.
The implementation is architecture-specific in some cases only.
Reported-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
lib/eal/include/generic/rte_spinlock.h | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/lib/eal/include/generic/rte_spinlock.h b/lib/eal/include/generic/rte_spinlock.h
index 19c0e34f0a..d9f255f8c4 100644
--- a/lib/eal/include/generic/rte_spinlock.h
+++ b/lib/eal/include/generic/rte_spinlock.h
@@ -7,12 +7,16 @@
/**
* @file
+ * DPDK spinlocks
*
- * RTE Spinlocks
+ * This is an API for spinlocks.
+ * This kind of lock simply waits in a loop
+ * repeatedly checking until the lock becomes available.
*
- * This file defines an API for read-write locks, which are implemented
- * in an architecture-specific way. This kind of lock simply waits in
- * a loop repeatedly checking until the lock becomes available.
+ * Some functions may have an architecture-specific implementation
+ * if RTE_FORCE_INTRINSICS is disabled.
+ * The hardware transactional memory (lock elision) functions have _tm suffix
+ * and are implemented in architecture-specific files.
*
* All locks must be initialised before use, and only initialised once.
*/
@@ -197,7 +201,7 @@ rte_spinlock_trylock_tm(rte_spinlock_t *sl)
*/
typedef struct {
rte_spinlock_t sl; /**< the actual spinlock */
- int user; /**< core id using lock, -1 for unused */
+ int user; /**< thread id using lock, -1 for unused */
int count; /**< count of time this lock has been called */
} rte_spinlock_recursive_t;
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH] spinlock: fix API comments
2026-05-04 9:12 ` [PATCH] spinlock: fix API comments Thomas Monjalon
@ 2026-05-04 12:46 ` Thomas Monjalon
0 siblings, 0 replies; 25+ messages in thread
From: Thomas Monjalon @ 2026-05-04 12:46 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
04/05/2026 11:12, Thomas Monjalon:
> This is not a read-write lock.
>
> The user field stores the thread ID, not the core ID.
>
> The implementation is architecture-specific in some cases only.
>
> Reported-by: Stephen Hemminger <stephen@networkplumber.org>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
Fixes: ca2e2dab079a ("spinlock: support non-EAL thread")
Fixes: af75078fece3 ("first public release")
Cc: stable@dpdk.org
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH] spinlock: remove volatile qualifier
2026-05-04 8:37 [PATCH] spinlock: remove volatile qualifier Thomas Monjalon
2026-05-04 9:06 ` Thomas Monjalon
@ 2026-05-04 17:02 ` Stephen Hemminger
2026-05-05 7:01 ` Thomas Monjalon
2026-05-18 15:07 ` [PATCH v2 1/2] " Thomas Monjalon
2026-05-19 10:34 ` [PATCH v3 1/3] " Thomas Monjalon
3 siblings, 1 reply; 25+ messages in thread
From: Stephen Hemminger @ 2026-05-04 17:02 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev, stable
On Mon, 4 May 2026 10:37:14 +0200
Thomas Monjalon <thomas@monjalon.net> wrote:
> diff --git a/lib/eal/include/generic/rte_spinlock.h b/lib/eal/include/generic/rte_spinlock.h
> index c907d4e45c..19c0e34f0a 100644
> --- a/lib/eal/include/generic/rte_spinlock.h
> +++ b/lib/eal/include/generic/rte_spinlock.h
> @@ -197,8 +197,8 @@ rte_spinlock_trylock_tm(rte_spinlock_t *sl)
> */
> typedef struct {
> rte_spinlock_t sl; /**< the actual spinlock */
> - volatile int user; /**< core id using lock, -1 for unused */
> - volatile int count; /**< count of time this lock has been called */
> + int user; /**< core id using lock, -1 for unused */
> + int count; /**< count of time this lock has been called */
It might make sense to use unsigned for count, and sized types.
I.e do you really need 32 bit values?
Only in tree use of recursive spinlock in vdev code.
PS: I wonder if we really need to keep the transactional memory versions of stuff.
I
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH] spinlock: remove volatile qualifier
2026-05-04 17:02 ` Stephen Hemminger
@ 2026-05-05 7:01 ` Thomas Monjalon
2026-05-05 13:24 ` Stephen Hemminger
0 siblings, 1 reply; 25+ messages in thread
From: Thomas Monjalon @ 2026-05-05 7:01 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev, stable
04/05/2026 19:02, Stephen Hemminger:
> On Mon, 4 May 2026 10:37:14 +0200
> Thomas Monjalon <thomas@monjalon.net> wrote:
>
> > diff --git a/lib/eal/include/generic/rte_spinlock.h b/lib/eal/include/generic/rte_spinlock.h
> > index c907d4e45c..19c0e34f0a 100644
> > --- a/lib/eal/include/generic/rte_spinlock.h
> > +++ b/lib/eal/include/generic/rte_spinlock.h
> > @@ -197,8 +197,8 @@ rte_spinlock_trylock_tm(rte_spinlock_t *sl)
> > */
> > typedef struct {
> > rte_spinlock_t sl; /**< the actual spinlock */
> > - volatile int user; /**< core id using lock, -1 for unused */
> > - volatile int count; /**< count of time this lock has been called */
> > + int user; /**< core id using lock, -1 for unused */
> > + int count; /**< count of time this lock has been called */
>
> It might make sense to use unsigned for count, and sized types.
> I.e do you really need 32 bit values?
Such a change would need to be evaluated in a performance benchmark.
> Only in tree use of recursive spinlock in vdev code.
>
> PS: I wonder if we really need to keep the transactional memory versions of stuff.
I don't know, it's part of the API and has no maintenance cost.
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH] spinlock: remove volatile qualifier
2026-05-05 7:01 ` Thomas Monjalon
@ 2026-05-05 13:24 ` Stephen Hemminger
0 siblings, 0 replies; 25+ messages in thread
From: Stephen Hemminger @ 2026-05-05 13:24 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev, stable
On Tue, 05 May 2026 09:01:43 +0200
Thomas Monjalon <thomas@monjalon.net> wrote:
> > PS: I wonder if we really need to keep the transactional memory versions of stuff.
>
> I don't know, it's part of the API and has no maintenance cost.
It is not tested, only worked on x86 and most of the CPU's and tooling
dropped support for transactional memory years ago. It was a failed idea.
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH] spinlock: remove volatile qualifier
2026-05-04 9:06 ` Thomas Monjalon
2026-05-04 9:12 ` [PATCH] spinlock: fix API comments Thomas Monjalon
@ 2026-05-18 13:57 ` Thomas Monjalon
1 sibling, 0 replies; 25+ messages in thread
From: Thomas Monjalon @ 2026-05-18 13:57 UTC (permalink / raw)
To: dev; +Cc: stable, Stephen Hemminger, Konstantin Ananyev
04/05/2026 11:06, Thomas Monjalon:
> 04/05/2026 10:37, Thomas Monjalon:
> > The user and count fields of rte_spinlock_recursive_t
> > do not need the volatile qualifier
> > because they are only accessed by the thread holding the lock,
> > which already provides the necessary memory ordering.
> >
> > Removing volatile aligns with a C++20 deprecation
> > for increment and decrement of volatile variables.
> >
> > This issue was seen with GCC 16 which changes the default C++ version
> > from -std=gnu++17 to -std=gnu++20.
> >
> > Fixes: af75078fece3 ("first public release")
> > Cc: stable@dpdk.org
> >
> > Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
>
> I've just found this has been discussed 4 years ago:
> https://inbox.dpdk.org/dev/20221221083717.135c3f81@hermes.local
>
> Stephen had found some comments issues that I will fix in another patch.
Adding the compiler messages:
rte_spinlock.h:241:14: error: '++' expression of 'volatile'-qualified type is deprecated [-Werror=volatile]
rte_spinlock.h:252:21: error: '--' expression of 'volatile'-qualified type is deprecated [-Werror=volatile]
rte_spinlock.h:278:14: error: '++' expression of 'volatile'-qualified type is deprecated [-Werror=volatile]
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 1/2] spinlock: remove volatile qualifier
2026-05-04 8:37 [PATCH] spinlock: remove volatile qualifier Thomas Monjalon
2026-05-04 9:06 ` Thomas Monjalon
2026-05-04 17:02 ` Stephen Hemminger
@ 2026-05-18 15:07 ` Thomas Monjalon
2026-05-18 15:07 ` [PATCH v2 2/2] spinlock: fix API comments Thomas Monjalon
` (2 more replies)
2026-05-19 10:34 ` [PATCH v3 1/3] " Thomas Monjalon
3 siblings, 3 replies; 25+ messages in thread
From: Thomas Monjalon @ 2026-05-18 15:07 UTC (permalink / raw)
To: dev
Cc: Stephen Hemminger, Konstantin Ananyev, Bruce Richardson,
Robin Jarry, stable
When compiling with C++20 standard requirement (default in GCC 16),
the increment and decrement of volatile variables are rejected:
rte_spinlock.h:241:14: error:
'++' expression of 'volatile'-qualified type is deprecated
rte_spinlock.h:252:21: error:
'--' expression of 'volatile'-qualified type is deprecated
rte_spinlock.h:278:14: error:
'++' expression of 'volatile'-qualified type is deprecated
The count field of rte_spinlock_recursive_t
does not need the volatile qualifier
because it is only accessed by the thread holding the lock,
which already provides the necessary memory ordering.
The user field can be accessed outside of the lock,
so it must handled as a C11 atomic variable.
Fixes: af75078fece3 ("first public release")
Cc: stable@dpdk.org
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
v1: drop volatile keyword
v2: make user an atomic variable
---
lib/eal/include/generic/rte_spinlock.h | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/lib/eal/include/generic/rte_spinlock.h b/lib/eal/include/generic/rte_spinlock.h
index c907d4e45c..5d810b682a 100644
--- a/lib/eal/include/generic/rte_spinlock.h
+++ b/lib/eal/include/generic/rte_spinlock.h
@@ -197,8 +197,8 @@ rte_spinlock_trylock_tm(rte_spinlock_t *sl)
*/
typedef struct {
rte_spinlock_t sl; /**< the actual spinlock */
- volatile int user; /**< core id using lock, -1 for unused */
- volatile int count; /**< count of time this lock has been called */
+ RTE_ATOMIC(int) user; /**< core id using lock, -1 for unused */
+ int count; /**< count of time this lock has been called */
} rte_spinlock_recursive_t;
/**
@@ -215,7 +215,7 @@ typedef struct {
static inline void rte_spinlock_recursive_init(rte_spinlock_recursive_t *slr)
{
rte_spinlock_init(&slr->sl);
- slr->user = -1;
+ rte_atomic_store_explicit(&slr->user, -1, rte_memory_order_relaxed);
slr->count = 0;
}
@@ -230,9 +230,9 @@ static inline void rte_spinlock_recursive_lock(rte_spinlock_recursive_t *slr)
{
int id = rte_gettid();
- if (slr->user != id) {
+ if (rte_atomic_load_explicit(&slr->user, rte_memory_order_relaxed) != id) {
rte_spinlock_lock(&slr->sl);
- slr->user = id;
+ rte_atomic_store_explicit(&slr->user, id, rte_memory_order_relaxed);
}
slr->count++;
}
@@ -246,10 +246,9 @@ static inline void rte_spinlock_recursive_unlock(rte_spinlock_recursive_t *slr)
__rte_no_thread_safety_analysis
{
if (--(slr->count) == 0) {
- slr->user = -1;
+ rte_atomic_store_explicit(&slr->user, -1, rte_memory_order_relaxed);
rte_spinlock_unlock(&slr->sl);
}
-
}
/**
@@ -266,10 +265,10 @@ static inline int rte_spinlock_recursive_trylock(rte_spinlock_recursive_t *slr)
{
int id = rte_gettid();
- if (slr->user != id) {
+ if (rte_atomic_load_explicit(&slr->user, rte_memory_order_relaxed) != id) {
if (rte_spinlock_trylock(&slr->sl) == 0)
return 0;
- slr->user = id;
+ rte_atomic_store_explicit(&slr->user, id, rte_memory_order_relaxed);
}
slr->count++;
return 1;
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 2/2] spinlock: fix API comments
2026-05-18 15:07 ` [PATCH v2 1/2] " Thomas Monjalon
@ 2026-05-18 15:07 ` Thomas Monjalon
2026-05-18 15:14 ` [PATCH v2 1/2] spinlock: remove volatile qualifier Robin Jarry
2026-05-18 16:28 ` Stephen Hemminger
2 siblings, 0 replies; 25+ messages in thread
From: Thomas Monjalon @ 2026-05-18 15:07 UTC (permalink / raw)
To: dev
Cc: Stephen Hemminger, Konstantin Ananyev, Bruce Richardson,
Robin Jarry, stable, Olivier Matz, Cunming Liang
This is not a read-write lock.
The user field stores the thread ID, not the core ID
since a change in DPDK 2.0.0.
The implementation is architecture-specific in some cases only.
Fixes: ca2e2dab079a ("spinlock: support non-EAL thread")
Fixes: af75078fece3 ("first public release")
Cc: stable@dpdk.org
Reported-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
lib/eal/include/generic/rte_spinlock.h | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/lib/eal/include/generic/rte_spinlock.h b/lib/eal/include/generic/rte_spinlock.h
index 5d810b682a..5c46a7a90f 100644
--- a/lib/eal/include/generic/rte_spinlock.h
+++ b/lib/eal/include/generic/rte_spinlock.h
@@ -7,12 +7,16 @@
/**
* @file
+ * DPDK spinlocks
*
- * RTE Spinlocks
+ * This is an API for spinlocks.
+ * This kind of lock simply waits in a loop
+ * repeatedly checking until the lock becomes available.
*
- * This file defines an API for read-write locks, which are implemented
- * in an architecture-specific way. This kind of lock simply waits in
- * a loop repeatedly checking until the lock becomes available.
+ * Some functions may have an architecture-specific implementation
+ * if RTE_FORCE_INTRINSICS is disabled.
+ * The hardware transactional memory (lock elision) functions have _tm suffix
+ * and are implemented in architecture-specific files.
*
* All locks must be initialised before use, and only initialised once.
*/
@@ -197,7 +201,7 @@ rte_spinlock_trylock_tm(rte_spinlock_t *sl)
*/
typedef struct {
rte_spinlock_t sl; /**< the actual spinlock */
- RTE_ATOMIC(int) user; /**< core id using lock, -1 for unused */
+ RTE_ATOMIC(int) user; /**< thread id using lock, -1 for unused */
int count; /**< count of time this lock has been called */
} rte_spinlock_recursive_t;
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH v2 1/2] spinlock: remove volatile qualifier
2026-05-18 15:07 ` [PATCH v2 1/2] " Thomas Monjalon
2026-05-18 15:07 ` [PATCH v2 2/2] spinlock: fix API comments Thomas Monjalon
@ 2026-05-18 15:14 ` Robin Jarry
2026-05-18 15:25 ` Thomas Monjalon
2026-05-18 16:26 ` Stephen Hemminger
2026-05-18 16:28 ` Stephen Hemminger
2 siblings, 2 replies; 25+ messages in thread
From: Robin Jarry @ 2026-05-18 15:14 UTC (permalink / raw)
To: Thomas Monjalon, dev
Cc: Stephen Hemminger, Konstantin Ananyev, Bruce Richardson, stable
Hey Thomas,
Thomas Monjalon, May 18, 2026 at 17:07:
> When compiling with C++20 standard requirement (default in GCC 16),
> the increment and decrement of volatile variables are rejected:
>
> rte_spinlock.h:241:14: error:
> '++' expression of 'volatile'-qualified type is deprecated
> rte_spinlock.h:252:21: error:
> '--' expression of 'volatile'-qualified type is deprecated
> rte_spinlock.h:278:14: error:
> '++' expression of 'volatile'-qualified type is deprecated
>
> The count field of rte_spinlock_recursive_t
> does not need the volatile qualifier
> because it is only accessed by the thread holding the lock,
> which already provides the necessary memory ordering.
>
> The user field can be accessed outside of the lock,
> so it must handled as a C11 atomic variable.
>
> Fixes: af75078fece3 ("first public release")
> Cc: stable@dpdk.org
>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> ---
> v1: drop volatile keyword
> v2: make user an atomic variable
> ---
> lib/eal/include/generic/rte_spinlock.h | 17 ++++++++---------
> 1 file changed, 8 insertions(+), 9 deletions(-)
>
> diff --git a/lib/eal/include/generic/rte_spinlock.h b/lib/eal/include/generic/rte_spinlock.h
> index c907d4e45c..5d810b682a 100644
> --- a/lib/eal/include/generic/rte_spinlock.h
> +++ b/lib/eal/include/generic/rte_spinlock.h
> @@ -197,8 +197,8 @@ rte_spinlock_trylock_tm(rte_spinlock_t *sl)
> */
> typedef struct {
> rte_spinlock_t sl; /**< the actual spinlock */
> - volatile int user; /**< core id using lock, -1 for unused */
> - volatile int count; /**< count of time this lock has been called */
> + RTE_ATOMIC(int) user; /**< core id using lock, -1 for unused */
> + int count; /**< count of time this lock has been called */
> } rte_spinlock_recursive_t;
>
> /**
> @@ -215,7 +215,7 @@ typedef struct {
> static inline void rte_spinlock_recursive_init(rte_spinlock_recursive_t *slr)
> {
> rte_spinlock_init(&slr->sl);
> - slr->user = -1;
> + rte_atomic_store_explicit(&slr->user, -1, rte_memory_order_relaxed);
> slr->count = 0;
> }
>
> @@ -230,9 +230,9 @@ static inline void rte_spinlock_recursive_lock(rte_spinlock_recursive_t *slr)
> {
> int id = rte_gettid();
>
> - if (slr->user != id) {
> + if (rte_atomic_load_explicit(&slr->user, rte_memory_order_relaxed) != id) {
This needs to be rte_memory_order_acquire
> rte_spinlock_lock(&slr->sl);
> - slr->user = id;
> + rte_atomic_store_explicit(&slr->user, id, rte_memory_order_relaxed);
And rte_memory_order_release
> }
> slr->count++;
> }
> @@ -246,10 +246,9 @@ static inline void rte_spinlock_recursive_unlock(rte_spinlock_recursive_t *slr)
> __rte_no_thread_safety_analysis
> {
> if (--(slr->count) == 0) {
This code is completely broken. Any thread can unlock without any check.
I think it should be:
diff --git a/lib/eal/include/generic/rte_spinlock.h b/lib/eal/include/generic/rte_spinlock.h
index c907d4e45c39..b1058e4f8b4f 100644
--- a/lib/eal/include/generic/rte_spinlock.h
+++ b/lib/eal/include/generic/rte_spinlock.h
@@ -245,11 +247,17 @@ static inline void rte_spinlock_recursive_lock(rte_spinlock_recursive_t *slr)
static inline void rte_spinlock_recursive_unlock(rte_spinlock_recursive_t *slr)
__rte_no_thread_safety_analysis
{
- if (--(slr->count) == 0) {
- slr->user = -1;
- rte_spinlock_unlock(&slr->sl);
- }
+ int id = rte_gettid();
+ if (rte_atomic_load_explicit(&slr->user, rte_memory_order_acquire) == id) {
+ RTE_ASSERT(slr->count > 0);
+ if (--(slr->count) == 0) {
+ rte_atomic_store_explicit(&slr->user, -1, rte_memory_order_release);
+ rte_spinlock_unlock(&slr->sl);
+ }
+ } else {
+ RTE_ASSERT(id != -1 && "unlocked from another thread");
+ }
}
(not tested)
> - slr->user = -1;
> + rte_atomic_store_explicit(&slr->user, -1, rte_memory_order_relaxed);
> rte_spinlock_unlock(&slr->sl);
> }
> -
> }
>
> /**
> @@ -266,10 +265,10 @@ static inline int rte_spinlock_recursive_trylock(rte_spinlock_recursive_t *slr)
> {
> int id = rte_gettid();
>
> - if (slr->user != id) {
> + if (rte_atomic_load_explicit(&slr->user, rte_memory_order_relaxed) != id) {
rte_memory_order_acquire
> if (rte_spinlock_trylock(&slr->sl) == 0)
> return 0;
> - slr->user = id;
> + rte_atomic_store_explicit(&slr->user, id, rte_memory_order_relaxed);
rte_memory_order_release
> }
> slr->count++;
> return 1;
--
Robin
> Monitored by the American Human Association.
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH v2 1/2] spinlock: remove volatile qualifier
2026-05-18 15:14 ` [PATCH v2 1/2] spinlock: remove volatile qualifier Robin Jarry
@ 2026-05-18 15:25 ` Thomas Monjalon
2026-05-18 15:28 ` Bruce Richardson
2026-05-18 16:26 ` Stephen Hemminger
1 sibling, 1 reply; 25+ messages in thread
From: Thomas Monjalon @ 2026-05-18 15:25 UTC (permalink / raw)
To: Robin Jarry
Cc: dev, Stephen Hemminger, Konstantin Ananyev, Bruce Richardson,
stable
18/05/2026 17:14, Robin Jarry:
> Hey Thomas,
>
> Thomas Monjalon, May 18, 2026 at 17:07:
> > When compiling with C++20 standard requirement (default in GCC 16),
> > the increment and decrement of volatile variables are rejected:
> >
> > rte_spinlock.h:241:14: error:
> > '++' expression of 'volatile'-qualified type is deprecated
> > rte_spinlock.h:252:21: error:
> > '--' expression of 'volatile'-qualified type is deprecated
> > rte_spinlock.h:278:14: error:
> > '++' expression of 'volatile'-qualified type is deprecated
> >
> > The count field of rte_spinlock_recursive_t
> > does not need the volatile qualifier
> > because it is only accessed by the thread holding the lock,
> > which already provides the necessary memory ordering.
> >
> > The user field can be accessed outside of the lock,
> > so it must handled as a C11 atomic variable.
> >
> > Fixes: af75078fece3 ("first public release")
> > Cc: stable@dpdk.org
> >
> > Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> > ---
> > v1: drop volatile keyword
> > v2: make user an atomic variable
> > ---
> > typedef struct {
> > rte_spinlock_t sl; /**< the actual spinlock */
> > - volatile int user; /**< core id using lock, -1 for unused */
> > - volatile int count; /**< count of time this lock has been called */
> > + RTE_ATOMIC(int) user; /**< core id using lock, -1 for unused */
> > + int count; /**< count of time this lock has been called */
> > } rte_spinlock_recursive_t;
[...]
> > @@ -230,9 +230,9 @@ static inline void rte_spinlock_recursive_lock(rte_spinlock_recursive_t *slr)
> > {
> > int id = rte_gettid();
> >
> > - if (slr->user != id) {
> > + if (rte_atomic_load_explicit(&slr->user, rte_memory_order_relaxed) != id) {
>
> This needs to be rte_memory_order_acquire
The memory ordering is managed with the sl variable.
The variable user has just to be atomic, so relaxed should be enough,
am I wrong?
[...]
> > @@ -246,10 +246,9 @@ static inline void rte_spinlock_recursive_unlock(rte_spinlock_recursive_t *slr)
> > __rte_no_thread_safety_analysis
> > {
> > if (--(slr->count) == 0) {
>
> This code is completely broken. Any thread can unlock without any check.
Maybe, but I don't intend to fix recursive unlock in this patch.
The subject is "remove volatile qualifier" (and unblock GCC 16).
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v2 1/2] spinlock: remove volatile qualifier
2026-05-18 15:25 ` Thomas Monjalon
@ 2026-05-18 15:28 ` Bruce Richardson
2026-05-19 9:17 ` Robin Jarry
0 siblings, 1 reply; 25+ messages in thread
From: Bruce Richardson @ 2026-05-18 15:28 UTC (permalink / raw)
To: Thomas Monjalon
Cc: Robin Jarry, dev, Stephen Hemminger, Konstantin Ananyev, stable
On Mon, May 18, 2026 at 05:25:43PM +0200, Thomas Monjalon wrote:
> 18/05/2026 17:14, Robin Jarry:
> > Hey Thomas,
> >
> > Thomas Monjalon, May 18, 2026 at 17:07:
<snip>
>
> [...]
> > > @@ -246,10 +246,9 @@ static inline void rte_spinlock_recursive_unlock(rte_spinlock_recursive_t *slr)
> > > __rte_no_thread_safety_analysis
> > > {
> > > if (--(slr->count) == 0) {
> >
> > This code is completely broken. Any thread can unlock without any check.
>
> Maybe, but I don't intend to fix recursive unlock in this patch.
> The subject is "remove volatile qualifier" (and unblock GCC 16).
>
As with regular mutexes, threads should not go around unlocking when not
holding the lock. Therefore, I think this is fine. [With regular spinlocks
we can't check since we don't track threads, therefore I think we just need
to assume a well-behaved app.]
/Bruce
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v2 1/2] spinlock: remove volatile qualifier
2026-05-18 15:14 ` [PATCH v2 1/2] spinlock: remove volatile qualifier Robin Jarry
2026-05-18 15:25 ` Thomas Monjalon
@ 2026-05-18 16:26 ` Stephen Hemminger
1 sibling, 0 replies; 25+ messages in thread
From: Stephen Hemminger @ 2026-05-18 16:26 UTC (permalink / raw)
To: Robin Jarry
Cc: Thomas Monjalon, dev, Konstantin Ananyev, Bruce Richardson,
stable
On Mon, 18 May 2026 17:14:54 +0200
"Robin Jarry" <rjarry@redhat.com> wrote:
> Hey Thomas,
>
> Thomas Monjalon, May 18, 2026 at 17:07:
> > When compiling with C++20 standard requirement (default in GCC 16),
> > the increment and decrement of volatile variables are rejected:
> >
> > rte_spinlock.h:241:14: error:
> > '++' expression of 'volatile'-qualified type is deprecated
> > rte_spinlock.h:252:21: error:
> > '--' expression of 'volatile'-qualified type is deprecated
> > rte_spinlock.h:278:14: error:
> > '++' expression of 'volatile'-qualified type is deprecated
> >
> > The count field of rte_spinlock_recursive_t
> > does not need the volatile qualifier
> > because it is only accessed by the thread holding the lock,
> > which already provides the necessary memory ordering.
> >
> > The user field can be accessed outside of the lock,
> > so it must handled as a C11 atomic variable.
> >
> > Fixes: af75078fece3 ("first public release")
> > Cc: stable@dpdk.org
> >
> > Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> > ---
> > v1: drop volatile keyword
> > v2: make user an atomic variable
> > ---
> > lib/eal/include/generic/rte_spinlock.h | 17 ++++++++---------
> > 1 file changed, 8 insertions(+), 9 deletions(-)
> >
> > diff --git a/lib/eal/include/generic/rte_spinlock.h b/lib/eal/include/generic/rte_spinlock.h
> > index c907d4e45c..5d810b682a 100644
> > --- a/lib/eal/include/generic/rte_spinlock.h
> > +++ b/lib/eal/include/generic/rte_spinlock.h
> > @@ -197,8 +197,8 @@ rte_spinlock_trylock_tm(rte_spinlock_t *sl)
> > */
> > typedef struct {
> > rte_spinlock_t sl; /**< the actual spinlock */
> > - volatile int user; /**< core id using lock, -1 for unused */
> > - volatile int count; /**< count of time this lock has been called */
> > + RTE_ATOMIC(int) user; /**< core id using lock, -1 for unused */
> > + int count; /**< count of time this lock has been called */
> > } rte_spinlock_recursive_t;
> >
> > /**
> > @@ -215,7 +215,7 @@ typedef struct {
> > static inline void rte_spinlock_recursive_init(rte_spinlock_recursive_t *slr)
> > {
> > rte_spinlock_init(&slr->sl);
> > - slr->user = -1;
> > + rte_atomic_store_explicit(&slr->user, -1, rte_memory_order_relaxed);
> > slr->count = 0;
> > }
> >
> > @@ -230,9 +230,9 @@ static inline void rte_spinlock_recursive_lock(rte_spinlock_recursive_t *slr)
> > {
> > int id = rte_gettid();
> >
> > - if (slr->user != id) {
> > + if (rte_atomic_load_explicit(&slr->user, rte_memory_order_relaxed) != id) {
>
> This needs to be rte_memory_order_acquire
No it does not. There is no dependency here.
The acquire is inside the spinlock.
>
> > rte_spinlock_lock(&slr->sl);
> > - slr->user = id;
> > + rte_atomic_store_explicit(&slr->user, id, rte_memory_order_relaxed);
>
> And rte_memory_order_release
Ditto.
>
> > }
> > slr->count++;
> > }
> > @@ -246,10 +246,9 @@ static inline void rte_spinlock_recursive_unlock(rte_spinlock_recursive_t *slr)
> > __rte_no_thread_safety_analysis
> > {
> > if (--(slr->count) == 0) {
>
> This code is completely broken. Any thread can unlock without any check.
I would make an RTE_ASSERT() that id matched current thread id.
Since caller holds lock, no atomic required for that.
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v2 1/2] spinlock: remove volatile qualifier
2026-05-18 15:07 ` [PATCH v2 1/2] " Thomas Monjalon
2026-05-18 15:07 ` [PATCH v2 2/2] spinlock: fix API comments Thomas Monjalon
2026-05-18 15:14 ` [PATCH v2 1/2] spinlock: remove volatile qualifier Robin Jarry
@ 2026-05-18 16:28 ` Stephen Hemminger
2 siblings, 0 replies; 25+ messages in thread
From: Stephen Hemminger @ 2026-05-18 16:28 UTC (permalink / raw)
To: Thomas Monjalon
Cc: dev, Konstantin Ananyev, Bruce Richardson, Robin Jarry, stable
On Mon, 18 May 2026 17:07:35 +0200
Thomas Monjalon <thomas@monjalon.net> wrote:
> When compiling with C++20 standard requirement (default in GCC 16),
> the increment and decrement of volatile variables are rejected:
>
> rte_spinlock.h:241:14: error:
> '++' expression of 'volatile'-qualified type is deprecated
> rte_spinlock.h:252:21: error:
> '--' expression of 'volatile'-qualified type is deprecated
> rte_spinlock.h:278:14: error:
> '++' expression of 'volatile'-qualified type is deprecated
>
> The count field of rte_spinlock_recursive_t
> does not need the volatile qualifier
> because it is only accessed by the thread holding the lock,
> which already provides the necessary memory ordering.
>
> The user field can be accessed outside of the lock,
> so it must handled as a C11 atomic variable.
>
> Fixes: af75078fece3 ("first public release")
> Cc: stable@dpdk.org
>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
I would also suggest renaming 'user' to 'owner' to follow common
practice in other places. It also provides an intentional API
break if somebody is misguided enough to do direct access to the
structure field.
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v2 1/2] spinlock: remove volatile qualifier
2026-05-18 15:28 ` Bruce Richardson
@ 2026-05-19 9:17 ` Robin Jarry
2026-05-19 10:35 ` Thomas Monjalon
0 siblings, 1 reply; 25+ messages in thread
From: Robin Jarry @ 2026-05-19 9:17 UTC (permalink / raw)
To: Bruce Richardson, Thomas Monjalon
Cc: dev, Stephen Hemminger, Konstantin Ananyev, stable
Bruce Richardson, May 18, 2026 at 17:28:
> On Mon, May 18, 2026 at 05:25:43PM +0200, Thomas Monjalon wrote:
>> 18/05/2026 17:14, Robin Jarry:
>> > Hey Thomas,
>> >
>> > Thomas Monjalon, May 18, 2026 at 17:07:
>
> <snip>
>
>>
>> [...]
>> > > @@ -246,10 +246,9 @@ static inline void rte_spinlock_recursive_unlock(rte_spinlock_recursive_t *slr)
>> > > __rte_no_thread_safety_analysis
>> > > {
>> > > if (--(slr->count) == 0) {
>> >
>> > This code is completely broken. Any thread can unlock without any check.
>>
>> Maybe, but I don't intend to fix recursive unlock in this patch.
>> The subject is "remove volatile qualifier" (and unblock GCC 16).
>>
> As with regular mutexes, threads should not go around unlocking when not
> holding the lock. Therefore, I think this is fine. [With regular spinlocks
> we can't check since we don't track threads, therefore I think we just need
> to assume a well-behaved app.]
Ok, fair enough :)
As Stephen suggested, maybe we could add some assertions?
static inline void rte_spinlock_recursive_unlock(rte_spinlock_recursive_t *slr)
__rte_no_thread_safety_analysis
{
+ RTE_ASSERT(rte_atomic_load_explicit(&slr->user, rte_memory_order_relaxed) == rte_gettid());
+ RTE_ASSERT(slr->count > 0);
+
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v3 1/3] spinlock: remove volatile qualifier
2026-05-04 8:37 [PATCH] spinlock: remove volatile qualifier Thomas Monjalon
` (2 preceding siblings ...)
2026-05-18 15:07 ` [PATCH v2 1/2] " Thomas Monjalon
@ 2026-05-19 10:34 ` Thomas Monjalon
2026-05-19 10:34 ` [PATCH v3 2/3] spinlock: add debug checks in recursive unlock Thomas Monjalon
` (4 more replies)
3 siblings, 5 replies; 25+ messages in thread
From: Thomas Monjalon @ 2026-05-19 10:34 UTC (permalink / raw)
To: dev
Cc: Stephen Hemminger, Konstantin Ananyev, Bruce Richardson,
Robin Jarry, stable
When compiling with C++20 standard requirement (default in GCC 16),
the increment and decrement of volatile variables are rejected:
rte_spinlock.h:241:14: error:
'++' expression of 'volatile'-qualified type is deprecated
rte_spinlock.h:252:21: error:
'--' expression of 'volatile'-qualified type is deprecated
rte_spinlock.h:278:14: error:
'++' expression of 'volatile'-qualified type is deprecated
The count field of rte_spinlock_recursive_t
does not need the volatile qualifier
because it is only accessed by the thread holding the lock,
which already provides the necessary memory ordering.
The user field can be accessed outside of the lock,
so it must handled as a C11 atomic variable.
The name is also changed from user to owner.
It will break if an application is accessing this field directly,
which should never happen.
Fixes: af75078fece3 ("first public release")
Cc: stable@dpdk.org
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
v1: drop volatile keyword
v2: make user an atomic variable
v3: rename user as owner
---
lib/eal/include/generic/rte_spinlock.h | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/lib/eal/include/generic/rte_spinlock.h b/lib/eal/include/generic/rte_spinlock.h
index c907d4e45c..ffdcb8fa3d 100644
--- a/lib/eal/include/generic/rte_spinlock.h
+++ b/lib/eal/include/generic/rte_spinlock.h
@@ -197,8 +197,8 @@ rte_spinlock_trylock_tm(rte_spinlock_t *sl)
*/
typedef struct {
rte_spinlock_t sl; /**< the actual spinlock */
- volatile int user; /**< core id using lock, -1 for unused */
- volatile int count; /**< count of time this lock has been called */
+ RTE_ATOMIC(int) owner; /**< core id using lock, -1 for unused */
+ int count; /**< count of time this lock has been called */
} rte_spinlock_recursive_t;
/**
@@ -215,7 +215,7 @@ typedef struct {
static inline void rte_spinlock_recursive_init(rte_spinlock_recursive_t *slr)
{
rte_spinlock_init(&slr->sl);
- slr->user = -1;
+ rte_atomic_store_explicit(&slr->owner, -1, rte_memory_order_relaxed);
slr->count = 0;
}
@@ -230,9 +230,9 @@ static inline void rte_spinlock_recursive_lock(rte_spinlock_recursive_t *slr)
{
int id = rte_gettid();
- if (slr->user != id) {
+ if (rte_atomic_load_explicit(&slr->owner, rte_memory_order_relaxed) != id) {
rte_spinlock_lock(&slr->sl);
- slr->user = id;
+ rte_atomic_store_explicit(&slr->owner, id, rte_memory_order_relaxed);
}
slr->count++;
}
@@ -246,10 +246,9 @@ static inline void rte_spinlock_recursive_unlock(rte_spinlock_recursive_t *slr)
__rte_no_thread_safety_analysis
{
if (--(slr->count) == 0) {
- slr->user = -1;
+ rte_atomic_store_explicit(&slr->owner, -1, rte_memory_order_relaxed);
rte_spinlock_unlock(&slr->sl);
}
-
}
/**
@@ -266,10 +265,10 @@ static inline int rte_spinlock_recursive_trylock(rte_spinlock_recursive_t *slr)
{
int id = rte_gettid();
- if (slr->user != id) {
+ if (rte_atomic_load_explicit(&slr->owner, rte_memory_order_relaxed) != id) {
if (rte_spinlock_trylock(&slr->sl) == 0)
return 0;
- slr->user = id;
+ rte_atomic_store_explicit(&slr->owner, id, rte_memory_order_relaxed);
}
slr->count++;
return 1;
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 2/3] spinlock: add debug checks in recursive unlock
2026-05-19 10:34 ` [PATCH v3 1/3] " Thomas Monjalon
@ 2026-05-19 10:34 ` Thomas Monjalon
2026-05-19 11:19 ` Thomas Monjalon
2026-05-19 11:47 ` Robin Jarry
2026-05-19 10:34 ` [PATCH v3 3/3] spinlock: fix API comments Thomas Monjalon
` (3 subsequent siblings)
4 siblings, 2 replies; 25+ messages in thread
From: Thomas Monjalon @ 2026-05-19 10:34 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Konstantin Ananyev, Bruce Richardson,
Robin Jarry
The recursive unlock assumes that the caller owns the lock.
This behavior will be checked when RTE_ENABLE_ASSERT is on.
There is an additional check for the count which should be positive
if no corruption happened.
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
v3: new patch in the series
---
lib/eal/include/generic/rte_spinlock.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/eal/include/generic/rte_spinlock.h b/lib/eal/include/generic/rte_spinlock.h
index ffdcb8fa3d..e7cd18a8e2 100644
--- a/lib/eal/include/generic/rte_spinlock.h
+++ b/lib/eal/include/generic/rte_spinlock.h
@@ -21,6 +21,7 @@
#ifdef RTE_FORCE_INTRINSICS
#include <rte_common.h>
#endif
+#include <rte_debug.h>
#include <rte_lock_annotations.h>
#include <rte_pause.h>
#include <rte_stdatomic.h>
@@ -245,6 +246,8 @@ static inline void rte_spinlock_recursive_lock(rte_spinlock_recursive_t *slr)
static inline void rte_spinlock_recursive_unlock(rte_spinlock_recursive_t *slr)
__rte_no_thread_safety_analysis
{
+ RTE_ASSERT(rte_atomic_load_explicit(&slr->owner, rte_memory_order_relaxed) == rte_gettid());
+ RTE_ASSERT(slr->count > 0);
if (--(slr->count) == 0) {
rte_atomic_store_explicit(&slr->owner, -1, rte_memory_order_relaxed);
rte_spinlock_unlock(&slr->sl);
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 3/3] spinlock: fix API comments
2026-05-19 10:34 ` [PATCH v3 1/3] " Thomas Monjalon
2026-05-19 10:34 ` [PATCH v3 2/3] spinlock: add debug checks in recursive unlock Thomas Monjalon
@ 2026-05-19 10:34 ` Thomas Monjalon
2026-05-19 11:03 ` [PATCH v3 1/3] spinlock: remove volatile qualifier Bruce Richardson
` (2 subsequent siblings)
4 siblings, 0 replies; 25+ messages in thread
From: Thomas Monjalon @ 2026-05-19 10:34 UTC (permalink / raw)
To: dev
Cc: Stephen Hemminger, Konstantin Ananyev, Bruce Richardson,
Robin Jarry, stable, Cunming Liang, Olivier Matz
This is not a read-write lock.
The user field stores the thread ID, not the core ID
since a change in DPDK 2.0.0.
The implementation is architecture-specific in some cases only.
Fixes: ca2e2dab079a ("spinlock: support non-EAL thread")
Fixes: af75078fece3 ("first public release")
Cc: stable@dpdk.org
Reported-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
lib/eal/include/generic/rte_spinlock.h | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/lib/eal/include/generic/rte_spinlock.h b/lib/eal/include/generic/rte_spinlock.h
index e7cd18a8e2..dd3d2d046c 100644
--- a/lib/eal/include/generic/rte_spinlock.h
+++ b/lib/eal/include/generic/rte_spinlock.h
@@ -7,12 +7,16 @@
/**
* @file
+ * DPDK spinlocks
*
- * RTE Spinlocks
+ * This is an API for spinlocks.
+ * This kind of lock simply waits in a loop
+ * repeatedly checking until the lock becomes available.
*
- * This file defines an API for read-write locks, which are implemented
- * in an architecture-specific way. This kind of lock simply waits in
- * a loop repeatedly checking until the lock becomes available.
+ * Some functions may have an architecture-specific implementation
+ * if RTE_FORCE_INTRINSICS is disabled.
+ * The hardware transactional memory (lock elision) functions have _tm suffix
+ * and are implemented in architecture-specific files.
*
* All locks must be initialised before use, and only initialised once.
*/
@@ -198,7 +202,7 @@ rte_spinlock_trylock_tm(rte_spinlock_t *sl)
*/
typedef struct {
rte_spinlock_t sl; /**< the actual spinlock */
- RTE_ATOMIC(int) owner; /**< core id using lock, -1 for unused */
+ RTE_ATOMIC(int) owner; /**< thread id owning lock, -1 for unused */
int count; /**< count of time this lock has been called */
} rte_spinlock_recursive_t;
--
2.54.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH v2 1/2] spinlock: remove volatile qualifier
2026-05-19 9:17 ` Robin Jarry
@ 2026-05-19 10:35 ` Thomas Monjalon
0 siblings, 0 replies; 25+ messages in thread
From: Thomas Monjalon @ 2026-05-19 10:35 UTC (permalink / raw)
To: Robin Jarry
Cc: Bruce Richardson, dev, Stephen Hemminger, Konstantin Ananyev,
stable
19/05/2026 11:17, Robin Jarry:
> Bruce Richardson, May 18, 2026 at 17:28:
> > On Mon, May 18, 2026 at 05:25:43PM +0200, Thomas Monjalon wrote:
> >> 18/05/2026 17:14, Robin Jarry:
> >> > Thomas Monjalon, May 18, 2026 at 17:07:
> >> > > @@ -246,10 +246,9 @@ static inline void rte_spinlock_recursive_unlock(rte_spinlock_recursive_t *slr)
> >> > > __rte_no_thread_safety_analysis
> >> > > {
> >> > > if (--(slr->count) == 0) {
> >> >
> >> > This code is completely broken. Any thread can unlock without any check.
> >>
> >> Maybe, but I don't intend to fix recursive unlock in this patch.
> >> The subject is "remove volatile qualifier" (and unblock GCC 16).
> >>
> > As with regular mutexes, threads should not go around unlocking when not
> > holding the lock. Therefore, I think this is fine. [With regular spinlocks
> > we can't check since we don't track threads, therefore I think we just need
> > to assume a well-behaved app.]
>
> Ok, fair enough :)
>
> As Stephen suggested, maybe we could add some assertions?
>
> static inline void rte_spinlock_recursive_unlock(rte_spinlock_recursive_t *slr)
> __rte_no_thread_safety_analysis
> {
> + RTE_ASSERT(rte_atomic_load_explicit(&slr->user, rte_memory_order_relaxed) == rte_gettid());
> + RTE_ASSERT(slr->count > 0);
> +
OK I add it as a separate patch in v3.
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v3 1/3] spinlock: remove volatile qualifier
2026-05-19 10:34 ` [PATCH v3 1/3] " Thomas Monjalon
2026-05-19 10:34 ` [PATCH v3 2/3] spinlock: add debug checks in recursive unlock Thomas Monjalon
2026-05-19 10:34 ` [PATCH v3 3/3] spinlock: fix API comments Thomas Monjalon
@ 2026-05-19 11:03 ` Bruce Richardson
2026-05-19 13:32 ` Stephen Hemminger
2026-05-19 15:02 ` David Marchand
4 siblings, 0 replies; 25+ messages in thread
From: Bruce Richardson @ 2026-05-19 11:03 UTC (permalink / raw)
To: Thomas Monjalon
Cc: dev, Stephen Hemminger, Konstantin Ananyev, Robin Jarry, stable
On Tue, May 19, 2026 at 12:34:14PM +0200, Thomas Monjalon wrote:
> When compiling with C++20 standard requirement (default in GCC 16),
> the increment and decrement of volatile variables are rejected:
>
> rte_spinlock.h:241:14: error:
> '++' expression of 'volatile'-qualified type is deprecated
> rte_spinlock.h:252:21: error:
> '--' expression of 'volatile'-qualified type is deprecated
> rte_spinlock.h:278:14: error:
> '++' expression of 'volatile'-qualified type is deprecated
>
> The count field of rte_spinlock_recursive_t
> does not need the volatile qualifier
> because it is only accessed by the thread holding the lock,
> which already provides the necessary memory ordering.
>
> The user field can be accessed outside of the lock,
> so it must handled as a C11 atomic variable.
> The name is also changed from user to owner.
> It will break if an application is accessing this field directly,
> which should never happen.
>
> Fixes: af75078fece3 ("first public release")
> Cc: stable@dpdk.org
>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> ---
> v1: drop volatile keyword
> v2: make user an atomic variable
> v3: rename user as owner
> ---
> lib/eal/include/generic/rte_spinlock.h | 17 ++++++++---------
> 1 file changed, 8 insertions(+), 9 deletions(-)
>
Series-acked-by: Bruce Richardson <bruce.richardson@intel.com>
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v3 2/3] spinlock: add debug checks in recursive unlock
2026-05-19 10:34 ` [PATCH v3 2/3] spinlock: add debug checks in recursive unlock Thomas Monjalon
@ 2026-05-19 11:19 ` Thomas Monjalon
2026-05-19 11:47 ` Robin Jarry
1 sibling, 0 replies; 25+ messages in thread
From: Thomas Monjalon @ 2026-05-19 11:19 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Konstantin Ananyev, Bruce Richardson,
Robin Jarry
19/05/2026 12:34, Thomas Monjalon:
> The recursive unlock assumes that the caller owns the lock.
> This behavior will be checked when RTE_ENABLE_ASSERT is on.
> There is an additional check for the count which should be positive
> if no corruption happened.
>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> ---
> v3: new patch in the series
Forgot:
Suggested-by: Stephen Hemminger <stephen@networkplumber.org>
Suggested-by: Robin Jarry <rjarry@redhat.com>
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v3 2/3] spinlock: add debug checks in recursive unlock
2026-05-19 10:34 ` [PATCH v3 2/3] spinlock: add debug checks in recursive unlock Thomas Monjalon
2026-05-19 11:19 ` Thomas Monjalon
@ 2026-05-19 11:47 ` Robin Jarry
1 sibling, 0 replies; 25+ messages in thread
From: Robin Jarry @ 2026-05-19 11:47 UTC (permalink / raw)
To: Thomas Monjalon, dev
Cc: Stephen Hemminger, Konstantin Ananyev, Bruce Richardson
Thomas Monjalon, May 19, 2026 at 12:34:
> The recursive unlock assumes that the caller owns the lock.
> This behavior will be checked when RTE_ENABLE_ASSERT is on.
> There is an additional check for the count which should be positive
> if no corruption happened.
>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> ---
> v3: new patch in the series
> ---
> lib/eal/include/generic/rte_spinlock.h | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/lib/eal/include/generic/rte_spinlock.h b/lib/eal/include/generic/rte_spinlock.h
> index ffdcb8fa3d..e7cd18a8e2 100644
> --- a/lib/eal/include/generic/rte_spinlock.h
> +++ b/lib/eal/include/generic/rte_spinlock.h
> @@ -21,6 +21,7 @@
> #ifdef RTE_FORCE_INTRINSICS
> #include <rte_common.h>
> #endif
> +#include <rte_debug.h>
> #include <rte_lock_annotations.h>
> #include <rte_pause.h>
> #include <rte_stdatomic.h>
> @@ -245,6 +246,8 @@ static inline void rte_spinlock_recursive_lock(rte_spinlock_recursive_t *slr)
> static inline void rte_spinlock_recursive_unlock(rte_spinlock_recursive_t *slr)
> __rte_no_thread_safety_analysis
> {
> + RTE_ASSERT(rte_atomic_load_explicit(&slr->owner, rte_memory_order_relaxed) == rte_gettid());
> + RTE_ASSERT(slr->count > 0);
> if (--(slr->count) == 0) {
> rte_atomic_store_explicit(&slr->owner, -1, rte_memory_order_relaxed);
> rte_spinlock_unlock(&slr->sl);
Acked-by: Robin Jarry <rjarry@redhat.com>
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v3 1/3] spinlock: remove volatile qualifier
2026-05-19 10:34 ` [PATCH v3 1/3] " Thomas Monjalon
` (2 preceding siblings ...)
2026-05-19 11:03 ` [PATCH v3 1/3] spinlock: remove volatile qualifier Bruce Richardson
@ 2026-05-19 13:32 ` Stephen Hemminger
2026-05-19 15:02 ` David Marchand
4 siblings, 0 replies; 25+ messages in thread
From: Stephen Hemminger @ 2026-05-19 13:32 UTC (permalink / raw)
To: Thomas Monjalon
Cc: dev, Konstantin Ananyev, Bruce Richardson, Robin Jarry, stable
On Tue, 19 May 2026 12:34:14 +0200
Thomas Monjalon <thomas@monjalon.net> wrote:
> When compiling with C++20 standard requirement (default in GCC 16),
> the increment and decrement of volatile variables are rejected:
>
> rte_spinlock.h:241:14: error:
> '++' expression of 'volatile'-qualified type is deprecated
> rte_spinlock.h:252:21: error:
> '--' expression of 'volatile'-qualified type is deprecated
> rte_spinlock.h:278:14: error:
> '++' expression of 'volatile'-qualified type is deprecated
>
> The count field of rte_spinlock_recursive_t
> does not need the volatile qualifier
> because it is only accessed by the thread holding the lock,
> which already provides the necessary memory ordering.
>
> The user field can be accessed outside of the lock,
> so it must handled as a C11 atomic variable.
> The name is also changed from user to owner.
> It will break if an application is accessing this field directly,
> which should never happen.
>
> Fixes: af75078fece3 ("first public release")
> Cc: stable@dpdk.org
>
> Signed
Series-acked-by: Stephen Hemminger <stephen@networkplumber.org>
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v3 1/3] spinlock: remove volatile qualifier
2026-05-19 10:34 ` [PATCH v3 1/3] " Thomas Monjalon
` (3 preceding siblings ...)
2026-05-19 13:32 ` Stephen Hemminger
@ 2026-05-19 15:02 ` David Marchand
4 siblings, 0 replies; 25+ messages in thread
From: David Marchand @ 2026-05-19 15:02 UTC (permalink / raw)
To: Thomas Monjalon
Cc: dev, Stephen Hemminger, Konstantin Ananyev, Bruce Richardson,
Robin Jarry, stable
On Tue, 19 May 2026 at 12:37, Thomas Monjalon <thomas@monjalon.net> wrote:
>
> When compiling with C++20 standard requirement (default in GCC 16),
> the increment and decrement of volatile variables are rejected:
>
> rte_spinlock.h:241:14: error:
> '++' expression of 'volatile'-qualified type is deprecated
> rte_spinlock.h:252:21: error:
> '--' expression of 'volatile'-qualified type is deprecated
> rte_spinlock.h:278:14: error:
> '++' expression of 'volatile'-qualified type is deprecated
>
> The count field of rte_spinlock_recursive_t
> does not need the volatile qualifier
> because it is only accessed by the thread holding the lock,
> which already provides the necessary memory ordering.
>
> The user field can be accessed outside of the lock,
> so it must handled as a C11 atomic variable.
> The name is also changed from user to owner.
> It will break if an application is accessing this field directly,
> which should never happen.
>
> Fixes: af75078fece3 ("first public release")
> Cc: stable@dpdk.org
>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
Series applied, thanks.
--
David Marchand
^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2026-05-19 15:03 UTC | newest]
Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-04 8:37 [PATCH] spinlock: remove volatile qualifier Thomas Monjalon
2026-05-04 9:06 ` Thomas Monjalon
2026-05-04 9:12 ` [PATCH] spinlock: fix API comments Thomas Monjalon
2026-05-04 12:46 ` Thomas Monjalon
2026-05-18 13:57 ` [PATCH] spinlock: remove volatile qualifier Thomas Monjalon
2026-05-04 17:02 ` Stephen Hemminger
2026-05-05 7:01 ` Thomas Monjalon
2026-05-05 13:24 ` Stephen Hemminger
2026-05-18 15:07 ` [PATCH v2 1/2] " Thomas Monjalon
2026-05-18 15:07 ` [PATCH v2 2/2] spinlock: fix API comments Thomas Monjalon
2026-05-18 15:14 ` [PATCH v2 1/2] spinlock: remove volatile qualifier Robin Jarry
2026-05-18 15:25 ` Thomas Monjalon
2026-05-18 15:28 ` Bruce Richardson
2026-05-19 9:17 ` Robin Jarry
2026-05-19 10:35 ` Thomas Monjalon
2026-05-18 16:26 ` Stephen Hemminger
2026-05-18 16:28 ` Stephen Hemminger
2026-05-19 10:34 ` [PATCH v3 1/3] " Thomas Monjalon
2026-05-19 10:34 ` [PATCH v3 2/3] spinlock: add debug checks in recursive unlock Thomas Monjalon
2026-05-19 11:19 ` Thomas Monjalon
2026-05-19 11:47 ` Robin Jarry
2026-05-19 10:34 ` [PATCH v3 3/3] spinlock: fix API comments Thomas Monjalon
2026-05-19 11:03 ` [PATCH v3 1/3] spinlock: remove volatile qualifier Bruce Richardson
2026-05-19 13:32 ` Stephen Hemminger
2026-05-19 15:02 ` David Marchand
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox