Re: [PATCH] rcu: Print CPU that preempted stalled reader wants to run on

From: Paul E. McKenney

Date: Wed Oct 21 2026 - 00:03:37 EST


On Wed, Oct 21, 2026 at 09:11:02AM +0530, K Prateek Nayak wrote:
> Hello Paul,
>
> On 10/20/2026 2:17 AM, Paul E. McKenney wrote:
> > This commit defines a cpu_curr_snapshot_rcu() function that invokes
> > rcu_dereference_all(cpu_curr()) to determine which task is currently
> > running on the specified CPU. The RCU CPU stall warning then uses this
> > new function in order to print the task that has preempted the stalled
> > task (the stalled task being the one that is in an RCU read-side critical
> > section, thus preventing the current RCU grace period from completing).
> > This modified stall-warning message also includes the CPU, along with
> > an exclamation mark ("!") after the CPU number if that CPU is currently
> > offline.
> >
> > This is a potential step towards allowing people (or LLMs, for that
> > matter) locate any tasks that might be preventing the preempted RCU
> > reader task from running.
> >
> > Adding a get_task_struct() for the currently running task would be a
> > bug because we are not in a position to prevent that task from exiting.
> > Yes, yes, because interrupts are disabled throughout, the corresponding
> > task_struct structure cannot be freed, but following sequence of events
> > is all too possible:
> >
> > o The check_slow_task() function places a pointer to the task_struct
> > structure in its local variable "th".
> >
> > o The corresponding task exits, reducing its task_struct structure's
> > ->usage to zero. The task_struct structure is therefore passed
> > to call_rcu().
> >
> > o The check_slow_task() function invokes get_task_struct(th),
> > setting th->usage to one.
> >
> > o The rcu_print_task_stall() function invokes put_task_struct(),
> > again reducing ->usage to zero, and again passing the task
> > struct to call_rcu(). This results in either double-call_rcu()
> > or use-after-free, depending on when the RCU grace period for
> > the first call_rcu() completes. Both outcomes are bad.
> >
> > This commit therefore relies solely on disabled interrupts acting as
> > an implicit RCU read-side critical section that prevents all of the
> > task_struct structures from being freed, thus avoiding the need for
> > get_task_struct().
> >
> > The original get_task_struct() calls in rcu_print_task_stall() on the
> > tasks on the ->blkd_tasks list are safe because those tasks cannot exit
> > without first acquiring the rcu_node ->lock that this code already holds
> > (because these tasks must remove themselves from the ->blkd_tasks list).
> > But it is better to be consistent and rely on RCU in both cases.
> > These pre-existing get_task_struct() and put_task_struct() calls are
> > therefore removed.
> >
> > [ paulmck: Apply feedback from K Prateek Nayak and Peter Zijlstra. ]
> > [ paulmck: Apply feedback from Steven Rostedt. ]
> >
> > Link: https://lore.kernel.org/all/a7a21bf3-a7d5-45bb-be4f-0119fe53fa20@paulmck-laptop/
> > Link: https://lore.kernel.org/all/e8b6b372-d16b-4939-aa7a-755b7149e0fb@paulmck-laptop/
> > Signed-off-by: Paul E. McKenney <paulmck@xxxxxxxxxx>
> > Reviewed-by: Steven Rostedt <rostedt@xxxxxxxxxxx>
>
> I tested this on your old dev branch on top of commit 5433117c67f0 ("EXP
> rcutorture: Disable RCU priority boost testing on non-TREE03 scenarios")
> and the idle state during stalls are reported correctly.
>
> Feel free to include:
>
> Reviewed-by: K Prateek Nayak <kprateek.nayak@xxxxxxx>
> Tested-by: K Prateek Nayak <kprateek.nayak@xxxxxxx>

Thank you, and I will apply this on my next rebase.

> > diff --git a/include/linux/sched.h b/include/linux/sched.h
> > index 8b3d47a325cca..3606e5a2cec32 100644
> > --- a/include/linux/sched.h
> > +++ b/include/linux/sched.h
> > @@ -2532,3 +2532,5 @@ extern void migrate_enable(void);
> > DEFINE_LOCK_GUARD_0(migrate, migrate_disable(), migrate_enable())
> >
> > #endif
> > +
> > +struct task_struct *cpu_curr_snapshot_rcu(int cpu);
>
> nit.
>
> I think this and the function definition in core.c can go right after
> cpu_curr_snapshot() in respective files to keep the related bits
> together.

Excellent idea, especially given that its current location is getting me
merge conflicts when I test with the -next tree. Done!

Thanx, Paul