From: Paul E. McKenney Date: Wed, 11 Apr 2018 23:41:20 +0000 (-0700) Subject: rcu: Make rcu_gp_kthread() check for early-boot activity X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=5fe0a56298e674358ff2740a6288bf21509d895d;p=openwrt%2Fstaging%2Fblogic.git rcu: Make rcu_gp_kthread() check for early-boot activity The rcu_gp_kthread() function immediately sleeps waiting to be notified of the need for a new grace period, which currently works because there are a number of code sequences that will provide the needed wakeup later. However, some of these code sequences need to acquire the root rcu_node structure's ->lock, and contention on that lock has started manifesting. This commit therefore makes rcu_gp_kthread() check for early-boot activity when it starts up, omitting the initial sleep in that case. Reported-by: Nicholas Piggin Signed-off-by: Paul E. McKenney Tested-by: Nicholas Piggin --- diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 79fb99951a0c..497f139056c7 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -2192,6 +2192,12 @@ static int __noreturn rcu_gp_kthread(void *arg) struct rcu_state *rsp = arg; struct rcu_node *rnp = rcu_get_root(rsp); + /* Check for early-boot work. */ + raw_spin_lock_irq_rcu_node(rnp); + if (need_any_future_gp(rnp)) + WRITE_ONCE(rsp->gp_flags, RCU_GP_FLAG_INIT); + raw_spin_unlock_irq_rcu_node(rnp); + rcu_bind_gp_kthread(); for (;;) {