Skip to content

Commit fcf0e25

Browse files
terminusfbq
authored andcommitted
rcu: handle unstable rdp in rcu_read_unlock_strict()
rcu_read_unlock_strict() can be called with preemption enabled which can make for an unstable rdp and a racy norm value. Fix this by dropping the preempt-count in __rcu_read_unlock() after the call to rcu_read_unlock_strict(), adjusting the preempt-count check appropriately. Suggested-by: Frederic Weisbecker <frederic@kernel.org> 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 2c00e11 commit fcf0e25

File tree

2 files changed

+11
-2
lines changed

2 files changed

+11
-2
lines changed

include/linux/rcupdate.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,9 @@ static inline void __rcu_read_lock(void)
9595

9696
static inline void __rcu_read_unlock(void)
9797
{
98-
preempt_enable();
9998
if (IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD))
10099
rcu_read_unlock_strict();
100+
preempt_enable();
101101
}
102102

103103
static inline int rcu_preempt_depth(void)

kernel/rcu/tree_plugin.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -833,8 +833,17 @@ void rcu_read_unlock_strict(void)
833833
{
834834
struct rcu_data *rdp;
835835

836-
if (irqs_disabled() || preempt_count() || !rcu_state.gp_kthread)
836+
if (irqs_disabled() || in_atomic_preempt_off() || !rcu_state.gp_kthread)
837837
return;
838+
839+
/*
840+
* rcu_report_qs_rdp() can only be invoked with a stable rdp and
841+
* from the local CPU.
842+
*
843+
* The in_atomic_preempt_off() check ensures that we come here holding
844+
* the last preempt_count (which will get dropped once we return to
845+
* __rcu_read_unlock().
846+
*/
838847
rdp = this_cpu_ptr(&rcu_data);
839848
rdp->cpu_no_qs.b.norm = false;
840849
rcu_report_qs_rdp(rdp);

0 commit comments

Comments
 (0)