[PATCH] bpf: arena: reschedule while freeing the arena pages

From: Breno Leitao

Date: Mon Aug 24 2026 - 12:57:03 EST


On non-preemptible kernels that is long enough to trip both the RCU
stall detector and the softlockup watchdog. Observed on production arm64
hosts at Meta:

rcu: INFO: rcu_sched self-detected stall on CPU
rcu: 37-....: (20999 ticks this GP) idle=3834/1/0x4000000000000000
Workqueue: events_unbound bpf_map_free_deferred
Call trace:
__apply_to_page_range+0x404/0x518
apply_to_existing_page_range+0x18/0x28
arena_map_free+0x54/0x98
bpf_map_free_deferred+0x70/0xf8
process_scheduled_works+0x17c/0x400
worker_thread+0x198/0x498
[...]
watchdog: BUG: soft lockup - CPU#37 stuck for 44s! [kworker/u288:15]
Kernel panic - not syncing: softlockup: hung tasks

arena_map_free() sweeps the whole 4GiB arena address range in a single
apply_to_existing_page_range() call and drops every populated page from
the walk callback.

Give up the CPU after releasing each page, using cond_resched().

Fixes: 317460317a02 ("bpf: Introduce bpf_arena.")
Signed-off-by: Breno Leitao <leitao@xxxxxxxxxx>
---
kernel/bpf/arena.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/kernel/bpf/arena.c b/kernel/bpf/arena.c
index 7b6847200b431..c5f6bebbb15c3 100644
--- a/kernel/bpf/arena.c
+++ b/kernel/bpf/arena.c
@@ -364,6 +364,7 @@ static int existing_page_cb(pte_t *ptep, unsigned long addr, void *data)
* the freed page. So it all relies on 1.
*/
__free_page(page);
+ cond_resched();
return 0;
}


---
base-commit: 0a0d1d55dad570724bf8c7ea83409639cfb4be9b
change-id: 20260824-b4-bpf-arena-free-resched-e20ba0eb8919

Best regards,
--
Breno Leitao <leitao@xxxxxxxxxx>