Re: [syzbot] [mm?] INFO: rcu detected stall in khugepaged (3)

"Paul E. McKenney" <[email protected]>
Newsgroups gmane.linux.kernel,gmane.linux.kernel.mm
Message-ID <3fca260a-4544-4e65-916e-d2ef7fa1440f@paulmck-laptop>
On Wed, Aug 05, 2026 at 11:03:11PM -0700, Andrew Morton wrote:
> On Wed, 5 Aug 2026 13:28:16 -0700 "Paul E. McKenney" <[email protected]> wrote:
> 
> > > collapse_scan_file()'s main loop has
> > > 
> > > 		if (need_resched()) {
> > > 			xas_pause(&xas);
> > > 			cond_resched_rcu();
> > > 		}
> > > 
> > > but that won't help with the RCU stall detector(?).
> > > 
> > > I suggest that a suitable fix here would be to add the analogous
> > > 
> > > 	if (rcu_i_need_to_take_a_break()) {
> > > 		rcu_read_unlock();
> > > 		rcu_take_a_break())	
> > > 		rcu_read_lock();
> > > 	}
> > > 
> > > (iirc rcu_read_unlock() does an rcu run, so rcu_take_a_break() isn't
> > > needed here)
> > > 
> > > Paul, wdyt?
> > 
> > Let's see...
> > 
> > The console log says "rcu_preempt detected stalls on CPUs/tasks",
> > which means that cond_resched() is a no-op, but it also means that
> > the rcu_read_unlock() in cond_resched_rcu() will directly take care of
> > informing RCU of the pause.
> > 
> > But that is clearly not happening.  Why?
> > 
> > Well, we have this:
> > 
> > rcu: 	Tasks blocked on level-0 rcu_node (CPUs 0-1): P37/1:b..l
> > 
> > This means that the task whose RCU read-side critical section is blocking
> > the current RCU grace period isn't even running, and thus cannot invoke
> > cond_resched_rcu(), let alone the rcu_read_unlock() within that function.
> > So an RCU CPU stall warning is expected behavior.  Or at least it is not
> > in any way ruled out.
> > 
> > What we need is RCU priority boosting.
> 
> Do we?  I'm suggesting we need need_resched_rcu()!

Understood, and I initially agreed with you.  Except that I then
found that the poor preempted task isn't executing anything at all.
Which means that an added need_resched_rcu() cannot possibly help.

> > Except that the .config file
> > does not enable this.  Not only is there no CONFIG_RCU_BOOST=y, there
> > is also no CONFIG_RCU_EXPERT=y and no CONFIG_PREEMPT_RT=y.  But there
> > is CONFIG_RT_MUTEX=y and CONFIG_RCU_EXPERT=y.
> > 
> > Because we don't have RCU priority boosting, if the load on the system
> > is heavy enough to prevent our poor preempted RCU reader (PID 37) from
> > running, the grace period cannot end.
> > 
> > I am not sure why this task is saving its stack, but maybe that is normal
> > for this code path?
> > 
> > My bemusement aside, I recommend running this test either with
> > non-preemptible RCU (CONFIG_PREEMPT_LAZY=y these days) or enabling RCU
> > priority boosting (CONFIG_RCU_EXPERT=y and CONFIG_RCU_BOOST=y).
> > 
> > Maybe RCU_BOOST should no longer depend on RCU_EXPERT?  I would of
> > course need ot remove the prompt ("Enable RCU priority boosting") to
> > avoid annoying Linus.  Maybe as shown below.
> > 
> > Thoughts?
> 
> If I'm understanding correctly, this workload is busted with this
> config and the proposed fix is to alter the config?  Well, why are we
> permitting that config at all?

Agreed, and my proposal is in fact to remove that config.  This assumes
that CONFIG_RCU_BOOST is ready for prime time, and given that I have
been testing it for years and that CONFIG_PREEMPT_RT has been using it
for years, I am cautiously optimistic.

> Seems to me that a solution to permit this config to work is very
> simple.  Something like:
> 
> 	time_t start;
> 
> 	rcu_read_lock();
> 	start = current_time();
> 
> 	for (lots of work) {
> 		...
> 		if (need_resched_rcu(start)) {
> 			cond_resched_rcu();
> 			start = current_time();
> 	}
> 
> Where need_resched_rcu() tests to see if we're getting close to hitting
> the watchdog timeout.
> 
> No?

No.

Added code doesn't help a task that has been preempted for some seconds
and thus isn't executing any code at all.

The task has been preempted while within an RCU read-side critical
section.  The sequence of events is as follows:

	rcu_read_lock();
	// preempted for many tens of seconds.
	cond_resched_rcu(); // doesn't help because it is never executed.
	rcu_read_unlock();

Or am I missing your point?

							Thanx, Paul
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.