From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: x86@kernel.org, Paul McKenney <paulmck@kernel.org>,
Josh Poimboeuf <jpoimboe@redhat.com>,
"Joel Fernandes (Google)" <joel@joelfernandes.org>,
"Steven Rostedt (VMware)" <rostedt@goodmis.org>,
Masami Hiramatsu <mhiramat@kernel.org>,
Alexei Starovoitov <ast@kernel.org>,
Frederic Weisbecker <frederic@kernel.org>,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
Brian Gerst <brgerst@gmail.com>, Juergen Gross <jgross@suse.com>,
Alexandre Chartre <alexandre.chartre@oracle.com>,
Peter Zijlstra <peterz@infradead.org>,
Tom Lendacky <thomas.lendacky@amd.com>,
Paolo Bonzini <pbonzini@redhat.com>,
kvm@vger.kernel.org
Subject: [RESEND][patch V3 02/23] rcu: Add comments marking transitions between RCU watching and not
Date: Fri, 20 Mar 2020 18:59:58 +0100 [thread overview]
Message-ID: <20200320180032.614150506@linutronix.de> (raw)
In-Reply-To: 20200320175956.033706968@linutronix.de
From: "Paul E. McKenney" <paulmck@kernel.org>
It is not as clear as it might be just where in RCU's idle entry/exit
code RCU stops and starts watching the current CPU. This commit therefore
adds comments calling out the transitions.
Reported-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lkml.kernel.org/r/20200313024046.27622-2-paulmck@kernel.org
---
kernel/rcu/tree.c | 29 +++++++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -224,7 +224,9 @@ void rcu_softirq_qs(void)
/*
* Record entry into an extended quiescent state. This is only to be
- * called when not already in an extended quiescent state.
+ * called when not already in an extended quiescent state, that is,
+ * RCU is watching prior to the call to this function and is no longer
+ * watching upon return.
*/
static void rcu_dynticks_eqs_enter(void)
{
@@ -237,7 +239,7 @@ static void rcu_dynticks_eqs_enter(void)
* next idle sojourn.
*/
seq = atomic_add_return(RCU_DYNTICK_CTRL_CTR, &rdp->dynticks);
- /* Better be in an extended quiescent state! */
+ // RCU is no longer watching. Better be in extended quiescent state!
WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) &&
(seq & RCU_DYNTICK_CTRL_CTR));
/* Better not have special action (TLB flush) pending! */
@@ -247,7 +249,8 @@ static void rcu_dynticks_eqs_enter(void)
/*
* Record exit from an extended quiescent state. This is only to be
- * called from an extended quiescent state.
+ * called from an extended quiescent state, that is, RCU is not watching
+ * prior to the call to this function and is watching upon return.
*/
static void rcu_dynticks_eqs_exit(void)
{
@@ -260,6 +263,7 @@ static void rcu_dynticks_eqs_exit(void)
* critical section.
*/
seq = atomic_add_return(RCU_DYNTICK_CTRL_CTR, &rdp->dynticks);
+ // RCU is now watching. Better not be in an extended quiescent state!
WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) &&
!(seq & RCU_DYNTICK_CTRL_CTR));
if (seq & RCU_DYNTICK_CTRL_MASK) {
@@ -562,6 +566,7 @@ static void rcu_eqs_enter(bool user)
WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) &&
rdp->dynticks_nesting == 0);
if (rdp->dynticks_nesting != 1) {
+ // RCU will still be watching, so just do accounting and leave.
rdp->dynticks_nesting--;
return;
}
@@ -574,7 +579,9 @@ static void rcu_eqs_enter(bool user)
rcu_prepare_for_idle();
rcu_preempt_deferred_qs(current);
WRITE_ONCE(rdp->dynticks_nesting, 0); /* Avoid irq-access tearing. */
+ // RCU is watching here ...
rcu_dynticks_eqs_enter();
+ // ... but is no longer watching here.
rcu_dynticks_task_enter();
}
@@ -654,7 +661,9 @@ static __always_inline void rcu_nmi_exit
if (irq)
rcu_prepare_for_idle();
+ // RCU is watching here ...
rcu_dynticks_eqs_enter();
+ // ... but is no longer watching here.
if (irq)
rcu_dynticks_task_enter();
@@ -729,11 +738,14 @@ static void rcu_eqs_exit(bool user)
oldval = rdp->dynticks_nesting;
WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && oldval < 0);
if (oldval) {
+ // RCU was already watching, so just do accounting and leave.
rdp->dynticks_nesting++;
return;
}
rcu_dynticks_task_exit();
+ // RCU is not watching here ...
rcu_dynticks_eqs_exit();
+ // ... but is watching here.
rcu_cleanup_after_idle();
trace_rcu_dyntick(TPS("End"), rdp->dynticks_nesting, 1, atomic_read(&rdp->dynticks));
WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && !user && !is_idle_task(current));
@@ -810,7 +822,9 @@ static __always_inline void rcu_nmi_ente
if (irq)
rcu_dynticks_task_exit();
+ // RCU is not watching here ...
rcu_dynticks_eqs_exit();
+ // ... but is watching here.
if (irq)
rcu_cleanup_after_idle();
@@ -819,9 +833,16 @@ static __always_inline void rcu_nmi_ente
} else if (irq && tick_nohz_full_cpu(rdp->cpu) &&
rdp->dynticks_nmi_nesting == DYNTICK_IRQ_NONIDLE &&
READ_ONCE(rdp->rcu_urgent_qs) && !rdp->rcu_forced_tick) {
+ // We get here only if we had already exited the extended
+ // quiescent state and this was an interrupt (not an NMI).
+ // Therefore, (1) RCU is already watching and (2) The fact
+ // that we are in an interrupt handler and that the rcu_node
+ // lock is an irq-disabled lock prevents self-deadlock.
+ // So we can safely recheck under the lock.
raw_spin_lock_rcu_node(rdp->mynode);
- // Recheck under lock.
if (rdp->rcu_urgent_qs && !rdp->rcu_forced_tick) {
+ // A nohz_full CPU is in the kernel and RCU
+ // needs a quiescent state. Turn on the tick!
rdp->rcu_forced_tick = true;
tick_dep_set_cpu(rdp->cpu, TICK_DEP_BIT_RCU);
}
WARNING: multiple messages have this Message-ID (diff)
From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: x86@kernel.org, Paul McKenney <paulmck@kernel.org>,
Josh Poimboeuf <jpoimboe@redhat.com>,
"Joel Fernandes (Google)" <joel@joelfernandes.org>,
"Steven Rostedt (VMware)" <rostedt@goodmis.org>,
Masami Hiramatsu <mhiramat@kernel.org>,
Alexei Starovoitov <ast@kernel.org>,
Frederic Weisbecker <frederic@kernel.org>,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
Brian Gerst <brgerst@gmail.com>, Juergen Gross <jgross@suse.com>,
Alexandre Chartre <alexandre.chartre@oracle.com>,
Peter Zijlstra <peterz@infradead.org>,
Tom Lendacky <thomas.lendacky@amd.com>,
Paolo Bonzini <pbonzini@redhat.com>,
kvm@vger.kernel.org
Subject: [patch V3 02/23] rcu: Add comments marking transitions between RCU watching and not
Date: Fri, 20 Mar 2020 18:59:58 +0100 [thread overview]
Message-ID: <20200320180032.614150506@linutronix.de> (raw)
In-Reply-To: 20200320175956.033706968@linutronix.de
From: "Paul E. McKenney" <paulmck@kernel.org>
It is not as clear as it might be just where in RCU's idle entry/exit
code RCU stops and starts watching the current CPU. This commit therefore
adds comments calling out the transitions.
Reported-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lkml.kernel.org/r/20200313024046.27622-2-paulmck@kernel.org
---
kernel/rcu/tree.c | 29 +++++++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -224,7 +224,9 @@ void rcu_softirq_qs(void)
/*
* Record entry into an extended quiescent state. This is only to be
- * called when not already in an extended quiescent state.
+ * called when not already in an extended quiescent state, that is,
+ * RCU is watching prior to the call to this function and is no longer
+ * watching upon return.
*/
static void rcu_dynticks_eqs_enter(void)
{
@@ -237,7 +239,7 @@ static void rcu_dynticks_eqs_enter(void)
* next idle sojourn.
*/
seq = atomic_add_return(RCU_DYNTICK_CTRL_CTR, &rdp->dynticks);
- /* Better be in an extended quiescent state! */
+ // RCU is no longer watching. Better be in extended quiescent state!
WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) &&
(seq & RCU_DYNTICK_CTRL_CTR));
/* Better not have special action (TLB flush) pending! */
@@ -247,7 +249,8 @@ static void rcu_dynticks_eqs_enter(void)
/*
* Record exit from an extended quiescent state. This is only to be
- * called from an extended quiescent state.
+ * called from an extended quiescent state, that is, RCU is not watching
+ * prior to the call to this function and is watching upon return.
*/
static void rcu_dynticks_eqs_exit(void)
{
@@ -260,6 +263,7 @@ static void rcu_dynticks_eqs_exit(void)
* critical section.
*/
seq = atomic_add_return(RCU_DYNTICK_CTRL_CTR, &rdp->dynticks);
+ // RCU is now watching. Better not be in an extended quiescent state!
WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) &&
!(seq & RCU_DYNTICK_CTRL_CTR));
if (seq & RCU_DYNTICK_CTRL_MASK) {
@@ -562,6 +566,7 @@ static void rcu_eqs_enter(bool user)
WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) &&
rdp->dynticks_nesting == 0);
if (rdp->dynticks_nesting != 1) {
+ // RCU will still be watching, so just do accounting and leave.
rdp->dynticks_nesting--;
return;
}
@@ -574,7 +579,9 @@ static void rcu_eqs_enter(bool user)
rcu_prepare_for_idle();
rcu_preempt_deferred_qs(current);
WRITE_ONCE(rdp->dynticks_nesting, 0); /* Avoid irq-access tearing. */
+ // RCU is watching here ...
rcu_dynticks_eqs_enter();
+ // ... but is no longer watching here.
rcu_dynticks_task_enter();
}
@@ -654,7 +661,9 @@ static __always_inline void rcu_nmi_exit
if (irq)
rcu_prepare_for_idle();
+ // RCU is watching here ...
rcu_dynticks_eqs_enter();
+ // ... but is no longer watching here.
if (irq)
rcu_dynticks_task_enter();
@@ -729,11 +738,14 @@ static void rcu_eqs_exit(bool user)
oldval = rdp->dynticks_nesting;
WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && oldval < 0);
if (oldval) {
+ // RCU was already watching, so just do accounting and leave.
rdp->dynticks_nesting++;
return;
}
rcu_dynticks_task_exit();
+ // RCU is not watching here ...
rcu_dynticks_eqs_exit();
+ // ... but is watching here.
rcu_cleanup_after_idle();
trace_rcu_dyntick(TPS("End"), rdp->dynticks_nesting, 1, atomic_read(&rdp->dynticks));
WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && !user && !is_idle_task(current));
@@ -810,7 +822,9 @@ static __always_inline void rcu_nmi_ente
if (irq)
rcu_dynticks_task_exit();
+ // RCU is not watching here ...
rcu_dynticks_eqs_exit();
+ // ... but is watching here.
if (irq)
rcu_cleanup_after_idle();
@@ -819,9 +833,16 @@ static __always_inline void rcu_nmi_ente
} else if (irq && tick_nohz_full_cpu(rdp->cpu) &&
rdp->dynticks_nmi_nesting == DYNTICK_IRQ_NONIDLE &&
READ_ONCE(rdp->rcu_urgent_qs) && !rdp->rcu_forced_tick) {
+ // We get here only if we had already exited the extended
+ // quiescent state and this was an interrupt (not an NMI).
+ // Therefore, (1) RCU is already watching and (2) The fact
+ // that we are in an interrupt handler and that the rcu_node
+ // lock is an irq-disabled lock prevents self-deadlock.
+ // So we can safely recheck under the lock.
raw_spin_lock_rcu_node(rdp->mynode);
- // Recheck under lock.
if (rdp->rcu_urgent_qs && !rdp->rcu_forced_tick) {
+ // A nohz_full CPU is in the kernel and RCU
+ // needs a quiescent state. Turn on the tick!
rdp->rcu_forced_tick = true;
tick_dep_set_cpu(rdp->cpu, TICK_DEP_BIT_RCU);
}
next prev parent reply other threads:[~2020-03-20 22:05 UTC|newest]
Thread overview: 67+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-20 17:59 [RESEND][patch V3 00/23] x86/entry: Consolidation part II (syscalls) Thomas Gleixner
2020-03-20 17:59 ` [patch " Thomas Gleixner
2020-03-20 17:59 ` [RESEND][patch V3 01/23] rcu: Dont acquire lock in NMI handler in rcu_nmi_enter_common() Thomas Gleixner
2020-03-20 17:59 ` [patch " Thomas Gleixner
2020-03-24 15:37 ` Frederic Weisbecker
2020-03-20 17:59 ` Thomas Gleixner [this message]
2020-03-20 17:59 ` [patch V3 02/23] rcu: Add comments marking transitions between RCU watching and not Thomas Gleixner
2020-03-24 15:38 ` Frederic Weisbecker
2020-03-20 17:59 ` [RESEND][patch V3 03/23] vmlinux.lds.h: Create section for protection against instrumentation Thomas Gleixner
2020-03-20 17:59 ` [patch " Thomas Gleixner
2020-03-24 12:26 ` [RESEND][patch " Borislav Petkov
2020-04-03 8:08 ` Alexandre Chartre
2020-03-20 18:00 ` [RESEND][patch V3 04/23] kprobes: Prevent probes in .noinstr.text section Thomas Gleixner
2020-03-20 18:00 ` [patch " Thomas Gleixner
2020-03-23 14:00 ` Masami Hiramatsu
2020-03-23 16:03 ` Thomas Gleixner
2020-03-24 5:49 ` Masami Hiramatsu
2020-03-24 9:47 ` Thomas Gleixner
2020-03-25 13:39 ` Masami Hiramatsu
2020-03-20 18:00 ` [RESEND][patch V3 05/23] tracing: Provide lockdep less trace_hardirqs_on/off() variants Thomas Gleixner
2020-03-20 18:00 ` [patch " Thomas Gleixner
2020-04-03 8:34 ` [RESEND][patch " Alexandre Chartre
2020-03-20 18:00 ` [RESEND][patch V3 06/23] bug: Annotate WARN/BUG/stackfail as noinstr safe Thomas Gleixner
2020-03-20 18:00 ` [patch " Thomas Gleixner
2020-04-02 21:01 ` [RESEND][patch " Josh Poimboeuf
2020-04-02 21:34 ` Peter Zijlstra
2020-04-02 21:43 ` Josh Poimboeuf
2020-04-02 21:49 ` Thomas Gleixner
2020-03-20 18:00 ` [RESEND][patch V3 07/23] lockdep: Prepare for noinstr sections Thomas Gleixner
2020-03-20 18:00 ` [patch " Thomas Gleixner
2020-03-20 18:00 ` [RESEND][patch V3 08/23] x86/entry: Mark enter_from_user_mode() noinstr Thomas Gleixner
2020-03-20 18:00 ` [patch " Thomas Gleixner
2020-03-20 18:00 ` [RESEND][patch V3 09/23] x86/entry/common: Protect against instrumentation Thomas Gleixner
2020-03-20 18:00 ` [patch " Thomas Gleixner
2020-03-20 18:00 ` [RESEND][patch V3 10/23] x86/entry: Move irq tracing on syscall entry to C-code Thomas Gleixner
2020-03-20 18:00 ` [patch " Thomas Gleixner
2020-03-20 18:00 ` [RESEND][patch V3 11/23] x86/entry: Move irq flags tracing to prepare_exit_to_usermode() Thomas Gleixner
2020-03-20 18:00 ` [patch " Thomas Gleixner
2020-03-20 18:00 ` [RESEND][patch V3 12/23] context_tracking: Ensure that the critical path cannot be instrumented Thomas Gleixner
2020-03-20 18:00 ` [patch " Thomas Gleixner
2020-03-20 18:00 ` [RESEND][patch V3 13/23] lib/smp_processor_id: Move it into noinstr section Thomas Gleixner
2020-03-20 18:00 ` [patch " Thomas Gleixner
2020-03-20 18:00 ` [RESEND][patch V3 14/23] x86/speculation/mds: Mark mds_user_clear_cpu_buffers() __always_inline Thomas Gleixner
2020-03-20 18:00 ` [patch " Thomas Gleixner
2020-03-20 18:00 ` [RESEND][patch V3 15/23] x86/entry/64: Check IF in __preempt_enable_notrace() thunk Thomas Gleixner
2020-03-20 18:00 ` [patch " Thomas Gleixner
2020-03-20 18:00 ` [RESEND][patch V3 16/23] x86/entry/64: Mark ___preempt_schedule_notrace() thunk noinstr Thomas Gleixner
2020-03-20 18:00 ` [patch " Thomas Gleixner
2020-03-20 18:00 ` [RESEND][patch V3 17/23] rcu/tree: Mark the idle relevant functions noinstr Thomas Gleixner
2020-03-20 18:00 ` [patch " Thomas Gleixner
2020-03-24 16:09 ` [RESEND][patch " Paul E. McKenney
2020-03-24 19:28 ` Thomas Gleixner
2020-03-24 19:58 ` Paul E. McKenney
2020-03-20 18:00 ` [RESEND][patch V3 18/23] x86/kvm: Move context tracking where it belongs Thomas Gleixner
2020-03-20 18:00 ` [patch " Thomas Gleixner
2020-03-20 18:00 ` [RESEND][patch V3 19/23] x86/kvm/vmx: Add hardirq tracing to guest enter/exit Thomas Gleixner
2020-03-20 18:00 ` [patch " Thomas Gleixner
2020-03-24 23:03 ` [RESEND][patch " Peter Zijlstra
2020-03-24 23:21 ` Thomas Gleixner
2020-03-20 18:00 ` [RESEND][patch V3 20/23] x86/kvm/svm: Handle hardirqs proper on " Thomas Gleixner
2020-03-20 18:00 ` [patch " Thomas Gleixner
2020-03-20 18:00 ` [RESEND][patch V3 21/23] context_tracking: Make guest_enter/exit_irqoff() .noinstr ready Thomas Gleixner
2020-03-20 18:00 ` [patch " Thomas Gleixner
2020-03-20 18:00 ` [RESEND][patch V3 22/23] x86/kvm/vmx: Move guest enter/exit into .noinstr.text Thomas Gleixner
2020-03-20 18:00 ` [patch " Thomas Gleixner
2020-03-20 18:00 ` [RESEND][patch V3 23/23] x86/kvm/svm: " Thomas Gleixner
2020-03-20 18:00 ` [patch " Thomas Gleixner
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=20200320180032.614150506@linutronix.de \
--to=tglx@linutronix.de \
--cc=alexandre.chartre@oracle.com \
--cc=ast@kernel.org \
--cc=brgerst@gmail.com \
--cc=frederic@kernel.org \
--cc=jgross@suse.com \
--cc=joel@joelfernandes.org \
--cc=jpoimboe@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=mhiramat@kernel.org \
--cc=paulmck@kernel.org \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=thomas.lendacky@amd.com \
--cc=x86@kernel.org \
/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.