Re: [RFC PATCH] mm: restrict can_spin_trylock() to preemptible context on PREEMPT_RT

From: Karl Mehltretter

Date: Tue Sep 22 2026 - 02:04:42 EST


On Sat, Sep 19, 2026 at 06:17:30PM +0100, Alexei Starovoitov wrote:
> 6.19 had this check in kmalloc_nolock() only. alloc_pages_nolock() and
> free_pages_nolock() allowed irqs disabled since they were introduced,
> and arena was sleepable only under a mutex back then.

Hi Alexei,

Thanks for the review!

> No. This kills bpf arena on RT.

I have now confirmed by testing that the RFC breaks both BPF arena paths
on PREEMPT_RT.

> As Sebastian said in
> https://lore.kernel.org/r/20260831143500.x-saxdAs@xxxxxxxxxxxxx
> raw_spinlock_t is fine in general. pi_lock is special. rq lock too,
> I think, since rt_spin_unlock() can end up in try_to_wake_up().
> The check has to be about those and not about every irq/preempt
> disabled section.

This leaves me unsure where the boundary between the MM and BPF fixes
should be. I see four possible directions:

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?

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. Since the allocator change would restore
the behavior before f484f4a3e058 and be confined to BPF, could this
also be suitable for stable kernels?

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.

d) Combine (b) and (c) restore BPF functionality first, then add
the MM restriction for other and future callers.

Are these the right alternatives? In particular, what behavior is
intended from the _nolock() API in these scheduler-lock contexts?

Thanks,
Karl