[PATCH v9 0/3] riscv: optimize percpu access
Yunhui Cui
cuiyunhui at bytedance.com
Sun Nov 8 03:04:03 PST 2026
RISC-V has no asm/percpu.h, so this_cpu_*() read-modify-write
operations use generic fallbacks that disable local interrupts. Per-CPU
addressing also derives the current offset from the CPU number and
__per_cpu_offset[].
Implement RISC-V-specific this_cpu operations using relaxed AMOs with
preemption disabled. Native-width read-modify-write operations use AMOs,
while 8-bit and 16-bit read-modify-write operations use Zabha when
available or a local 32-bit LR/SC sequence otherwise. Cache the current
per-CPU offset in thread_info, keep it valid across CPU bringup, hotplug
and context switches, and select HAVE_CMPXCHG_LOCAL so vmstat and percpu
counters can use the this_cpu_try_cmpxchg() fast path.
On a SiFive P550, Davidlohr Bueso measured about 15-20% lower
this_cpu_inc() cost in an ad-hoc microbenchmark.
Changes since v8:
- Drop the PIO helper patch, which has already been merged.
- Rename the first patch and update its changelog as suggested by
Davidlohr Bueso.
- Use value-returning AMOs instead of rd=x0 for CPU-local operations.
- Remove unnecessary memory clobbers from the new relaxed AMO and LR/SC
code.
- Use .option arch,+zabha for the Zabha inline asm, matching the
existing RISC-V cmpxchg implementation.
- Isolate arch_cmpxchg_relaxed() behind typed always-inline helpers to
avoid macro variable capture while preserving atomic instrumentation.
- Make the cmpxchg128 fallback use the already resolved per-CPU pointer,
avoiding the same macro variable capture.
- Copy the cached per-CPU offset from prev to next during context switch,
as suggested by Thomas Gleixner.
- Initialize secondary idle tasks in the common startup path, covering
parallel bringup and CPU hotplug, and remove the duplicate initialization
from smp_callin(), as reported by Sashiko.
- Select HAVE_CMPXCHG_LOCAL in a separate patch.
Yunhui Cui (3):
riscv: implement this_cpu operations
riscv: store percpu offset into thread_info
riscv: select HAVE_CMPXCHG_LOCAL
arch/riscv/Kconfig | 1 +
arch/riscv/include/asm/asm.h | 6 +-
arch/riscv/include/asm/percpu.h | 574 +++++++++++++++++++++++++++
arch/riscv/include/asm/switch_to.h | 9 +
arch/riscv/include/asm/thread_info.h | 3 +-
arch/riscv/kernel/asm-offsets.c | 2 +-
arch/riscv/kernel/smpboot.c | 10 +-
arch/riscv/net/bpf_jit_comp64.c | 9 +-
8 files changed, 598 insertions(+), 16 deletions(-)
create mode 100644 arch/riscv/include/asm/percpu.h
base-commit: ddfe51b0a0f5dc9e415cc2c8ad8db17532dd426b
--
2.39.5
More information about the linux-riscv
mailing list