Re: [RFC PATCH] mm: restrict can_spin_trylock() to preemptible context on PREEMPT_RT
From: Alexei Starovoitov
Date: Fri Sep 25 2026 - 00:12:53 EST
On Tue, Sep 22, 2026 at 08:04 AM Karl Mehltretter <kmehltretter@xxxxxxxxx> wrote:
> a) Change MM so _nolock() allocation remains safe and can still succeed
> while pi_lock or an rq lock is held. Existing BPF behavior would
> remain unchanged. Is this feasible, or would it require substantial
> allocator changes?
I don't think it's feasible. On RT the sheaves lock, n->list_lock and
zone->lock are all rtmutex based. When trylock succeeded and a waiter
showed up rt_spin_unlock() has to wake it.
> b) Restore BPF local storage's dedicated allocator, and document, with
> debug checks if possible, that _nolock() must not be used in those
> scheduler-lock contexts.
No. Local storage is not the only one. bpf_arena_alloc_pages(),
bpf_stream_vprintk(), bpf_task_work_schedule_*() call kmalloc_nolock()
as well and the same sched_waking prog can call them.
bpf_mem_alloc was removed from local storage, because it wastes memory
on preallocation. Same answer for d).
> c) Have MM detect those contexts and return NULL. This prevents the
> deadlock while preserving ordinary raw-lock callers such as arena,
> but task-storage creation from scheduler tracepoints then fails
> deterministically.
This one.
bpf_task_storage_get() with F_CREATE can return NULL and the progs
have to check for it anyway.
> Are these the right alternatives? In particular, what behavior is
> intended from the _nolock() API in these scheduler-lock contexts?
It can be called from any context and it can return NULL.
That's what it does from NMI and hardirq on RT already.