rcu: Pull deferred rcuog wake up to rcu_eqs_enter() callers
authorFrederic Weisbecker <frederic@kernel.org>
Sun, 31 Jan 2021 23:05:44 +0000 (00:05 +0100)
committerIngo Molnar <mingo@kernel.org>
Wed, 17 Feb 2021 13:12:42 +0000 (14:12 +0100)
Deferred wakeup of rcuog kthreads upon RCU idle mode entry is going to
be handled differently whether initiated by idle, user or guest. Prepare
with pulling that control up to rcu_eqs_enter() callers.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: stable@vger.kernel.org
Link: https://lkml.kernel.org/r/20210131230548.32970-2-frederic@kernel.org
kernel/rcu/tree.c

index 40e5e3dd253e077cace9e8bd0edae8c71b9bf87d..63032e5620b969d7de8b08690e304af4d287085f 100644 (file)
@@ -644,7 +644,6 @@ static noinstr void rcu_eqs_enter(bool user)
        trace_rcu_dyntick(TPS("Start"), rdp->dynticks_nesting, 0, atomic_read(&rdp->dynticks));
        WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && !user && !is_idle_task(current));
        rdp = this_cpu_ptr(&rcu_data);
-       do_nocb_deferred_wakeup(rdp);
        rcu_prepare_for_idle();
        rcu_preempt_deferred_qs(current);
 
@@ -672,7 +671,10 @@ static noinstr void rcu_eqs_enter(bool user)
  */
 void rcu_idle_enter(void)
 {
+       struct rcu_data *rdp = this_cpu_ptr(&rcu_data);
+
        lockdep_assert_irqs_disabled();
+       do_nocb_deferred_wakeup(rdp);
        rcu_eqs_enter(false);
 }
 EXPORT_SYMBOL_GPL(rcu_idle_enter);
@@ -691,7 +693,14 @@ EXPORT_SYMBOL_GPL(rcu_idle_enter);
  */
 noinstr void rcu_user_enter(void)
 {
+       struct rcu_data *rdp = this_cpu_ptr(&rcu_data);
+
        lockdep_assert_irqs_disabled();
+
+       instrumentation_begin();
+       do_nocb_deferred_wakeup(rdp);
+       instrumentation_end();
+
        rcu_eqs_enter(true);
 }
 #endif /* CONFIG_NO_HZ_FULL */