From: "Paul E. McKenney" <paulmck@linux.ibm.com>
To: linux-kernel@vger.kernel.org
Cc: mingo@kernel.org, jiangshanlai@gmail.com, dipankar@in.ibm.com,
akpm@linux-foundation.org, mathieu.desnoyers@efficios.com,
josh@joshtriplett.org, tglx@linutronix.de, peterz@infradead.org,
rostedt@goodmis.org, dhowells@redhat.com, edumazet@google.com,
fweisbec@gmail.com, oleg@redhat.com, joel@joelfernandes.org,
"Paul E. McKenney" <paulmck@linux.ibm.com>
Subject: [PATCH tip/core/rcu 09/14] rcu: Speed up expedited GPs when interrupting RCU reader
Date: Sun, 11 Nov 2018 11:28:59 -0800 [thread overview]
Message-ID: <20181111192904.3199-9-paulmck@linux.ibm.com> (raw)
In-Reply-To: <20181111192839.GA32144@linux.ibm.com>
In PREEMPT kernels, an expedited grace period might send an IPI to a
CPU that is executing an RCU read-side critical section. In that case,
it would be nice if the rcu_read_unlock() directly interacted with the
RCU core code to immediately report the quiescent state. And this does
happen in the case where the reader has been preempted. But it would
also be a nice performance optimization if immediate reporting also
happened in the preemption-free case.
This commit therefore adds an ->exp_hint field to the task_struct structure's
->rcu_read_unlock_special field. The IPI handler sets this hint when
it has interrupted an RCU read-side critical section, and this causes
the outermost rcu_read_unlock() call to invoke rcu_read_unlock_special(),
which, if preemption is enabled, reports the quiescent state immediately.
If preemption is disabled, then the report is required to be deferred
until preemption (or bottom halves or interrupts or whatever) is re-enabled.
Because this is a hint, it does nothing for more complicated cases. For
example, if the IPI interrupts an RCU reader, but interrupts are disabled
across the rcu_read_unlock(), but another rcu_read_lock() is executed
before interrupts are re-enabled, the hint will already have been cleared.
If you do crazy things like this, reporting will be deferred until some
later RCU_SOFTIRQ handler, context switch, cond_resched(), or similar.
Reported-by: Joel Fernandes <joel@joelfernandes.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.ibm.com>
Acked-by: Joel Fernandes (Google) <joel@joelfernandes.org>
---
include/linux/sched.h | 4 +++-
kernel/rcu/tree_exp.h | 4 +++-
kernel/rcu/tree_plugin.h | 14 +++++++++++---
3 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index a51c13c2b1a0..e4c7b6241088 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -572,8 +572,10 @@ union rcu_special {
struct {
u8 blocked;
u8 need_qs;
+ u8 exp_hint; /* Hint for performance. */
+ u8 pad; /* No garbage from compiler! */
} b; /* Bits. */
- u16 s; /* Set of bits. */
+ u32 s; /* Set of bits. */
};
enum perf_event_task_context {
diff --git a/kernel/rcu/tree_exp.h b/kernel/rcu/tree_exp.h
index e669ccf3751b..928fe5893a57 100644
--- a/kernel/rcu/tree_exp.h
+++ b/kernel/rcu/tree_exp.h
@@ -692,8 +692,10 @@ static void sync_rcu_exp_handler(void *unused)
*/
if (t->rcu_read_lock_nesting > 0) {
raw_spin_lock_irqsave_rcu_node(rnp, flags);
- if (rnp->expmask & rdp->grpmask)
+ if (rnp->expmask & rdp->grpmask) {
rdp->deferred_qs = true;
+ WRITE_ONCE(t->rcu_read_unlock_special.b.exp_hint, true);
+ }
raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
}
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
index 05915e536336..618956cc7a55 100644
--- a/kernel/rcu/tree_plugin.h
+++ b/kernel/rcu/tree_plugin.h
@@ -642,13 +642,21 @@ static void rcu_read_unlock_special(struct task_struct *t)
local_irq_save(flags);
irqs_were_disabled = irqs_disabled_flags(flags);
- if ((preempt_bh_were_disabled || irqs_were_disabled) &&
- t->rcu_read_unlock_special.b.blocked) {
+ 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. */
- raise_softirq_irqoff(RCU_SOFTIRQ);
+ if (irqs_were_disabled) {
+ /* Enabling irqs does not reschedule, so... */
+ raise_softirq_irqoff(RCU_SOFTIRQ);
+ } else {
+ /* Enabling BH or preempt does reschedule, so... */
+ set_tsk_need_resched(current);
+ set_preempt_need_resched();
+ }
local_irq_restore(flags);
return;
}
+ WRITE_ONCE(t->rcu_read_unlock_special.b.exp_hint, false);
rcu_preempt_deferred_qs_irqrestore(t, flags);
}
--
2.17.1
next prev parent reply other threads:[~2018-11-11 19:29 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-11-11 19:28 [PATCH tip/core/rcu 0/14] Miscellaneous fixes for v4.21/v5.0 Paul E. McKenney
2018-11-11 19:28 ` [PATCH tip/core/rcu 01/14] rcu: Stop expedited grace periods from relying on stop-machine Paul E. McKenney
2018-11-11 19:28 ` [PATCH tip/core/rcu 02/14] MAINTAINERS: Update from @linux.vnet.ibm.com to @linux.ibm.com Paul E. McKenney
2018-11-11 19:28 ` [PATCH tip/core/rcu 03/14] rcu: Avoid double multiply by HZ Paul E. McKenney
2018-11-11 19:28 ` [PATCH tip/core/rcu 04/14] rcu: Parameterize rcu_check_gp_start_stall() Paul E. McKenney
2018-11-11 19:28 ` [PATCH tip/core/rcu 05/14] rcu: Add state name to show_rcu_gp_kthreads() output Paul E. McKenney
2018-11-11 19:28 ` [PATCH tip/core/rcu 06/14] rcu: Add jiffies-since-GP-activity to show_rcu_gp_kthreads() Paul E. McKenney
2018-11-11 19:28 ` [PATCH tip/core/rcu 07/14] rcu: Adjust the comment of function rcu_is_watching Paul E. McKenney
2018-11-11 19:28 ` [PATCH tip/core/rcu 08/14] rcu: Trace end of grace period before end of grace period Paul E. McKenney
2018-11-11 19:28 ` Paul E. McKenney [this message]
2018-11-11 19:29 ` [PATCH tip/core/rcu 10/14] rcu: Replace this_cpu_ptr() with __this_cpu_read() Paul E. McKenney
2018-11-11 19:29 ` [PATCH tip/core/rcu 11/14] rcu: Avoid signed integer overflow in rcu_preempt_deferred_qs() Paul E. McKenney
2018-11-11 19:29 ` [PATCH tip/core/rcu 12/14] MAINTAINERS: Add Joel Fernandes as RCU reviewer Paul E. McKenney
2018-11-11 19:29 ` [PATCH tip/core/rcu 13/14] checkpatch: Create table of obsolete APIs and apply to RCU Paul E. McKenney
2018-11-11 19:29 ` [PATCH tip/core/rcu 14/14] checkpatch.pl: Suggest lockdep instead of asserting !spin_is_locked() 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=20181111192904.3199-9-paulmck@linux.ibm.com \
--to=paulmck@linux.ibm.com \
--cc=akpm@linux-foundation.org \
--cc=dhowells@redhat.com \
--cc=dipankar@in.ibm.com \
--cc=edumazet@google.com \
--cc=fweisbec@gmail.com \
--cc=jiangshanlai@gmail.com \
--cc=joel@joelfernandes.org \
--cc=josh@joshtriplett.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=mingo@kernel.org \
--cc=oleg@redhat.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=tglx@linutronix.de \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox