Skip to content

Commit 7a32337

Browse files
paulmckrcuurezki
authored andcommitted
rcu: Make preemptible rcu_exp_handler() check idempotency
Although the non-preemptible implementation of rcu_exp_handler() contains checks to enforce idempotency, the preemptible version does not. The reason for this omission is that in preemptible kernels, there is no reporting of quiescent states from CPU hotplug notifiers, and thus no need for idempotency. In theory, anyway. In practice, accidents happen. This commit therefore adds checks under WARN_ON_ONCE() to catch any such accidents. Signed-off-by: Paul E. McKenney <paulmck@kernel.org> Cc: Frederic Weisbecker <frederic@kernel.org> Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
1 parent 6ae4c30 commit 7a32337

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

kernel/rcu/tree_exp.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,19 @@ static void rcu_exp_handler(void *unused)
746746
struct task_struct *t = current;
747747

748748
/*
749-
* First, the common case of not being in an RCU read-side
749+
* First, is there no need for a quiescent state from this CPU,
750+
* or is this CPU already looking for a quiescent state for the
751+
* current grace period? If either is the case, just leave.
752+
* However, this should not happen due to the preemptible
753+
* sync_sched_exp_online_cleanup() implementation being a no-op,
754+
* so warn if this does happen.
755+
*/
756+
if (WARN_ON_ONCE(!(READ_ONCE(rnp->expmask) & rdp->grpmask) ||
757+
READ_ONCE(rdp->cpu_no_qs.b.exp)))
758+
return;
759+
760+
/*
761+
* Second, the common case of not being in an RCU read-side
750762
* critical section. If also enabled or idle, immediately
751763
* report the quiescent state, otherwise defer.
752764
*/
@@ -760,7 +772,7 @@ static void rcu_exp_handler(void *unused)
760772
}
761773

762774
/*
763-
* Second, the less-common case of being in an RCU read-side
775+
* Third, the less-common case of being in an RCU read-side
764776
* critical section. In this case we can count on a future
765777
* rcu_read_unlock(). However, this rcu_read_unlock() might
766778
* execute on some other CPU, but in that case there will be
@@ -781,7 +793,7 @@ static void rcu_exp_handler(void *unused)
781793
return;
782794
}
783795

784-
// Finally, negative nesting depth should not happen.
796+
// Fourth and finally, negative nesting depth should not happen.
785797
WARN_ON_ONCE(1);
786798
}
787799

0 commit comments

Comments
 (0)