Skip to content

Commit 1bafbfb

Browse files
liupingfanpaulmckrcu
authored andcommitted
srcu: Remove needless rcu_seq_done() check while holding read lock
The srcu_gp_start_if_needed() function now read-holds the srcu_struct whose grace period is being started, which means that the corresponding SRCU grace period cannot end. This in turn means that the SRCU grace-period sequence number returned by rcu_seq_snap() cannot expire during this time. And that means that the calls to rcu_seq_done() in srcu_funnel_exp_start() and srcu_funnel_gp_start() can never return true. This commit therefore removes these rcu_seq_done() checks, but adds checks in kernels built with CONFIG_PROVE_RCU=y that splats if rcu_seq_done() does somehow return true. [ paulmck: Rearrange checks to handle kernels built with lockdep. ] Signed-off-by: Pingfan Liu <[email protected]> Cc: Lai Jiangshan <[email protected]> Cc: Frederic Weisbecker <[email protected]> Cc: Josh Triplett <[email protected]> Cc: Steven Rostedt <[email protected]> Cc: Mathieu Desnoyers <[email protected]> To: [email protected] Signed-off-by: Paul E. McKenney <[email protected]>
1 parent efa3c40 commit 1bafbfb

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

kernel/rcu/srcutree.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,7 @@ static void srcu_funnel_exp_start(struct srcu_struct *ssp, struct srcu_node *snp
915915
if (snp)
916916
for (; snp != NULL; snp = snp->srcu_parent) {
917917
sgsne = READ_ONCE(snp->srcu_gp_seq_needed_exp);
918-
if (rcu_seq_done(&ssp->srcu_gp_seq, s) ||
918+
if (WARN_ON_ONCE(rcu_seq_done(&ssp->srcu_gp_seq, s)) ||
919919
(!srcu_invl_snp_seq(sgsne) && ULONG_CMP_GE(sgsne, s)))
920920
return;
921921
spin_lock_irqsave_rcu_node(snp, flags);
@@ -942,6 +942,9 @@ static void srcu_funnel_exp_start(struct srcu_struct *ssp, struct srcu_node *snp
942942
*
943943
* Note that this function also does the work of srcu_funnel_exp_start(),
944944
* in some cases by directly invoking it.
945+
*
946+
* The srcu read lock should be hold around this function. And s is a seq snap
947+
* after holding that lock.
945948
*/
946949
static void srcu_funnel_gp_start(struct srcu_struct *ssp, struct srcu_data *sdp,
947950
unsigned long s, bool do_norm)
@@ -962,7 +965,7 @@ static void srcu_funnel_gp_start(struct srcu_struct *ssp, struct srcu_data *sdp,
962965
if (snp_leaf)
963966
/* Each pass through the loop does one level of the srcu_node tree. */
964967
for (snp = snp_leaf; snp != NULL; snp = snp->srcu_parent) {
965-
if (rcu_seq_done(&ssp->srcu_gp_seq, s) && snp != snp_leaf)
968+
if (WARN_ON_ONCE(rcu_seq_done(&ssp->srcu_gp_seq, s)) && snp != snp_leaf)
966969
return; /* GP already done and CBs recorded. */
967970
spin_lock_irqsave_rcu_node(snp, flags);
968971
snp_seq = snp->srcu_have_cbs[idx];
@@ -999,8 +1002,8 @@ static void srcu_funnel_gp_start(struct srcu_struct *ssp, struct srcu_data *sdp,
9991002
if (!do_norm && ULONG_CMP_LT(ssp->srcu_gp_seq_needed_exp, s))
10001003
WRITE_ONCE(ssp->srcu_gp_seq_needed_exp, s);
10011004

1002-
/* If grace period not already done and none in progress, start it. */
1003-
if (!rcu_seq_done(&ssp->srcu_gp_seq, s) &&
1005+
/* If grace period not already in progress, start it. */
1006+
if (!WARN_ON_ONCE(rcu_seq_done(&ssp->srcu_gp_seq, s)) &&
10041007
rcu_seq_state(ssp->srcu_gp_seq) == SRCU_STATE_IDLE) {
10051008
WARN_ON_ONCE(ULONG_CMP_GE(ssp->srcu_gp_seq, ssp->srcu_gp_seq_needed));
10061009
srcu_gp_start(ssp);

0 commit comments

Comments
 (0)