Re: [RFC] rcu: Avoid unnecessary softirq when system is idle

From: Paul E. McKenney
Date: Sat Jan 19 2019 - 20:07:53 EST


On Sat, Jan 19, 2019 at 11:14:18AM -0500, Joel Fernandes (Google) wrote:
> When there are no callbacks pending on an idle system, I noticed that
> RCU softirq is continuously firing. During this the cpu_no_qs is set to
> false, and core_needs_qs is set to true indefinitely. This causes
> rcu_process_callbacks to be repeatedly called, even though the node
> corresponding to the CPU has that CPU's mask bit cleared and the system
> is idle. I believe the race is when such mask clearing is done during
> idle CPU scan of the quiescent state forcing stage in the kthread
> instead of the softirq. Since the rnp mask is cleared, but the flags on
> the CPU's rdp are not cleared, the CPU thinks it still needs to report
> to core RCU.
>
> Cure this by clearing the core_needs_qs flag when the CPU detects that
> its node is already updated which will avoid the unwanted softirq raises
> to the benefit of real-time systems.
>
> Test: Ran rcutorture for various tree RCU configs.
>
> Signed-off-by: Joel Fernandes (Google) <joel@xxxxxxxxxxxxxxxxx>

Good catch, queued, thank you!

Thanx, Paul

> ---
> kernel/rcu/tree.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> index 9180158756d2..96ad80c76b15 100644
> --- a/kernel/rcu/tree.c
> +++ b/kernel/rcu/tree.c
> @@ -2273,6 +2273,7 @@ rcu_report_qs_rdp(int cpu, struct rcu_data *rdp)
> }
> mask = rdp->grpmask;
> if ((rnp->qsmask & mask) == 0) {
> + rdp->core_needs_qs = false;
> raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
> } else {
> rdp->core_needs_qs = false;
> --
> 2.20.1.321.g9e740568ce-goog
>