All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Paul E. McKenney" <paulmck@linux.ibm.com>
To: Scott Wood <swood@redhat.com>
Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
	Peter Zijlstra <peterz@infradead.org>,
	Steven Rostedt <rostedt@goodmis.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Juri Lelli <juri.lelli@redhat.com>,
	Clark Williams <williams@redhat.com>,
	linux-rt-users@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [RFC PATCH RT 3/4] rcu: unlock special: Treat irq and preempt disabled the same
Date: Thu, 20 Jun 2019 14:10:05 -0700	[thread overview]
Message-ID: <20190620211005.GW26519@linux.ibm.com> (raw)
In-Reply-To: <20190619011908.25026-4-swood@redhat.com>

On Tue, Jun 18, 2019 at 08:19:07PM -0500, Scott Wood wrote:
> [Note: Just before posting this I noticed that the invoke_rcu_core stuff
>  is part of the latest RCU pull request, and it has a patch that
>  addresses this in a more complicated way that appears to deal with the
>  bare irq-disabled sequence as well.

Far easier to deal with it than to debug the lack of it.  ;-)

>  Assuming we need/want to support such sequences, is the
>  invoke_rcu_core() call actually going to result in scheduling any
>  sooner?  resched_curr() just does the same setting of need_resched
>  when it's the same cpu.
> ]

Yes, invoke_rcu_core() can in some cases invoke the scheduler sooner.
Setting the CPU-local bits might not have effect until the next interrupt.

So if -rt wants the simpler and slower approach, the change needs to
use IS_ENABLED(CONFIG_PREEMPT_RT_FULL) or similar.  Not that this is
an issue until CONFIG_PREEMPT_RT_FULL hits mainline.

							Thanx, Paul

> Since special should never be getting set inside an irqs-disabled
> critical section, this is safe as long as there are no sequences of
> rcu_read_lock()/local_irq_disable()/rcu_read_unlock()/local_irq_enable()
> (without preempt_disable() wrapped around the IRQ disabling, as spinlocks
> do).  If there are such sequences, then the grace period may be delayed
> until the next time need_resched is checked.
> 
> This is needed because otherwise, in a sequence such as:
> 1. rcu_read_lock()
> 2. *preempt*, set rcu_read_unlock_special.b.blocked
> 3. preempt_disable()
> 4. rcu_read_unlock()
> 5. preempt_enable()
> 
> ...rcu_read_unlock_special.b.blocked will not be cleared during
> step 4, because of the disabled preemption.  If an interrupt is then
> taken between steps 4 and 5, and that interrupt enters scheduler code
> that takes pi/rq locks, and an rcu read lock inside that, then when
> dropping that rcu read lock we will end up in rcu_read_unlock_special()
> again -- but this time, since irqs are disabled, it will call
> invoke_rcu_core() in the RT tree (regardless of PREEMPT_RT_FULL), which
> calls wake_up_process().  This can cause a pi/rq lock deadlock.  An
> example of interrupt code that does this is scheduler_tick().
> 
> The above sequence can be found in (at least) __lock_task_sighand() (for
> !PREEMPT_RT_FULL) and d_alloc_parallel().
> 
> It's potentially an issue on non-RT as well.  While
> raise_softirq_irqoff() doesn't call wake_up_process() when in_interrupt()
> is true, if code between steps 4 and 5 directly calls into scheduler
> code, and that code uses RCU with pi/rq lock held, wake_up_process() can
> still be called.
> 
> On RT, migrate_enable() is such a codepath, so an in_interrupt() check
> alone would not work on RT.  Instead, keep track of whether we've already
> had an rcu_read_unlock_special() with preemption disabled but haven't yet
> scheduled, and rely on the preempt_enable() yet to come instead of
> calling invoke_rcu_core().
> 
> Signed-off-by: Scott Wood <swood@redhat.com>
> ---
>  kernel/rcu/tree_plugin.h | 10 ++--------
>  1 file changed, 2 insertions(+), 8 deletions(-)
> 
> diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
> index 5d63914b3687..d7ddbcc7231c 100644
> --- a/kernel/rcu/tree_plugin.h
> +++ b/kernel/rcu/tree_plugin.h
> @@ -630,14 +630,8 @@ static void rcu_read_unlock_special(struct task_struct *t)
>  	if (preempt_bh_were_disabled || irqs_were_disabled) {
>  		WRITE_ONCE(t->rcu_read_unlock_special.b.exp_hint, false);
>  		/* Need to defer quiescent state until everything is enabled. */
> -		if (irqs_were_disabled) {
> -			/* Enabling irqs does not reschedule, so... */
> -			invoke_rcu_core();
> -		} else {
> -			/* Enabling BH or preempt does reschedule, so... */
> -			set_tsk_need_resched(current);
> -			set_preempt_need_resched();
> -		}
> +		set_tsk_need_resched(current);
> +		set_preempt_need_resched();
>  		local_irq_restore(flags);
>  		return;
>  	}
> -- 
> 1.8.3.1
> 

  reply	other threads:[~2019-06-20 21:10 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-19  1:19 [PATCH RT 0/4] Address rcutorture issues Scott Wood
2019-06-19  1:19 ` [PATCH RT 1/4] rcu: Acquire RCU lock when disabling BHs Scott Wood
2019-06-20 20:53   ` Paul E. McKenney
2019-06-20 21:06     ` Scott Wood
2019-06-20 21:20       ` Paul E. McKenney
2019-06-20 21:38         ` Scott Wood
2019-06-20 22:16           ` Paul E. McKenney
2019-06-19  1:19 ` [PATCH RT 2/4] sched: migrate_enable: Use sleeping_lock to indicate involuntary sleep Scott Wood
2019-06-19  1:19 ` [RFC PATCH RT 3/4] rcu: unlock special: Treat irq and preempt disabled the same Scott Wood
2019-06-20 21:10   ` Paul E. McKenney [this message]
2019-06-20 21:59     ` Scott Wood
2019-06-20 22:25       ` Paul E. McKenney
2019-06-20 23:08         ` Scott Wood
2019-06-22  0:26           ` Paul E. McKenney
2019-06-22 19:13             ` Paul E. McKenney
2019-06-24 17:40               ` Scott Wood
2019-06-19  1:19 ` [RFC PATCH RT 4/4] rcutorture: Avoid problematic critical section nesting Scott Wood
2019-06-20 21:18   ` Paul E. McKenney
2019-06-20 21:43     ` Scott Wood
2019-06-21 16:38     ` Sebastian Andrzej Siewior
2019-06-21 23:59       ` Paul E. McKenney
2019-06-26 15:08         ` Steven Rostedt
2019-06-26 16:49           ` Scott Wood
2019-06-27 18:00             ` Paul E. McKenney
2019-06-27 20:16               ` Scott Wood
2019-06-27 20:50                 ` Paul E. McKenney
2019-06-27 22:46                   ` Scott Wood
2019-06-28  0:52                     ` Paul E. McKenney
2019-06-28 19:37                       ` Scott Wood
2019-06-28 20:24                         ` Paul E. McKenney
2019-06-20 19:12 ` [PATCH RT 0/4] Address rcutorture issues Paul E. McKenney

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190620211005.GW26519@linux.ibm.com \
    --to=paulmck@linux.ibm.com \
    --cc=bigeasy@linutronix.de \
    --cc=juri.lelli@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rt-users@vger.kernel.org \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=swood@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=williams@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.