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

From: sashiko-bot

Date: Sat Sep 19 2026 - 13:24:50 EST


Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] mm: can_spin_trylock() uses !preemptible() causing persistent bailout
--

commit da2bda4aca43320be916d709a95e77705d7bd75f
Author: Karl Mehltretter <kmehltretter@xxxxxxxxx>

mm: restrict can_spin_trylock() to preemptible context on PREEMPT_RT

This patch resolves a deadlock on PREEMPT_RT during kmalloc_nolock() by
restricting can_spin_trylock() to preemptible contexts only. It prevents
nested lock acquisition of the pi_lock when called from sched_waking
tracepoints inside try_to_wake_up().

> diff --git a/mm/internal.h b/mm/internal.h
> --- a/mm/internal.h
> +++ b/mm/internal.h
[ ... ]
> @@ -1641,10 +1641,14 @@ static inline bool can_spin_trylock(void)
> * confuse PI logic, so return immediately if called from hard IRQ or
> * NMI.
> *
> - * Note, irqs_disabled() case is ok. spin_trylock() can be called
> - * from raw_spin_lock_irqsave region.
> + * Task context with a raw spinlock held is not safe either. The
> + * caller may hold a pi_lock, like a BPF program on a tracepoint in
> + * try_to_wake_up(). rt_spin_trylock() takes the rtmutex wait_lock
> + * and can take a pi_lock under it. rt_spin_unlock() wakes a waiter
> + * if there is one, which takes a pi_lock again. The locks held by
> + * the caller are not known here, so allow preemptible context only.
> */
> - if (IS_ENABLED(CONFIG_PREEMPT_RT) && (in_nmi() || in_hardirq()))
> + if (IS_ENABLED(CONFIG_PREEMPT_RT) && !preemptible())

[Severity: Medium]
Does this !preemptible() check create a persistent bailout for ALLOC_TRYLOCK
paths on PREEMPT_RT?

BPF programs attached to non-faultable tracepoints run with preemption
disabled via guard(preempt_notrace). When they attempt to create task local
storage using kmalloc_nolock(), it calls can_spin_trylock().

Because preemption is always disabled inside the tracepoint, this check
acts as a persistent bailout rather than a transient one, unconditionally
failing the allocation on PREEMPT_RT. Will this permanently break BPF task
storage creation in tracepoints on PREEMPT_RT?

> return false;
>
> /* On UP, spin_trylock() always succeeds even when it is locked */

--
Sashiko AI review · https://sashiko.dev/#/patchset/20260919171443.90512-1-kmehltretter@xxxxxxxxx?part=1