[PATCH v5 2/3] riscv: introduce percpu.h into include/asm
bot+bpf-ci at kernel.org
bot+bpf-ci at kernel.org
Tue Jun 30 22:05:56 PDT 2026
> diff --git a/arch/riscv/include/asm/percpu.h b/arch/riscv/include/asm/percpu.h
> new file mode 100644
> index 000000000000..46f1901d3bb8
> --- /dev/null
> +++ b/arch/riscv/include/asm/percpu.h
> @@ -0,0 +1,283 @@
[ ... ]
> +#define PERCPU_8_16_OP(name, amo_insn, sz, sfx, val_type, new_val_expr, asm_op) \
> +static inline void __percpu_##name##_amo_case_##sz(void *ptr, unsigned long val) \
> +{ \
> + if (IS_ENABLED(CONFIG_RISCV_ISA_ZABHA) && \
> + riscv_has_extension_unlikely(RISCV_ISA_EXT_ZABHA)) { \
> + asm volatile ("amo" #amo_insn #sfx " zero, %[val], %[ptr]" \
> + : [ptr] "+A"(*(val_type *)ptr) \
> + : [val] "r"((val_type)((new_val_expr) & PERCPU_8_16_GET_MASK(sz))) \
> + : "memory"); \
> + } else { \
> + u32 *ptr32 = PERCPU_8_16_GET_PTR32(ptr); \
> + const unsigned long shift = PERCPU_8_16_GET_SHIFT(ptr); \
> + const u32 mask = PERCPU_8_16_GET_MASK(sz) << shift; \
> + const val_type val_trunc = (val_type)((new_val_expr) \
> + & PERCPU_8_16_GET_MASK(sz)); \
> + u32 retx, rc; \
> + val_type new_val_type; \
> + \
> + asm volatile ( \
> + "0: lr.w %0, %2\n" \
> + "and %3, %0, %4\n" \
> + "srl %3, %3, %5\n" \
> + #asm_op " %3, %3, %6\n" \
> + "and %3, %3, %8\n" \
> + "sll %3, %3, %5\n" \
> + "and %1, %0, %7\n" \
> + "or %1, %1, %3\n" \
> + "sc.w %1, %1, %2\n" \
> + "bnez %1, 0b\n" \
> + : "=&r"(retx), "=&r"(rc), "+A"(*ptr32), "=&r"(new_val_type) \
> + : "r"(mask), "r"(shift), "r"(val_trunc), "r"(~mask), \
> + "r"(PERCPU_8_16_GET_MASK(sz)) \
> + : "memory"); \
> + } \
> +}
[ ... ]
> +#define PERCPU_8_16_RET_OP(name, amo_insn, sz, sfx, val_type, new_val_expr) \
> +static inline val_type __percpu_##name##_return_amo_case_##sz(void *ptr, unsigned long val) \
> +{ \
> + if (IS_ENABLED(CONFIG_RISCV_ISA_ZABHA) && \
> + riscv_has_extension_unlikely(RISCV_ISA_EXT_ZABHA)) { \
> + register val_type ret; \
> + asm volatile ("amo" #amo_insn #sfx " %[ret], %[val], %[ptr]" \
> + : [ptr] "+A"(*(val_type *)ptr), [ret] "=r"(ret) \
> + : [val] "r"((val_type)((new_val_expr) & PERCPU_8_16_GET_MASK(sz))) \
> + : "memory"); \
> + return ret + (val_type)((new_val_expr) & PERCPU_8_16_GET_MASK(sz)); \
> + } else { \
> + u32 *ptr32 = PERCPU_8_16_GET_PTR32(ptr); \
> + const unsigned long shift = PERCPU_8_16_GET_SHIFT(ptr); \
> + const u32 mask = (PERCPU_8_16_GET_MASK(sz) << shift); \
> + const u32 inv_mask = ~mask; \
> + const val_type val_trunc = (val_type)((new_val_expr) \
> + & PERCPU_8_16_GET_MASK(sz)); \
> + u32 old, new, tmp; \
This isn't a bug, but the two LR/SC fallback loops name the same roles
differently. The non-return loop uses:
u32 retx, rc;
val_type new_val_type;
while the return loop above uses:
u32 old, new, tmp;
The loaded word, the scratch/merge register and the computed field play the
same role in both loops. Could they use one consistent set of names (e.g.
old/new/tmp) so the two loops read as clearly parallel? As a smaller point,
new_val_type reads like a type name rather than a value, and new shadows a
common keyword.
> + \
> + asm volatile ( \
> + "0: lr.w %0, %3\n" \
> + "and %1, %0, %4\n" \
> + "srl %1, %1, %5\n" \
> + "add %1, %1, %6\n" \
> + "and %1, %1, %7\n" \
> + "sll %1, %1, %5\n" \
> + "and %2, %0, %8\n" \
> + "or %2, %2, %1\n" \
> + "sc.w %2, %2, %3\n" \
> + "bnez %2, 0b\n" \
This isn't a bug, but the read-modify-write LR/SC sequence here is nearly
identical to the one in PERCPU_8_16_OP, differing only in operand numbering.
The non-return loop parameterises the operation via #asm_op, but this loop
hardcodes add:
"add %1, %1, %6\n"
Was the intent to keep the return path add-only, or could the two loops share
one templated sequence?
> + : "=&r"(old), "=&r"(tmp), "=&r"(new), "+A"(*ptr32) \
> + : "r"(mask), "r"(shift), "r"(val_trunc), "r"(PERCPU_8_16_GET_MASK(sz)), \
> + "r"(inv_mask) \
> + : "memory"); \
> + return (val_type)(tmp >> shift); \
> + } \
> +}
[ ... ]
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/28494034360
More information about the linux-riscv
mailing list