Re: [PATCH v4 0/5] Add two-byte cmpxchg emulation and wire it into the architectures

From: Bradley Morgan

Date: Tue Sep 22 2026 - 14:42:29 EST


On 22 September 2026 19:29:32 BST, "Paul E. McKenney" <paulmck@xxxxxxxxxx>
wrote:
>On Tue, Sep 22, 2026 at 05:33:49PM +0000, Bradley Morgan wrote:
>> This is v4 of the two byte cmpxchg emulation series, wiring
>> cmpxchg_emu_u16() into arc, csky, sh and xtensa.
>>
>> v3 had changed cmpxchg_emu_u8()'s success return to (u16)old, which was
>> a 16-bit mask in the 8-bit function, and a dead one at that, since the
>> compare guarantees the low 8 bits of old are the byte being returned.
>> David Laight asked where that cast came from. v4 returns old unmasked,
>> the exact behaviour the one-byte emulator always had, so nothing that
>> uses cmpxchg_emu_u8() through the widened prototypes sees a change.
>>
>> David also noted v3 extended the (unsigned long)(0 ? *ptr : (old)) type
>> check to csky and sh but not arc and xtensa. v4 adds it there too, so a
>> cmpxchg(&p, 4, 5) fails to compile on every architecture in the series,
>> verified with each architecture's macro instantiated standalone.
>>
>> While adding the type check to arc, the switch subject turned out to be
>> sizeof((_p_)), the pointer, not sizeof(*(_p_)), the pointee. On 32-bit
>> arc the switch was always 4, so the size 1 and size 2 cases were dead
>> code and every sub-word cmpxchg() went through the 32-bit llock/scond
>> pair, comparing whole words against sub-word values, so the compare
>> almost never succeeded. The switch now tests the pointee, and the u8
>> path it was always meant to dispatch actually runs, so the one-byte
>> emulation works on arc for the first time since the sizeof bug landed
>> with the original cmpxchg_emu_u8() wiring.
>>
>> The host test of 972 cases across both halfword offsets against a byte
>> level reference model still passes, and a 20000 case randomized run
>> checking the masked compare and return against a hardware cmpxchg r16
>> model passes with zero mismatches.
>>
>> David pointed out on v1 that a u16 prototype does not compile warning
>> free when exchanging a pointer type, because the switch statements in
>> the architecture macros instantiate every size case, so a pointer
>> cmpxchg() type checks the two byte case, and the (u16) casts there
>> warn. v4 keeps taking the old and new values as unsigned long and
>> casting to u16 inside the function, so the call sites need no narrowing
>> casts and pointer exchanges compile clean. The function still compares
>> and returns exactly the 16 bits the caller asked for, which matches
>> hardware cmpxchg r16 behaviour.
>>
>> The ARMv6 wiring stays dropped from v1, per Arnd Bergmann's offer to
>> take the INTEGRATOR_CM1136JFS cleanup in his platform removal series.
>
>I have pulled these in, but only to expose them to things like the kernel
>test robot. My guess is that they will go in by some other path.
>
>And to that end:
>
>Reviewed-by: Paul E. McKenney <paulmck@xxxxxxxxxx>
>
>But I could of course easily be missing subtle arch-specific bugs.

There are, according to sashiko, but I can't seem to make that thing happy
no matter what I do

>
> Thanx, Paul
>
>> Bradley Morgan (5):
>> lib: Add two-byte cmpxchg emulation function
>> ARC: Emulate two-byte cmpxchg
>> sh: Emulate two-byte cmpxchg
>> csky: Emulate two-byte cmpxchg
>> xtensa: Emulate two-byte cmpxchg

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