summaryrefslogtreecommitdiff
path: root/kernel/rcu/tree.c
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2018-05-15 11:53:41 -0700
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2018-07-12 15:38:54 -0700
commit2e3e5e55010105f9d4351f68e15dbc43402a7794 (patch)
treeaba67c3616182d92c7b2a5867331250234befcce /kernel/rcu/tree.c
parent5ca0905f6787e930bc2a626cf1d8f69fab52acef (diff)
rcu: Make rcu_start_this_gp() check for grace period already started
In the old days of ->gpnum and ->completed, the code requesting a new grace period checked to see if that grace period had already started, bailing early if so. The new-age ->gp_seq approach instead checks whether the grace period has already finished. A compensating change pushed the requested grace period down to the bottom of the tree, thus reducing lock contention and even eliminating it in some cases. But why not further reduce contention, especially on large systems, by doing both, especially given that the cost of doing both is extremely small? This commit therefore adds a new rcu_seq_started() function that checks whether a specified grace period has already started. It then uses this new function in place of rcu_seq_done() in the rcu_start_this_gp() function's funnel locking code. Reported-by: Joel Fernandes <joel@joelfernandes.org> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'kernel/rcu/tree.c')
-rw-r--r--kernel/rcu/tree.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 973250503d98..cbf2bcde5e60 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -1583,7 +1583,7 @@ static bool rcu_start_this_gp(struct rcu_node *rnp, struct rcu_data *rdp,
if (rnp_root != rnp)
raw_spin_lock_rcu_node(rnp_root);
if (ULONG_CMP_GE(rnp_root->gp_seq_needed, c) ||
- rcu_seq_done(&rnp_root->gp_seq, c) ||
+ rcu_seq_started(&rnp_root->gp_seq, c) ||
(rnp != rnp_root &&
rcu_seq_state(rcu_seq_current(&rnp_root->gp_seq)))) {
trace_rcu_this_gp(rnp_root, rdp, c, TPS("Prestarted"));