mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v5 0/3] Add two-byte cmpxchg emulation and wire it into the architectures
@ 2026-10-05 12:06 Bradley Morgan
  2026-10-05 12:06 ` [PATCH v5 1/3] ARC: Emulate two-byte cmpxchg Bradley Morgan
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Bradley Morgan @ 2026-10-05 12:06 UTC (permalink / raw)
  To: akpm, vgupta, guoren, chris, jcmvbkbc
  Cc: arnd, paulmck, david.laight.linux, glaubitz, ysato, dalias,
	linux-snps-arc, linux-csky, linux-kernel, brads

This is v5 of the two-byte cmpxchg emulation series, reduced to the
three architectures still missing after Paul McKenney queued the lib
and sh patches, ARC, csky and xtensa.

The v4 attempt at these folded in a type checking idiom,
(unsigned long)(0 ? *ptr : old), meant to make cmpxchg(&p, 4, 5) fail
to compile. The kernel test robot and Vineet Gupta showed that idiom
breaks real callers, fs/crypto/hooks.c passes a char * and an
unsigned char * to cmpxchg_release(), and the conditional expression
then has incompatible pointer types, which is a hard error on gcc 14
and newer. So this version only adds the case 2 dispatch, the
declarations the architectures already have are kept as is.

The ARC sizeof bug that v4 fixed along the way is in mainline
separately through Vineet's f050c3e61d2a ("ARC: arch_cmpxchg_relaxed
to use size of pointed type not pointer"), so the ARC patch here is
only the case 2 wiring on top of that.

On the why, RCU previously used single-byte cmpxchg(), which is what
motivated cmpxchg_emu_u8() in the first place, and Paul has now
queued cmpxchg_emu_u16(). Unused new code is frowned upon, so wiring
it into the architectures that need it is the missing half, and
there are existing workarounds for the missing two-byte cmpxchg() in
the tree, _Q_PENDING_BITS for one, that can make use of it.

Per Paul's suggestion each patch is standalone and can go in
independently, they only depend on the lib patch already queued.
Each one was build tested with the real cross toolchain, ARC with
arc-linux-gnu-gcc and csky and xtensa with the gcc 16.2 crosstool
builds Vineet pointed at, W=1, with the macro instantiated on
u8, u16, u32 and pointer types, confirming the new dispatch is
reached and no new warnings appear. The pointer instantiation
covers the fs/crypto/hooks.c case that broke v4.

Bradley Morgan (3):
  ARC: Emulate two-byte cmpxchg
  csky: Emulate two-byte cmpxchg
  xtensa: Emulate two-byte cmpxchg

 arch/arc/include/asm/cmpxchg.h    | 3 +++
 arch/csky/include/asm/cmpxchg.h   | 9 +++++++++
 arch/xtensa/include/asm/cmpxchg.h | 1 +
 3 files changed, 13 insertions(+)

-- 
2.53.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v5 1/3] ARC: Emulate two-byte cmpxchg
  2026-10-05 12:06 [PATCH v5 0/3] Add two-byte cmpxchg emulation and wire it into the architectures Bradley Morgan
@ 2026-10-05 12:06 ` Bradley Morgan
  2026-10-05 12:06 ` [PATCH v5 2/3] csky: " Bradley Morgan
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Bradley Morgan @ 2026-10-05 12:06 UTC (permalink / raw)
  To: akpm, vgupta, guoren, chris, jcmvbkbc
  Cc: arnd, paulmck, david.laight.linux, glaubitz, ysato, dalias,
	linux-snps-arc, linux-csky, linux-kernel, brads

ARC has no two-byte atomic compare and swap, so the
arch_cmpxchg_relaxed() macro switch lets case 2 fall through to
BUILD_BUG() via default, and a two-byte cmpxchg() fails the build.

Route case 2 through the new cmpxchg_emu_u16(), which narrows the
old and new values itself, so the dispatch keeps the (uintptr_t)
casts the case 1 path already uses.

The sizeof(*(_p_)) fix that v4 folded in here landed separately
through Vineet's f050c3e61d2a, so this patch is now only the
case 2 wiring.

Signed-off-by: Bradley Morgan <brads@mainlining.org>
---
 arch/arc/include/asm/cmpxchg.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arc/include/asm/cmpxchg.h b/arch/arc/include/asm/cmpxchg.h
index 66b3743c9400..b30b20933f32 100644
--- a/arch/arc/include/asm/cmpxchg.h
+++ b/arch/arc/include/asm/cmpxchg.h
@@ -50,6 +50,9 @@
 	case 1:								\
 		_prev_ = (__typeof__(*(ptr)))cmpxchg_emu_u8((volatile u8 *__force)_p_, (uintptr_t)_o_, (uintptr_t)_n_);	\
 		break;							\
+	case 2:								\
+		_prev_ = (__typeof__(*(ptr)))cmpxchg_emu_u16((volatile u16 *__force)_p_, (unsigned long)_o_, (unsigned long)_n_);	\
+		break;							\
 	case 4:								\
 		_prev_ = __cmpxchg(_p_, _o_, _n_);			\
 		break;							\
-- 
2.53.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v5 2/3] csky: Emulate two-byte cmpxchg
  2026-10-05 12:06 [PATCH v5 0/3] Add two-byte cmpxchg emulation and wire it into the architectures Bradley Morgan
  2026-10-05 12:06 ` [PATCH v5 1/3] ARC: Emulate two-byte cmpxchg Bradley Morgan
@ 2026-10-05 12:06 ` Bradley Morgan
  2026-10-05 12:07 ` [PATCH v5 3/3] xtensa: " Bradley Morgan
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Bradley Morgan @ 2026-10-05 12:06 UTC (permalink / raw)
  To: akpm, vgupta, guoren, chris, jcmvbkbc
  Cc: arnd, paulmck, david.laight.linux, glaubitz, ysato, dalias,
	linux-snps-arc, linux-csky, linux-kernel, brads

C-SKY has no two-byte atomic compare and swap, so the __cmpxchg()
macros let case 2 fall through to BUILD_BUG() via default, and a
two-byte cmpxchg() fails the build.

Route case 2 through the new cmpxchg_emu_u16(), which narrows the
old and new values itself, so all three orderings, relaxed, acquire
and full, keep the (uintptr_t) casts the case 1 path already uses.

Signed-off-by: Bradley Morgan <brads@mainlining.org>
---
 arch/csky/include/asm/cmpxchg.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/csky/include/asm/cmpxchg.h b/arch/csky/include/asm/cmpxchg.h
index db6dda47184e..6f3ca79e54ac 100644
--- a/arch/csky/include/asm/cmpxchg.h
+++ b/arch/csky/include/asm/cmpxchg.h
@@ -64,6 +64,9 @@
 	switch (size) {						\
 	case 1:							\
 		__ret = (__typeof__(*(ptr)))cmpxchg_emu_u8((volatile u8 *)__ptr, (uintptr_t)__old, (uintptr_t)__new); \
+		break;							\
+	case 2:							\
+		__ret = (__typeof__(*(ptr)))cmpxchg_emu_u16((volatile u16 *)__ptr, (unsigned long)__old, (unsigned long)__new); \
 		break;						\
 	case 4:							\
 		asm volatile (					\
@@ -97,6 +100,9 @@
 	switch (size) {						\
 	case 1:							\
 		__ret = (__typeof__(*(ptr)))cmpxchg_emu_u8((volatile u8 *)__ptr, (uintptr_t)__old, (uintptr_t)__new); \
+		break;							\
+	case 2:							\
+		__ret = (__typeof__(*(ptr)))cmpxchg_emu_u16((volatile u16 *)__ptr, (unsigned long)__old, (unsigned long)__new); \
 		break;						\
 	case 4:							\
 		asm volatile (					\
@@ -131,6 +137,9 @@
 	switch (size) {						\
 	case 1:							\
 		__ret = (__typeof__(*(ptr)))cmpxchg_emu_u8((volatile u8 *)__ptr, (uintptr_t)__old, (uintptr_t)__new); \
+		break;							\
+	case 2:							\
+		__ret = (__typeof__(*(ptr)))cmpxchg_emu_u16((volatile u16 *)__ptr, (unsigned long)__old, (unsigned long)__new); \
 		break;						\
 	case 4:							\
 		asm volatile (					\
-- 
2.53.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v5 3/3] xtensa: Emulate two-byte cmpxchg
  2026-10-05 12:06 [PATCH v5 0/3] Add two-byte cmpxchg emulation and wire it into the architectures Bradley Morgan
  2026-10-05 12:06 ` [PATCH v5 1/3] ARC: Emulate two-byte cmpxchg Bradley Morgan
  2026-10-05 12:06 ` [PATCH v5 2/3] csky: " Bradley Morgan
@ 2026-10-05 12:07 ` Bradley Morgan
  2026-10-05 12:19 ` [PATCH v5 0/3] Add two-byte cmpxchg emulation and wire it into the architectures Bradley Morgan
  2026-10-05 18:02 ` David Laight
  4 siblings, 0 replies; 7+ messages in thread
From: Bradley Morgan @ 2026-10-05 12:07 UTC (permalink / raw)
  To: akpm, vgupta, guoren, chris, jcmvbkbc
  Cc: arnd, paulmck, david.laight.linux, glaubitz, ysato, dalias,
	linux-snps-arc, linux-csky, linux-kernel, brads

Xtensa has no two-byte atomic compare and swap, so the __cmpxchg()
switch lets case 2 fall through to __cmpxchg_called_with_bad_pointer(),
which is declared but never defined, so a two-byte cmpxchg() fails
at link time.

Route case 2 through the new cmpxchg_emu_u16(), which takes the
old and new values as unsigned long and narrows them itself, so
the call needs no extra casts.

Signed-off-by: Bradley Morgan <brads@mainlining.org>
---
 arch/xtensa/include/asm/cmpxchg.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/xtensa/include/asm/cmpxchg.h b/arch/xtensa/include/asm/cmpxchg.h
index b6db4838b175..8dea8e357fc0 100644
--- a/arch/xtensa/include/asm/cmpxchg.h
+++ b/arch/xtensa/include/asm/cmpxchg.h
@@ -76,6 +76,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
 {
 	switch (size) {
 	case 1:  return cmpxchg_emu_u8(ptr, old, new);
+	case 2:  return cmpxchg_emu_u16(ptr, old, new);
 	case 4:  return __cmpxchg_u32(ptr, old, new);
 	default: __cmpxchg_called_with_bad_pointer();
 		 return old;
-- 
2.53.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v5 0/3] Add two-byte cmpxchg emulation and wire it into the architectures
  2026-10-05 12:06 [PATCH v5 0/3] Add two-byte cmpxchg emulation and wire it into the architectures Bradley Morgan
                   ` (2 preceding siblings ...)
  2026-10-05 12:07 ` [PATCH v5 3/3] xtensa: " Bradley Morgan
@ 2026-10-05 12:19 ` Bradley Morgan
  2026-10-05 18:02 ` David Laight
  4 siblings, 0 replies; 7+ messages in thread
From: Bradley Morgan @ 2026-10-05 12:19 UTC (permalink / raw)
  To: akpm, vgupta, guoren, chris, jcmvbkbc
  Cc: arnd, paulmck, david.laight.linux, glaubitz, ysato, dalias,
	linux-snps-arc, linux-csky, linux-kernel

On 5 October 2026 13:06:57 BST, Bradley Morgan <brads@mainlining.org>
wrote:
>This is v5 of the two-byte cmpxchg emulation series, reduced to the
>three architectures still missing after Paul McKenney queued the lib
>and sh patches, ARC, csky and xtensa.
>
>The v4 attempt at these folded in a type checking idiom,
>(unsigned long)(0 ? *ptr : old), meant to make cmpxchg(&p, 4, 5) fail
>to compile. The kernel test robot and Vineet Gupta showed that idiom
>breaks real callers, fs/crypto/hooks.c passes a char * and an
>unsigned char * to cmpxchg_release(), and the conditional expression
>then has incompatible pointer types, which is a hard error on gcc 14
>and newer. So this version only adds the case 2 dispatch, the
>declarations the architectures already have are kept as is.
>
>The ARC sizeof bug that v4 fixed along the way is in mainline
>separately through Vineet's f050c3e61d2a ("ARC: arch_cmpxchg_relaxed
>to use size of pointed type not pointer"), so the ARC patch here is
>only the case 2 wiring on top of that.

Sashiko took a hitch at it, all the "bugs" are bogus, most are just cuz
"u16 is undefined oh no error", but they didn't see Paul's tree, where it
is defined.

whatever

>
>On the why, RCU previously used single-byte cmpxchg(), which is what
>motivated cmpxchg_emu_u8() in the first place, and Paul has now
>queued cmpxchg_emu_u16(). Unused new code is frowned upon, so wiring
>it into the architectures that need it is the missing half, and
>there are existing workarounds for the missing two-byte cmpxchg() in
>the tree, _Q_PENDING_BITS for one, that can make use of it.
>
>Per Paul's suggestion each patch is standalone and can go in
>independently, they only depend on the lib patch already queued.
>Each one was build tested with the real cross toolchain, ARC with
>arc-linux-gnu-gcc and csky and xtensa with the gcc 16.2 crosstool
>builds Vineet pointed at, W=1, with the macro instantiated on
>u8, u16, u32 and pointer types, confirming the new dispatch is
>reached and no new warnings appear. The pointer instantiation
>covers the fs/crypto/hooks.c case that broke v4.
>
>Bradley Morgan (3):
>  ARC: Emulate two-byte cmpxchg
>  csky: Emulate two-byte cmpxchg
>  xtensa: Emulate two-byte cmpxchg
>
> arch/arc/include/asm/cmpxchg.h    | 3 +++
> arch/csky/include/asm/cmpxchg.h   | 9 +++++++++
> arch/xtensa/include/asm/cmpxchg.h | 1 +
> 3 files changed, 13 insertions(+)
>
>

--- Thanks!
"I'm not a very positive person" - Linus torvalds

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v5 0/3] Add two-byte cmpxchg emulation and wire it into the architectures
  2026-10-05 12:06 [PATCH v5 0/3] Add two-byte cmpxchg emulation and wire it into the architectures Bradley Morgan
                   ` (3 preceding siblings ...)
  2026-10-05 12:19 ` [PATCH v5 0/3] Add two-byte cmpxchg emulation and wire it into the architectures Bradley Morgan
@ 2026-10-05 18:02 ` David Laight
  4 siblings, 0 replies; 7+ messages in thread
From: David Laight @ 2026-10-05 18:02 UTC (permalink / raw)
  To: Bradley Morgan
  Cc: akpm, vgupta, guoren, chris, jcmvbkbc, arnd, paulmck, glaubitz,
	ysato, dalias, linux-snps-arc, linux-csky, linux-kernel

On Mon,  5 Oct 2026 12:06:57 +0000
Bradley Morgan <brads@mainlining.org> wrote:

> This is v5 of the two-byte cmpxchg emulation series, reduced to the
> three architectures still missing after Paul McKenney queued the lib
> and sh patches, ARC, csky and xtensa.
> 
> The v4 attempt at these folded in a type checking idiom,
> (unsigned long)(0 ? *ptr : old), meant to make cmpxchg(&p, 4, 5) fail
> to compile. The kernel test robot and Vineet Gupta showed that idiom
> breaks real callers, fs/crypto/hooks.c passes a char * and an
> unsigned char * to cmpxchg_release(),

That ought to be a bug...

David

> and the conditional expression
> then has incompatible pointer types, which is a hard error on gcc 14
> and newer. So this version only adds the case 2 dispatch, the
> declarations the architectures already have are kept as is.
> 
> The ARC sizeof bug that v4 fixed along the way is in mainline
> separately through Vineet's f050c3e61d2a ("ARC: arch_cmpxchg_relaxed
> to use size of pointed type not pointer"), so the ARC patch here is
> only the case 2 wiring on top of that.
> 
> On the why, RCU previously used single-byte cmpxchg(), which is what
> motivated cmpxchg_emu_u8() in the first place, and Paul has now
> queued cmpxchg_emu_u16(). Unused new code is frowned upon, so wiring
> it into the architectures that need it is the missing half, and
> there are existing workarounds for the missing two-byte cmpxchg() in
> the tree, _Q_PENDING_BITS for one, that can make use of it.
> 
> Per Paul's suggestion each patch is standalone and can go in
> independently, they only depend on the lib patch already queued.
> Each one was build tested with the real cross toolchain, ARC with
> arc-linux-gnu-gcc and csky and xtensa with the gcc 16.2 crosstool
> builds Vineet pointed at, W=1, with the macro instantiated on
> u8, u16, u32 and pointer types, confirming the new dispatch is
> reached and no new warnings appear. The pointer instantiation
> covers the fs/crypto/hooks.c case that broke v4.
> 
> Bradley Morgan (3):
>   ARC: Emulate two-byte cmpxchg
>   csky: Emulate two-byte cmpxchg
>   xtensa: Emulate two-byte cmpxchg
> 
>  arch/arc/include/asm/cmpxchg.h    | 3 +++
>  arch/csky/include/asm/cmpxchg.h   | 9 +++++++++
>  arch/xtensa/include/asm/cmpxchg.h | 1 +
>  3 files changed, 13 insertions(+)
> 


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v5 3/3] xtensa: Emulate two-byte cmpxchg
  2026-10-05 12:05 Bradley Morgan
@ 2026-10-05 12:05 ` Bradley Morgan
  0 siblings, 0 replies; 7+ messages in thread
From: Bradley Morgan @ 2026-10-05 12:05 UTC (permalink / raw)
  To: akpm, vgupta, guoren, chris, jcmvbkbc
  Cc: arnd, paulmck, david.laight.linux, glaubitz, ysato, dalias,
	linux-snps-arc, linux-csky, linux-kernel, brads

Xtensa has no two-byte atomic compare and swap, so the __cmpxchg()
switch lets case 2 fall through to __cmpxchg_called_with_bad_pointer(),
which is declared but never defined, so a two-byte cmpxchg() fails
at link time.

Route case 2 through the new cmpxchg_emu_u16(), which takes the
old and new values as unsigned long and narrows them itself, so
the call needs no extra casts.

Signed-off-by: Bradley Morgan <brads@mainlining.org>
---
 arch/xtensa/include/asm/cmpxchg.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/xtensa/include/asm/cmpxchg.h b/arch/xtensa/include/asm/cmpxchg.h
index b6db4838b175..8dea8e357fc0 100644
--- a/arch/xtensa/include/asm/cmpxchg.h
+++ b/arch/xtensa/include/asm/cmpxchg.h
@@ -76,6 +76,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
 {
 	switch (size) {
 	case 1:  return cmpxchg_emu_u8(ptr, old, new);
+	case 2:  return cmpxchg_emu_u16(ptr, old, new);
 	case 4:  return __cmpxchg_u32(ptr, old, new);
 	default: __cmpxchg_called_with_bad_pointer();
 		 return old;
-- 
2.53.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-10-05 18:02 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-05 12:06 [PATCH v5 0/3] Add two-byte cmpxchg emulation and wire it into the architectures Bradley Morgan
2026-10-05 12:06 ` [PATCH v5 1/3] ARC: Emulate two-byte cmpxchg Bradley Morgan
2026-10-05 12:06 ` [PATCH v5 2/3] csky: " Bradley Morgan
2026-10-05 12:07 ` [PATCH v5 3/3] xtensa: " Bradley Morgan
2026-10-05 12:19 ` [PATCH v5 0/3] Add two-byte cmpxchg emulation and wire it into the architectures Bradley Morgan
2026-10-05 18:02 ` David Laight
  -- strict thread matches above, loose matches on Subject: below --
2026-10-05 12:05 Bradley Morgan
2026-10-05 12:05 ` [PATCH v5 3/3] xtensa: Emulate two-byte cmpxchg Bradley Morgan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®