linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Paul E. McKenney" <paulmck@linux.vnet.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,
	"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Subject: [PATCH tip/core/rcu 19/20] rcu: Make expedited RCU CPU selection avoid unnecessary stores
Date: Mon, 26 Feb 2018 13:53:09 -0800	[thread overview]
Message-ID: <1519681990-31349-19-git-send-email-paulmck@linux.vnet.ibm.com> (raw)
In-Reply-To: <20180226215219.GA27379@linux.vnet.ibm.com>

This commit reworks the first loop in sync_rcu_exp_select_cpus()
to avoid doing unnecssary stores to other CPUs' rcu_data
structures.  This speeds up that first loop by roughly a factor of
two on an old x86 system.  In the case where the system is mostly
idle, this loop incurs a large fraction of the overhead of the
synchronize_rcu_expedited().  There is less benefit on busy systems
because the overhead of the smp_call_function_single() in the second
loop dominates in that case.

However, it is not unusual to do configuration chances involving
RCU grace periods (both expedited and normal) while the system is
mostly idle, so this optimization is worth doing.

While we are in the area, this commit also adds parentheses to arguments
used by the for_each_leaf_node_possible_cpu() macro.

Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
 kernel/rcu/rcu.h      | 16 +++++++++++++---
 kernel/rcu/tree_exp.h | 21 ++++++++++++++-------
 2 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h
index 507a0802c717..1c868bcfd705 100644
--- a/kernel/rcu/rcu.h
+++ b/kernel/rcu/rcu.h
@@ -301,9 +301,19 @@ static inline void rcu_init_levelspread(int *levelspread, const int *levelcnt)
  * Iterate over all possible CPUs in a leaf RCU node.
  */
 #define for_each_leaf_node_possible_cpu(rnp, cpu) \
-	for ((cpu) = cpumask_next(rnp->grplo - 1, cpu_possible_mask); \
-	     cpu <= rnp->grphi; \
-	     cpu = cpumask_next((cpu), cpu_possible_mask))
+	for ((cpu) = cpumask_next((rnp)->grplo - 1, cpu_possible_mask); \
+	     (cpu) <= rnp->grphi; \
+	     (cpu) = cpumask_next((cpu), cpu_possible_mask))
+
+/*
+ * Iterate over all CPUs in a leaf RCU node's specified mask.
+ */
+#define rcu_find_next_bit(rnp, cpu, mask) \
+	((rnp)->grplo + find_next_bit(&(mask), BITS_PER_LONG, (cpu)))
+#define for_each_leaf_node_cpu_mask(rnp, cpu, mask) \
+	for ((cpu) = rcu_find_next_bit((rnp), 0, (mask)); \
+	     (cpu) <= rnp->grphi; \
+	     (cpu) = rcu_find_next_bit((rnp), (cpu) + 1 - (rnp->grplo), (mask)))
 
 /*
  * Wrappers for the rcu_node::lock acquire and release.
diff --git a/kernel/rcu/tree_exp.h b/kernel/rcu/tree_exp.h
index fecb6b6ab452..6ad87642f44a 100644
--- a/kernel/rcu/tree_exp.h
+++ b/kernel/rcu/tree_exp.h
@@ -383,15 +383,22 @@ static void sync_rcu_exp_select_cpus(struct rcu_state *rsp,
 
 		/* Each pass checks a CPU for identity, offline, and idle. */
 		mask_ofl_test = 0;
-		for_each_leaf_node_possible_cpu(rnp, cpu) {
+		for_each_leaf_node_cpu_mask(rnp, cpu, rnp->expmask) {
+			unsigned long mask = leaf_node_cpu_bit(rnp, cpu);
 			struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
+			struct rcu_dynticks *rdtp = per_cpu_ptr(&rcu_dynticks, cpu);
+			int snap;
 
-			rdp->exp_dynticks_snap =
-				rcu_dynticks_snap(rdp->dynticks);
 			if (raw_smp_processor_id() == cpu ||
-			    rcu_dynticks_in_eqs(rdp->exp_dynticks_snap) ||
-			    !(rnp->qsmaskinitnext & rdp->grpmask))
-				mask_ofl_test |= rdp->grpmask;
+			    !(rnp->qsmaskinitnext & mask)) {
+				mask_ofl_test |= mask;
+			} else {
+				snap = rcu_dynticks_snap(rdtp);
+				if (rcu_dynticks_in_eqs(snap))
+					mask_ofl_test |= mask;
+				else
+					rdp->exp_dynticks_snap = snap;
+			}
 		}
 		mask_ofl_ipi = rnp->expmask & ~mask_ofl_test;
 
@@ -405,7 +412,7 @@ static void sync_rcu_exp_select_cpus(struct rcu_state *rsp,
 		raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
 
 		/* IPI the remaining CPUs for expedited quiescent state. */
-		for_each_leaf_node_possible_cpu(rnp, cpu) {
+		for_each_leaf_node_cpu_mask(rnp, cpu, rnp->expmask) {
 			unsigned long mask = leaf_node_cpu_bit(rnp, cpu);
 			struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
 
-- 
2.5.2

  parent reply	other threads:[~2018-02-26 21:54 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-26 21:52 [PATCH tip/core/rcu 0/20] Miscellaneous fixes Paul E. McKenney
2018-02-26 21:52 ` [PATCH tip/core/rcu 01/20] rcu: Remove unnecessary spinlock in rcu_boot_init_percpu_data() Paul E. McKenney
2018-02-26 21:52 ` [PATCH tip/core/rcu 02/20] sched/isolation: Eliminate NO_HZ_FULL_ALL Paul E. McKenney
2018-02-26 21:52 ` [PATCH tip/core/rcu 03/20] rcu: Fix CPU offload boot message when no CPUs are offloaded Paul E. McKenney
2018-02-26 21:52 ` [PATCH tip/core/rcu 04/20] doc: Fix typo in rcutorture documentation Paul E. McKenney
2018-02-26 21:52 ` [PATCH tip/core/rcu 05/20] doc: Fix typo in rcu_head comments Paul E. McKenney
2018-02-26 21:52 ` [PATCH tip/core/rcu 06/20] rcu: Call touch_nmi_watchdog() while printing stall warnings Paul E. McKenney
2018-02-26 21:52 ` [PATCH tip/core/rcu 07/20] rcu: Remove obsolete boost statistics for debugfs Paul E. McKenney
2018-02-26 21:52 ` [PATCH tip/core/rcu 08/20] rcu: Remove obsolete callback-invocation " Paul E. McKenney
2018-02-26 21:52 ` [PATCH tip/core/rcu 09/20] rcu: Remove obsolete __rcu_pending() " Paul E. McKenney
2018-02-26 21:53 ` [PATCH tip/core/rcu 10/20] rcu: Remove obsolete force-quiescent-state " Paul E. McKenney
2018-02-26 21:53 ` [PATCH tip/core/rcu 11/20] rcu: More clearly identify grace-period kthread stack dump Paul E. McKenney
2018-02-26 21:53 ` [PATCH tip/core/rcu 12/20] rcu: Consolidate rcu.h #ifdefs Paul E. McKenney
2018-02-26 21:53 ` [PATCH tip/core/rcu 13/20] rcu: Remove redundant nxttail index macro define Paul E. McKenney
2018-02-26 21:53 ` [PATCH tip/core/rcu 14/20] rcu: Use wrapper for lockdep asserts Paul E. McKenney
2018-02-26 21:53 ` [PATCH tip/core/rcu 15/20] rcu: Fix init_rcu_head() comment Paul E. McKenney
2018-02-26 21:53 ` [PATCH tip/core/rcu 16/20] rcu: Fix misprint in srcu_funnel_exp_start Paul E. McKenney
2018-02-26 21:53 ` [PATCH tip/core/rcu 17/20] rcu: Add more tracing of expedited grace periods Paul E. McKenney
2018-02-26 21:53 ` [PATCH tip/core/rcu 18/20] rcu: Trace expedited GP delays due to transitioning CPUs Paul E. McKenney
2018-02-26 21:53 ` Paul E. McKenney [this message]
2018-02-26 21:53 ` [PATCH tip/core/rcu 20/20] rcu: Create RCU-specific workqueues with rescuers 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=1519681990-31349-19-git-send-email-paulmck@linux.vnet.ibm.com \
    --to=paulmck@linux.vnet.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=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;
as well as URLs for NNTP newsgroup(s).