mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH bpf v2] bpf, riscv: Make arena support depend on ZACAS
@ 2026-09-02  6:14 Chen Pei
  2026-09-02  7:00 ` bot+bpf-ci
  2026-09-05  3:08 ` Pu Lehui
  0 siblings, 2 replies; 3+ messages in thread
From: Chen Pei @ 2026-09-02  6:14 UTC (permalink / raw)
  To: ast, daniel, andrii, memxor, bjorn, puranjay
  Cc: ihor.solodrai, eddyz87, martin.lau, song, yonghong.song, jolsa,
	emil, pulehui, pjw, palmer, guoren, bpf, linux-riscv,
	linux-kernel, stable

The arena range tree allocates its nodes with kmalloc_nolock() since
commit f8c67d8550ee ("bpf: Use kmalloc_nolock() in range tree").
kmalloc_nolock() requires slab caches with cmpxchg128 support
(__CMPXCHG_DOUBLE); on riscv cmpxchg128 is provided by the ZACAS
extension. On systems without ZACAS every arena map creation fails
with a misleading -ENOMEM.

Report the missing support instead: make bpf_jit_supports_arena()
return system_has_cmpxchg128() where it is defined, so arena map
creation fails with -EOPNOTSUPP on systems without ZACAS. The macro
is only defined when both CONFIG_RISCV_ISA_ZACAS and
CONFIG_TOOLCHAIN_HAS_ZACAS are enabled, so guard it with #ifdef the
same way mm/slab.h consumes it, and reject arena otherwise. This
matches how arena BPF_CMPXCHG instructions are already gated on ZACAS
in bpf_jit_supports_insn().

Fixes: f8c67d8550ee ("bpf: Use kmalloc_nolock() in range tree")
Cc: stable@vger.kernel.org
Signed-off-by: Chen Pei <cp0613@linux.alibaba.com>
---
Changes since v1:
- Guard system_has_cmpxchg128() with #ifdef instead of calling it
  unconditionally: the macro is only defined when both
  CONFIG_RISCV_ISA_ZACAS and CONFIG_TOOLCHAIN_HAS_ZACAS are enabled
  (as reported by sashiko-bot), so v1 broke the build when either
  was disabled. This mirrors how mm/slab.h consumes the macro.

Why #ifdef rather than rv_ext_enabled(ZACAS)? The predicates differ
exactly in the configurations that matter:

  scenario (ISA_ZACAS/TOOLCHAIN/hw)  v1           rv_ext_enabled  #ifdef
  ISA=n or TOOLCHAIN=n               build fails  rejects         rejects
  ISA=y TOOLCHAIN=n hw has ZACAS     build fails  accepts, then   rejects
                                                  -ENOMEM again
  ISA=y TOOLCHAIN=y hw has ZACAS     exact        exact           exact

rv_ext_enabled(ZACAS) does not check CONFIG_TOOLCHAIN_HAS_ZACAS, but
slab's cmpxchg128 - and thus kmalloc_nolock() - does require it, so
on an old toolchain with ZACAS hardware it would accept arena maps
and bring back the very -ENOMEM failure this patch fixes. The #ifdef
form builds in every configuration and matches exactly the
kmalloc_nolock() availability gate in mm/slab.h.

This issue was reported by sashiko-bot:
https://sashiko.dev/#/patchset/20260901120013.16104-1-cp0613@linux.alibaba.com?part=1

Question for reviewers: should the arena selftests gate on ZACAS,
e.g. probing it via riscv_hwprobe() (RISCV_ISA_EXT_ZACAS) and
SKIPping cleanly on systems without the extension?

 arch/riscv/net/bpf_jit_comp64.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c
index 74efe4b138d2..151031e97a24 100644
--- a/arch/riscv/net/bpf_jit_comp64.c
+++ b/arch/riscv/net/bpf_jit_comp64.c
@@ -2128,7 +2128,15 @@ bool bpf_jit_supports_ptr_xchg(void)
 
 bool bpf_jit_supports_arena(void)
 {
-	return true;
+	/*
+	 * The arena range tree uses kmalloc_nolock(), which needs
+	 * cmpxchg128, provided by ZACAS on riscv.
+	 */
+#ifdef system_has_cmpxchg128
+	return system_has_cmpxchg128();
+#else
+	return false;
+#endif
 }
 
 bool bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena)
-- 
2.50.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH bpf v2] bpf, riscv: Make arena support depend on ZACAS
  2026-09-02  6:14 [PATCH bpf v2] bpf, riscv: Make arena support depend on ZACAS Chen Pei
@ 2026-09-02  7:00 ` bot+bpf-ci
  2026-09-05  3:08 ` Pu Lehui
  1 sibling, 0 replies; 3+ messages in thread
From: bot+bpf-ci @ 2026-09-02  7:00 UTC (permalink / raw)
  To: cp0613, ast, daniel, andrii, memxor, bjorn, puranjay
  Cc: ihor.solodrai, eddyz87, martin.lau, song, yonghong.song, jolsa,
	emil, pulehui, pjw, palmer, guoren, bpf, linux-riscv,
	linux-kernel, stable, ast, andrii, daniel, martin.lau, eddyz87,
	yonghong.song, mason, ihor.solodrai

[-- Attachment #1: Type: text/plain, Size: 3971 bytes --]

> diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c
> index 74efe4b138d2..151031e97a24 100644
> --- a/arch/riscv/net/bpf_jit_comp64.c
> +++ b/arch/riscv/net/bpf_jit_comp64.c
> @@ -2128,7 +2128,15 @@ bool bpf_jit_supports_ptr_xchg(void)
>
>  bool bpf_jit_supports_arena(void)
>  {
> -	return true;
> +	/*
> +	 * The arena range tree uses kmalloc_nolock(), which needs
> +	 * cmpxchg128, provided by ZACAS on riscv.
> +	 */
> +#ifdef system_has_cmpxchg128
> +	return system_has_cmpxchg128();
> +#else
> +	return false;
> +#endif
>  }

The constraint being checked here is a slab property (kmalloc_nolock()
requiring cmpxchg128 support), not a JIT property. Fixing it
per-architecture leaves the identical misleading -ENOMEM on every other
architecture.

Looking at mm/slub.c, kmalloc_nolock() rejects the request whenever
the cache lacks __CMPXCHG_DOUBLE:

    if (!(s->flags & __CMPXCHG_DOUBLE) && !kmem_cache_debug(s))
            return NULL;

and __CMPXCHG_DOUBLE is __SLAB_FLAG_UNUSED (0) whenever the arch
provides no system_has_cmpxchg128 on 64-bit (mm/slab.h).

Grepping every definition of system_has_cmpxchg128 in the tree gives:

    arm64        constant 1
    s390         constant 1
    x86_64       boot_cpu_has(X86_FEATURE_CX16)
    loongarch    cpu_opt(LOONGARCH_CPU_SCQ)
    riscv        this patch's ZACAS check

Yet the other bpf_jit_supports_arena() implementations are unconditional:

    arch/powerpc/net/bpf_jit_comp.c      return IS_ENABLED(CONFIG_PPC64);
    arch/x86/net/bpf_jit_comp.c          return true;
    arch/loongarch/net/bpf_jit.c         return true;

So on ppc64 kmalloc_nolock() can never succeed for a non-debug cache,
and arena_map_alloc() returns -ENOMEM unconditionally -- exactly the
symptom this patch is fixing, with no ZACAS involved. The same holds
for x86_64 CPUs without CX16 and loongarch without SCQ.

Is a check in generic code (arena_map_alloc() or a slab-provided
helper) worth considering to fix all affected architectures at once and
avoid replicating SLUB internals knowledge into each arch JIT hook?

--- Commit message ---

> The arena range tree allocates its nodes with kmalloc_nolock() since
> commit f8c67d8550ee ("bpf: Use kmalloc_nolock() in range tree").
> kmalloc_nolock() requires slab caches with cmpxchg128 support
> (__CMPXCHG_DOUBLE); on riscv cmpxchg128 is provided by the ZACAS
> extension. On systems without ZACAS every arena map creation fails
> with a misleading -ENOMEM.

The claim "every arena map creation fails with a misleading -ENOMEM" is
not exhaustively accurate. Looking at mm/slub.c:

    if (!(s->flags & __CMPXCHG_DOUBLE) && !kmem_cache_debug(s))
            /*
             * kmalloc_nolock() is not supported on architectures that
             * don't implement cmpxchg16b and thus need slab_lock()
             * ...
             * kmem_cache_node->list_lock, so kmalloc_nolock() can attempt
             * to allocate from debug caches by
             * spin_trylock_irqsave(&n->list_lock, ...)
             */
            return NULL;

The condition is an AND: when the cache is a debug cache (slub_debug
boot parameter, or CONFIG_SLUB_DEBUG_ON=y), kmalloc_nolock() proceeds
even with no cmpxchg128, so range_tree_set() and the arena.c
kmalloc_nolock() sites succeed and arena maps can be created today on a
non-ZACAS riscv64 system. After this change those same systems get
-EOPNOTSUPP.

That narrowing is arguably desirable (BPF should not depend on a SLUB
debug-mode escape hatch), but is the changelog accurate about the
current behavior? Should it note the debug-cache exception, or state
explicitly that gating on the CPU feature is deliberately stricter than
kmalloc_nolock()'s minimum requirement?


---
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/33598715943

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH bpf v2] bpf, riscv: Make arena support depend on ZACAS
  2026-09-02  6:14 [PATCH bpf v2] bpf, riscv: Make arena support depend on ZACAS Chen Pei
  2026-09-02  7:00 ` bot+bpf-ci
@ 2026-09-05  3:08 ` Pu Lehui
  1 sibling, 0 replies; 3+ messages in thread
From: Pu Lehui @ 2026-09-05  3:08 UTC (permalink / raw)
  To: Chen Pei, ast, daniel, andrii, memxor, bjorn, puranjay
  Cc: ihor.solodrai, eddyz87, martin.lau, song, yonghong.song, jolsa,
	emil, pjw, palmer, guoren, bpf, linux-riscv, linux-kernel,
	stable

Hi Pei,

On 2026/9/2 14:14, Chen Pei wrote:
> The arena range tree allocates its nodes with kmalloc_nolock() since
> commit f8c67d8550ee ("bpf: Use kmalloc_nolock() in range tree").
> kmalloc_nolock() requires slab caches with cmpxchg128 support
> (__CMPXCHG_DOUBLE); on riscv cmpxchg128 is provided by the ZACAS
> extension. On systems without ZACAS every arena map creation fails

This limitation has a significant impact, as much of the hardware on the 
market lacks ZACAS support given that it is not mandatory in RVA23.

> with a misleading -ENOMEM.
> 
> Report the missing support instead: make bpf_jit_supports_arena()
> return system_has_cmpxchg128() where it is defined, so arena map

Originally, I thought rv_ext_enabled(ZACAS) && 
IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZACAS) would make it more explicit, but 
system_has_cmpxchg128() seems to better capture what we were missing.


Acked-by: Pu Lehui <pulehui@huawei.com>

> creation fails with -EOPNOTSUPP on systems without ZACAS. The macro
> is only defined when both CONFIG_RISCV_ISA_ZACAS and
> CONFIG_TOOLCHAIN_HAS_ZACAS are enabled, so guard it with #ifdef the
> same way mm/slab.h consumes it, and reject arena otherwise. This
> matches how arena BPF_CMPXCHG instructions are already gated on ZACAS
> in bpf_jit_supports_insn().
> 
> Fixes: f8c67d8550ee ("bpf: Use kmalloc_nolock() in range tree")
> Cc: stable@vger.kernel.org
> Signed-off-by: Chen Pei <cp0613@linux.alibaba.com>
> ---
> Changes since v1:
> - Guard system_has_cmpxchg128() with #ifdef instead of calling it
>    unconditionally: the macro is only defined when both
>    CONFIG_RISCV_ISA_ZACAS and CONFIG_TOOLCHAIN_HAS_ZACAS are enabled
>    (as reported by sashiko-bot), so v1 broke the build when either
>    was disabled. This mirrors how mm/slab.h consumes the macro.
> 
> Why #ifdef rather than rv_ext_enabled(ZACAS)? The predicates differ
> exactly in the configurations that matter:
> 
>    scenario (ISA_ZACAS/TOOLCHAIN/hw)  v1           rv_ext_enabled  #ifdef
>    ISA=n or TOOLCHAIN=n               build fails  rejects         rejects
>    ISA=y TOOLCHAIN=n hw has ZACAS     build fails  accepts, then   rejects
>                                                    -ENOMEM again
>    ISA=y TOOLCHAIN=y hw has ZACAS     exact        exact           exact
> 
> rv_ext_enabled(ZACAS) does not check CONFIG_TOOLCHAIN_HAS_ZACAS, but
> slab's cmpxchg128 - and thus kmalloc_nolock() - does require it, so
> on an old toolchain with ZACAS hardware it would accept arena maps
> and bring back the very -ENOMEM failure this patch fixes. The #ifdef
> form builds in every configuration and matches exactly the
> kmalloc_nolock() availability gate in mm/slab.h.
> 
> This issue was reported by sashiko-bot:
> https://sashiko.dev/#/patchset/20260901120013.16104-1-cp0613@linux.alibaba.com?part=1
> 
> Question for reviewers: should the arena selftests gate on ZACAS,
> e.g. probing it via riscv_hwprobe() (RISCV_ISA_EXT_ZACAS) and
> SKIPping cleanly on systems without the extension?

riscv isn't currently integrated into the BPF CI, and handling this 
locally via qemu is fairly straightforward, so I'm not entirely sure 
this is strictly necessary.

> 
>   arch/riscv/net/bpf_jit_comp64.c | 10 +++++++++-
>   1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c
> index 74efe4b138d2..151031e97a24 100644
> --- a/arch/riscv/net/bpf_jit_comp64.c
> +++ b/arch/riscv/net/bpf_jit_comp64.c
> @@ -2128,7 +2128,15 @@ bool bpf_jit_supports_ptr_xchg(void)
>   
>   bool bpf_jit_supports_arena(void)
>   {
> -	return true;
> +	/*
> +	 * The arena range tree uses kmalloc_nolock(), which needs
> +	 * cmpxchg128, provided by ZACAS on riscv.
> +	 */
> +#ifdef system_has_cmpxchg128
> +	return system_has_cmpxchg128();
> +#else
> +	return false;
> +#endif
>   }
>   
>   bool bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena)

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-09-05  3:08 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-02  6:14 [PATCH bpf v2] bpf, riscv: Make arena support depend on ZACAS Chen Pei
2026-09-02  7:00 ` bot+bpf-ci
2026-09-05  3:08 ` Pu Lehui

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®