]> git.ipfire.org Git - thirdparty/kernel/linux.git/commit
bpf: arena: make arena kfuncs any context safe
authorPuranjay Mohan <puranjay@kernel.org>
Mon, 22 Dec 2025 19:50:18 +0000 (11:50 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Tue, 23 Dec 2025 19:30:00 +0000 (11:30 -0800)
commitb8467290edab4bafae352bf3f317055669a1a458
tree8cef38c8c6b6173f0d994eff3f684f5053f9cccd
parent360c35f8ffae0f184805d9eb7d126474345bac9b
bpf: arena: make arena kfuncs any context safe

Make arena related kfuncs any context safe by the following changes:

bpf_arena_alloc_pages() and bpf_arena_reserve_pages():
Replace the usage of the mutex with a rqspinlock for range tree and use
kmalloc_nolock() wherever needed. Use free_pages_nolock() to free pages
from any context.
apply_range_set/clear_cb() with apply_to_page_range() has already made
populating the vm_area in bpf_arena_alloc_pages() any context safe.

bpf_arena_free_pages(): defer the main logic to a workqueue if it is
called from a non-sleepable context.

specialize_kfunc() is used to replace the sleepable arena_free_pages()
with bpf_arena_free_pages_non_sleepable() when the verifier detects the
call is from a non-sleepable context.

In the non-sleepable case, arena_free_pages() queues the address and the
page count to be freed to a lock-less list of struct arena_free_spans
and raises an irq_work. The irq_work handler calls schedules_work() as
it is safe to be called from irq context.  arena_free_worker() (the work
queue handler) iterates these spans and clears ptes, flushes tlb, zaps
pages, and calls __free_page().

Signed-off-by: Puranjay Mohan <puranjay@kernel.org>
Link: https://lore.kernel.org/r/20251222195022.431211-4-puranjay@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
include/linux/bpf.h
kernel/bpf/arena.c
kernel/bpf/verifier.c