Re: [PATCH 3/5] sh: Emulate two-byte cmpxchg

From: David Laight

Date: Wed Sep 23 2026 - 05:43:09 EST


On Tue, 22 Sep 2026 17:33:52 +0000
Bradley Morgan <brads@xxxxxxxxxxxxxx> wrote:

You missed v4 from the subject line of all the patches.

> SH has no byte or halfword atomic memory operations, so the __cmpxchg()
> switch routes case 1 through cmpxchg_emu_u8() and 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, so the (unsigned long) casts move off the
> call and into _old_ and _new_ declarations that type check the old
> and new arguments against *ptr through (unsigned long)(0 ? *ptr : _o_),
> the idiom David Laight suggested, so cmpxchg(&p, 4, 5) no longer
> compiles silently.
>
> Acked-by: John Paul Adrian Glaubitz <glaubitz@xxxxxxxxxxxxxxxxxxx>
> Signed-off-by: Bradley Morgan <brads@xxxxxxxxxxxxxx>
> ---
> arch/sh/include/asm/cmpxchg.h | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/arch/sh/include/asm/cmpxchg.h b/arch/sh/include/asm/cmpxchg.h
> index 1e5dc5ccf7bf..b87f59107b4e 100644
> --- a/arch/sh/include/asm/cmpxchg.h
> +++ b/arch/sh/include/asm/cmpxchg.h
> @@ -59,6 +59,8 @@ static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,
> 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);
> }
> @@ -70,8 +72,10 @@ static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,
> ({ \
> __typeof__(*(ptr)) _o_ = (o); \
> __typeof__(*(ptr)) _n_ = (n); \
> - (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
> - (unsigned long)_n_, sizeof(*(ptr))); \
> + unsigned long _old_ = (unsigned long)(0 ? *ptr : _o_); \
> + unsigned long _new_ = (unsigned long)(0 ? *ptr : _n_); \
> + (__typeof__(*(ptr))) __cmpxchg((ptr), _old_, \
> + _new_, sizeof(*(ptr))); \

Minor niggle if you have to do these again...
That line doesn't look long enough to need splitting.
More generally if you add 'unsigned long _rval_' and put a final cast
at the bottom the the #define the code will probably look neater.

David

> })
>
> #include <asm-generic/cmpxchg-local.h>