Since the srcu read lock is still held during srcu_funnel_gp_start(), the seq snap should be the largest number for the slot srcu_have_cbs[idx]. Test info Running the following test without any failure tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 10h --configs 18*SRCU-P And cd res && find . -name console.log -exec grep WARNING {} \; prints nothing Signed-off-by: Pingfan Liu <kernelfans@xxxxxxxxx> Cc: Lai Jiangshan <jiangshanlai@xxxxxxxxx> Cc: "Paul E. McKenney" <paulmck@xxxxxxxxxx> Cc: Frederic Weisbecker <frederic@xxxxxxxxxx> Cc: Josh Triplett <josh@xxxxxxxxxxxxxxxx> Cc: Steven Rostedt <rostedt@xxxxxxxxxxx> Cc: Mathieu Desnoyers <mathieu.desnoyers@xxxxxxxxxxxx> To: rcu@xxxxxxxxxxxxxxx --- kernel/rcu/srcutree.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c index 7e450bb4ddcf..687f243dd2e2 100644 --- a/kernel/rcu/srcutree.c +++ b/kernel/rcu/srcutree.c @@ -905,14 +905,12 @@ static void srcu_funnel_gp_start(struct srcu_struct *ssp, struct srcu_data *sdp, for (snp = snp_leaf; snp != NULL; snp = snp->srcu_parent) { spin_lock_irqsave_rcu_node(snp, flags); snp_seq = snp->srcu_have_cbs[idx]; - if (!srcu_invl_snp_seq(snp_seq) && ULONG_CMP_GE(snp_seq, s)) { + /* s should be the biggest in the current slot. */ + WARN_ON_ONCE(ULONG_CMP_LT(s, snp_seq)); + if (!srcu_invl_snp_seq(snp_seq) && (snp_seq == s)) { if (snp == snp_leaf && snp_seq == s) snp->srcu_data_have_cbs[idx] |= sdp->grpmask; spin_unlock_irqrestore_rcu_node(snp, flags); - if (snp == snp_leaf && snp_seq != s) { - srcu_schedule_cbs_sdp(sdp, do_norm ? SRCU_INTERVAL : 0); - return; - } if (!do_norm) srcu_funnel_exp_start(ssp, snp, s); return; -- 2.31.1