On Fri, Sep 16, 2022 at 03:42:58PM +0200, Frederic Weisbecker wrote: > On Thu, Sep 15, 2022 at 01:58:25PM +0800, Pingfan Liu wrote: > > As Paul pointed out "The tick_dep_clear() is SMP-safe because it uses > > atomic operations, but the problem is that if there are multiple > > nohz_full CPUs going offline concurrently, the first CPU to invoke > > rcutree_dead_cpu() will turn the tick off. This might require an > > atomically manipulated counter to mediate the calls to > > rcutree_dead_cpu(). " > > > > This patch introduces a new member ->dying to rcu_node, which reflects > > the number of concurrent offlining cpu. TICK_DEP_BIT_RCU is set by > > the first entrance and cleared by the last. > > > > Note: now, tick_dep_set() is put under the rnp->lock, but since it takes > > no lock, no extra locking order is introduced. > > > > Suggested-by: "Paul E. McKenney" <paulmck@xxxxxxxxxx> > > Signed-off-by: Pingfan Liu <kernelfans@xxxxxxxxx> > > Cc: "Paul E. McKenney" <paulmck@xxxxxxxxxx> > > Cc: David Woodhouse <dwmw@xxxxxxxxxxxx> > > Cc: Frederic Weisbecker <frederic@xxxxxxxxxx> > > Cc: Neeraj Upadhyay <quic_neeraju@xxxxxxxxxxx> > > Cc: Josh Triplett <josh@xxxxxxxxxxxxxxxx> > > Cc: Steven Rostedt <rostedt@xxxxxxxxxxx> > > Cc: Mathieu Desnoyers <mathieu.desnoyers@xxxxxxxxxxxx> > > Cc: Lai Jiangshan <jiangshanlai@xxxxxxxxx> > > Cc: Joel Fernandes <joel@xxxxxxxxxxxxxxxxx> > > Cc: "Jason A. Donenfeld" <Jason@xxxxxxxxx> > > To: rcu@xxxxxxxxxxxxxxx > > --- > > kernel/rcu/tree.c | 19 ++++++++++++++----- > > kernel/rcu/tree.h | 1 + > > 2 files changed, 15 insertions(+), 5 deletions(-) > > > > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c > > index 8a829b64f5b2..f8bd0fc5fd2f 100644 > > --- a/kernel/rcu/tree.c > > +++ b/kernel/rcu/tree.c > > @@ -2164,13 +2164,19 @@ int rcutree_dead_cpu(unsigned int cpu) > > { > > struct rcu_data *rdp = per_cpu_ptr(&rcu_data, cpu); > > struct rcu_node *rnp = rdp->mynode; /* Outgoing CPU's rdp & rnp. */ > > + unsigned long flags; > > + u8 dying; > > > > if (!IS_ENABLED(CONFIG_HOTPLUG_CPU)) > > return 0; > > > > WRITE_ONCE(rcu_state.n_online_cpus, rcu_state.n_online_cpus - 1); > > - // Stop-machine done, so allow nohz_full to disable tick. > > - tick_dep_clear(TICK_DEP_BIT_RCU); > > + raw_spin_lock_irqsave_rcu_node(rnp, flags); > > + dying = --rnp->dying; > > + if (!dying) > > + // Stop-machine done, so allow nohz_full to disable tick. > > + tick_dep_clear(TICK_DEP_BIT_RCU); > > + raw_spin_lock_irqsave_rcu_node(rnp, flags); > > Note this is only locking the rdp's node, not the root node. > Therefore if CPU 0 and CPU 256 are going off at the same time and they > don't belong to the same node, the above won't protect against concurrent > TICK_DEP_BIT_RCU set/clear. > Nice, thanks for the careful thoughts. How about moving the counting place to the root node? > My suspicion is that we don't need this TICK_DEP_BIT_RCU tick dependency > anymore. I believe it was there because of issues that were fixed with: > > 53e87e3cdc15 (timers/nohz: Last resort update jiffies on nohz_full IRQ entry) > and: > > a1ff03cd6fb9 (tick: Detect and fix jiffies update stall) > > It's unfortunately just suspicion because the reason for that tick dependency > is unclear but I believe it should be safe to remove now. > I have gone through this tick dependency again, but got less. I think at least from the RCU's viewpoint, it is useless since multi_cpu_stop()->rcu_momentary_dyntick_idle() has eliminate the requirement for tick interrupt. Is there a way to have a convincing test so that these code can be removed? Or this code will be got along with? Thanks, Pingfan