]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
rcu: Clear .exp_hint only when deferred quiescent state has been reported
authorLai Jiangshan <laijs@linux.alibaba.com>
Fri, 1 Nov 2019 11:06:22 +0000 (04:06 -0700)
committerPaul E. McKenney <paulmck@kernel.org>
Fri, 24 Jan 2020 18:27:33 +0000 (10:27 -0800)
Currently, the .exp_hint flag is cleared in rcu_read_unlock_special(),
which works, but which can also prevent subsequent rcu_read_unlock() calls
from helping expedite the quiescent state needed by an ongoing expedited
RCU grace period.  This commit therefore defers clearing of .exp_hint
from rcu_read_unlock_special() to rcu_preempt_deferred_qs_irqrestore(),
thus ensuring that intervening calls to rcu_read_unlock() have a chance
to help end the expedited grace period.

Signed-off-by: Lai Jiangshan <laijs@linux.alibaba.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
kernel/rcu/tree_plugin.h

index 8cdce111ea731e7d408be0a5a9809ae0218c5637..7487c7930a47f59039a2205bfec4a0513a3f3a2e 100644 (file)
@@ -444,6 +444,7 @@ rcu_preempt_deferred_qs_irqrestore(struct task_struct *t, unsigned long flags)
                local_irq_restore(flags);
                return;
        }
+       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();
@@ -610,7 +611,6 @@ static void rcu_read_unlock_special(struct task_struct *t)
                struct rcu_data *rdp = this_cpu_ptr(&rcu_data);
                struct rcu_node *rnp = rdp->mynode;
 
-               t->rcu_read_unlock_special.b.exp_hint = false;
                exp = (t->rcu_blocked_node && t->rcu_blocked_node->exp_tasks) ||
                      (rdp->grpmask & rnp->expmask) ||
                      tick_nohz_full_cpu(rdp->cpu);
@@ -640,7 +640,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);
 }