Re: [PATCH bpf v3] bpf: do not use kmalloc_nolock when !HAVE_CMPXCHG_DOUBLE
From: Levi Zim
Date: Mon Mar 16 2026 - 11:48:32 EST
On 3/16/26 11:05 PM, Paul Chaignon wrote:
> On Sun, Mar 15, 2026 at 12:02:48AM +0800, Levi Zim via B4 Relay wrote:
>> From: Levi Zim <rsworktech@xxxxxxxxxxx>
>>
>> kmalloc_nolock always fails for architectures that lack cmpxchg16b.
>> For example, this causes bpf_task_storage_get with flag
>> BPF_LOCAL_STORAGE_GET_F_CREATE to fails on riscv64 6.19 kernel.
>>
>> Fix it by enabling use_kmalloc_nolock only when HAVE_CMPXCHG_DOUBLE.
>> But leave the PREEMPT_RT case as is because it requires kmalloc_nolock
>> for correctness. Add a comment about this limitation that architecture's
>> lack of CMPXCHG_DOUBLE combined with PREEMPT_RT could make
>> bpf_local_storage_alloc always fail.
>>
>> Fixes: f484f4a3e058 ("bpf: Replace bpf memory allocator with kmalloc_nolock() in local storage")
>> Cc: stable@xxxxxxxxxxxxxxx
>> Signed-off-by: Levi Zim <rsworktech@xxxxxxxxxxx>
>> ---
>
> Note there may be something broken with your setup as lore is reporting
> that you sent this v3 email three times. Not sure if it could be an
> issue.
Thanks for reporting! But I only send PATCH v3 once using b4 with web endpoint.
I only received a single email myself.
So I guess it is a bug with b4 or lore.
>
> [...]
>
>> diff --git a/kernel/bpf/bpf_task_storage.c b/kernel/bpf/bpf_task_storage.c
>> index 605506792b5b4..6e8597edea314 100644
>> --- a/kernel/bpf/bpf_task_storage.c
>> +++ b/kernel/bpf/bpf_task_storage.c
>> @@ -212,7 +212,8 @@ static int notsupp_get_next_key(struct bpf_map *map, void *key, void *next_key)
>>
>> static struct bpf_map *task_storage_map_alloc(union bpf_attr *attr)
>> {
>> - return bpf_local_storage_map_alloc(attr, &task_cache, true);
>> + return bpf_local_storage_map_alloc(attr, &task_cache,
>> + KMALLOC_NOLOCK_SUPPORTED);
>
> I can confirm that this does fix one selftest using
> BPF_LOCAL_STORAGE_GET_F_CREATE on riscv64: test_ls_map_kptr_ref1 in
> map_kptr. Other tests using BPF_LOCAL_STORAGE_GET_F_CREATE are still
> failing so I guess they have other issues.
>
> Tested-by: Paul Chaignon <paul.chaignon@xxxxxxxxx>
Thanks very much for testing this patch!
I am not sure why the other tests fail but perhaps it is because
a big issue for fentry/kprobe on riscv64 is that the first function argument
cannot be read as a0 register is clobbered [1].
I will try to run the selftests on riscv64 when I have more time.
IIRC the issue is workaround-ed by using PTRACE_GET_SYSCALL_INFO for ptrace.
But I got surprised by it again when adding riscv64 to my CI setup.
A working kprobe/fentry bpf program on other architectures cannot read the
first argument of exec family syscalls on riscv64 at all [2].
[1]: https://github.com/strace/strace/issues/315
[2]: https://github.com/kxxt/tracexec/actions/runs/23147343712/job/67247821299#step:6:1429
Best regards,
Levi
>
>> }
>>
>> static void task_storage_map_free(struct bpf_map *map)
>>
>> ---
>> base-commit: e06e6b8001233241eb5b2e2791162f0585f50f4b
>> change-id: 20260314-bpf-kmalloc-nolock-60da80e613de
>>
>> Best regards,
>> --
>> Levi Zim <rsworktech@xxxxxxxxxxx>
>>
>>
>>