rcu_preempt_deferred_qs_irqrestore() is always called when ->rcu_read_lock_nesting <= 0 and there is nothing to prevent it from reporting qs if needed which means ->rcu_read_unlock_special is better to be clearred after the function. But in some cases, it leaves exp_hint (for example, after rcu_note_context_switch()), which is harmess since it is just a hint, but it may also intruduce unneeded rcu_read_unlock_special() later. The new code write to exp_hint without WRITE_ONCE() since the writing is protected by irq. Signed-off-by: Lai Jiangshan <laijs@xxxxxxxxxxxxxxxxx> --- kernel/rcu/tree_plugin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h index 9fe8138ed3c3..bb3bcdb5c9b8 100644 --- a/kernel/rcu/tree_plugin.h +++ b/kernel/rcu/tree_plugin.h @@ -439,6 +439,7 @@ rcu_preempt_deferred_qs_irqrestore(struct task_struct *t, unsigned long flags) * t->rcu_read_unlock_special cannot change. */ special = t->rcu_read_unlock_special; + t->rcu_read_unlock_special.b.exp_hint = false; t->rcu_read_unlock_special.b.deferred_qs = false; if (special.b.need_qs) { rcu_qs(); @@ -626,7 +627,6 @@ static void rcu_read_unlock_special(struct task_struct *t) local_irq_restore(flags); return; } - WRITE_ONCE(t->rcu_read_unlock_special.b.exp_hint, false); rcu_preempt_deferred_qs_irqrestore(t, flags); } -- 2.20.1