Skip to content

Commit 83b28cf

Browse files
terminusfbq
authored andcommitted
rcu: handle quiescent states for PREEMPT_RCU=n, PREEMPT_COUNT=y
With PREEMPT_RCU=n, cond_resched() provides urgently needed quiescent states for read-side critical sections via rcu_all_qs(). One reason why this was needed: lacking preempt-count, the tick handler has no way of knowing whether it is executing in a read-side critical section or not. With (PREEMPT_LAZY=y, PREEMPT_DYNAMIC=n), we get (PREEMPT_COUNT=y, PREEMPT_RCU=n). In this configuration cond_resched() is a stub and does not provide quiescent states via rcu_all_qs(). (PREEMPT_RCU=y provides this information via rcu_read_unlock() and its nesting counter.) So, use the availability of preempt_count() to report quiescent states in rcu_flavor_sched_clock_irq(). Suggested-by: Paul E. McKenney <paulmck@kernel.org> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Ankur Arora <ankur.a.arora@oracle.com> Reviewed-by: Frederic Weisbecker <frederic@kernel.org> Signed-off-by: Paul E. McKenney <paulmck@kernel.org> Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
1 parent fcf0e25 commit 83b28cf

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

kernel/rcu/tree_plugin.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -984,13 +984,16 @@ static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp)
984984
*/
985985
static void rcu_flavor_sched_clock_irq(int user)
986986
{
987-
if (user || rcu_is_cpu_rrupt_from_idle()) {
987+
if (user || rcu_is_cpu_rrupt_from_idle() ||
988+
(IS_ENABLED(CONFIG_PREEMPT_COUNT) &&
989+
(preempt_count() == HARDIRQ_OFFSET))) {
988990

989991
/*
990992
* Get here if this CPU took its interrupt from user
991-
* mode or from the idle loop, and if this is not a
992-
* nested interrupt. In this case, the CPU is in
993-
* a quiescent state, so note it.
993+
* mode, from the idle loop without this being a nested
994+
* interrupt, or while not holding the task preempt count
995+
* (with PREEMPT_COUNT=y). In this case, the CPU is in a
996+
* quiescent state, so note it.
994997
*
995998
* No memory barrier is required here because rcu_qs()
996999
* references only CPU-local variables that other CPUs

0 commit comments

Comments
 (0)