rcu: Fix rcu_preempt_deferred_qs_irqrestore() strict QS reporting
authorPaul E. McKenney <paulmck@kernel.org>
Wed, 16 Feb 2022 17:54:56 +0000 (09:54 -0800)
committerPaul E. McKenney <paulmck@kernel.org>
Tue, 12 Apr 2022 00:28:48 +0000 (17:28 -0700)
commit90d2efe7bdbde5371b6122174af0718843f805c6
tree5cc5da7957665dffb8028c2daf41a3a377908c98
parentd22959aa93528c6cf4583560696856cf6bba6b72
rcu: Fix rcu_preempt_deferred_qs_irqrestore() strict QS reporting

Suppose we have a kernel built with both CONFIG_RCU_STRICT_GRACE_PERIOD=y
and CONFIG_PREEMPT=y.  Suppose further that an RCU reader from which RCU
core needs a quiescent state ends in rcu_preempt_deferred_qs_irqrestore().
This function will then invoke rcu_report_qs_rdp() in order to immediately
report that quiescent state.  Unfortunately, it will not have cleared
that reader's CPU's rcu_data structure's ->cpu_no_qs.b.norm field.
As a result, rcu_report_qs_rdp() will take an early exit because it
will believe that this CPU has not yet encountered a quiescent state,
and there will be no reporting of the current quiescent state.

This commit therefore causes rcu_preempt_deferred_qs_irqrestore() to
clear the ->cpu_no_qs.b.norm field before invoking rcu_report_qs_rdp().

Kudos to Boqun Feng and Neeraj Upadhyay for helping with analysis of
this issue!

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
kernel/rcu/tree_plugin.h