On Tue, Jun 16, 2026 at 12:44:48AM +0800, [email protected] wrote:
> From: Wen Yang <[email protected]>
>
> The DEFINE_WAIT_OVERRIDE_MAP() macro creates a lockdep map with
> wait_type_inner = LD_WAIT_CONFIG, which inherits the outer context's
> wait type. When rv_react() is called from a LD_WAIT_FREE context
> (e.g., a KUnit test with busy-wait), and the reactor callback triggers
> a timer interrupt during the busy-loop, the interrupt exit path attempts
> to schedule (preempt_schedule_irq -> __schedule -> rq->__lock), which is
> LD_WAIT_SPIN. Lockdep then reports:
>
> [ BUG: Invalid wait context ]
> context-{5:5}
> 1 lock held by kunit_try_catch/209:
> #0: rv_react_map-wait-type-override at rv_react+0x9d/0xf0
It would be nice to have the full trace here from your real-world example.
> The wait_type_override map allowed the outer LD_WAIT_FREE to propagate
> inward, but scheduling from an interrupt is LD_WAIT_SPIN, violating the
> constraint.
>
> Fix by explicitly setting wait_type_inner = LD_WAIT_SPIN, which is the
> tightest constraint rv_react() callbacks must satisfy: they may not
> sleep (LD_WAIT_SLEEP) or use mutexes, but can use spinlocks and be
> interrupted. This matches the documented LD_WAIT_FREE constraint.
So this is not a pure fix but a change in behavior. This should be
reflected in the subject.
> Fixes: 69d8895cb9a9 ("rv: Add explicit lockdep context for reactors")
> Signed-off-by: Wen Yang <[email protected]>
> Cc: Thomas Weißschuh <[email protected]>
> ---
> kernel/trace/rv/rv_reactors.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/trace/rv/rv_reactors.c b/kernel/trace/rv/rv_reactors.c
> index 460af07f7aba..423f843bbd68 100644
> --- a/kernel/trace/rv/rv_reactors.c
> +++ b/kernel/trace/rv/rv_reactors.c
> @@ -465,7 +465,13 @@ int init_rv_reactors(struct dentry *root_dir)
>
> void rv_react(struct rv_monitor *monitor, const char *msg, ...)
> {
> - static DEFINE_WAIT_OVERRIDE_MAP(rv_react_map, LD_WAIT_FREE);
> +#ifdef CONFIG_LOCKDEP
> + static struct lockdep_map rv_react_map = {
> + .name = "rv_react",
> + .wait_type_outer = LD_WAIT_FREE,
> + .wait_type_inner = LD_WAIT_SPIN,
> + };
> +#endif
This now allows reactors to take (raw) spinlocks. The original idea was
to not allow that as a reactor can be called from LD_WAIT_FREE context.
So I am not sure this is the right fix. Not that I have a better one
available right now.
> va_list args;
>
> if (!rv_reacting_on() || !monitor->react)
> --
> 2.25.1
>