[PATCH 0/4] sparc32: SMP fixes, futexes on SMP, and a cmpxchg system call
From: Ramin Moussavi
Date: Thu Oct 15 2026 - 05:01:11 EST
This series makes NPTL usable on sparc32 SMP kernels. It started with
the uClibc-ng test suite on qemu's SS-20 with -smp 4: the kernel went to
error state under console load, sometimes hung at boot, and had no
futexes at all.
Patches 1 and 2 are fixes and do not depend on the rest:
1. The per-cpu timer interrupts on sun4m/sun4d and the LEON IPI leave
their handler with traps enabled at the PIL of the interrupted
code while the trap frame is still on the stack, so interrupts can
nest without bound until the CPU goes to error state. The generic
path was fixed in 2.1.129; these three exits never got the change.
2. A secondary CPU gets 10000 rounds of udelay(200) to call in. Under
qemu the delay loop calibration depends on host load, the wait can
shrink to a few milliseconds, and a CPU that calls in late blocks
RCU and hangs the boot. Wait by jiffies instead.
Both are marked for stable but have no Fixes: tag. The sun4m and sun4d
code they change is already in 2.6.12-rc2, the start of the git history;
the LEON variants were copied from it in 2011.
Patches 3 and 4 add what user space needs on SMP:
3. Futex atomics for sparc32, so FUTEX no longer depends on !SMP.
casa is probed at boot (LEON); without it the word is updated
under the hashed spinlock the kernel already uses for its atomics.
4. sparc_atomic_cmpxchg_32, a compare-and-exchange system call for
user space built for v8, which has no CAS of its own. The ldstub
emulation C libraries use instead is not async-signal-safe and is
invisible to the futex code. It takes the same path as the futex
atomics, like atomic_cmpxchg_32 does on m68k. The uClibc-ng side
that uses it is ready and waits for this.
Tested on next-20261014 under qemu 11.1.0: the uClibc-ng suite on SS-20
with -smp 4 and UP and on leon3_generic with -smp 4, plus a test
program for the system call; the details are in each patch. sun4d was
only built, qemu has no sun4d machine.
Testing under qemu
------------------
Three qemu problems get in the way of reproducing this, none of them
caused by the series:
- leon3_generic does not boot an image passed with -kernel since qemu
9.0: the synthetic bootloader no longer sets %sp (92688a91c358 took
it out of the reset handler). Gaisler's own prebuilt images fail the
same way.
- leon3_generic does not bring up a second CPU under Linux. The IRQMP
model never sets the broadcast-available bit, and Linux stops with a
BUG in leon_smp.c; with that bit set, the secondary CPU dies on the
swapa with ASI 0x01 (forced cache miss) in leon_cpu_pre_online(),
which qemu does not decode.
- On sun4m, qemu's ESCC drives only the interrupt line of the channel
it was called for; the board ORs both lines, and a stale line keeps
level 12 asserted. Boots then hang at random with an RCU stall about
20 seconds in (4 of 40 boots with -smp 4 here). That looks like a
problem with this series but is not.
The LEON SMP results were taken with these fixed in qemu; the fixes are
going to be reported to qemu.
These patches were developed with the help of Claude (Anthropic), as
the Assisted-by tags say. I have reviewed them and tested them as
described.
Ramin Moussavi (4):
sparc32: keep PIL raised until the IRQ frame is gone
sparc32: wait for secondary CPUs by time, not by loop count
sparc32: implement futex atomics, with casa detected at run time
sparc32: add the sparc_atomic_cmpxchg_32 system call
arch/sparc/include/asm/cmpxchg_32.h | 4 ++
arch/sparc/include/asm/futex_32.h | 72 +++++++++++++++++++++++++-
arch/sparc/kernel/entry.S | 9 ++--
arch/sparc/kernel/leon_smp.c | 8 ++-
arch/sparc/kernel/sun4d_smp.c | 8 ++-
arch/sparc/kernel/sun4m_smp.c | 8 ++-
arch/sparc/kernel/sys_sparc_32.c | 35 +++++++++++++
arch/sparc/kernel/syscalls/syscall.tbl | 1 +
arch/sparc/kernel/systbls.h | 1 +
arch/sparc/kernel/traps_32.c | 13 ++++-
arch/sparc/lib/Makefile | 3 +-
arch/sparc/lib/atomic32.c | 53 +++++++++++++++++++
arch/sparc/lib/casa_32.S | 30 +++++++++++
init/Kconfig | 1 -
14 files changed, 224 insertions(+), 22 deletions(-)
create mode 100644 arch/sparc/lib/casa_32.S
base-commit: d419d682257d813f6cb7a28e42b35d0edf4ad038
--
2.53.0