]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 4 Mar 2021 09:26:46 +0000 (10:26 +0100)
commit 54b7429efffc99e845ba9381bee3244f012a06c2 upstream.

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
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
kernel/rcu/tree.c

index 1b1d2b09efa9b83c5ccf866b03491112c08ef6b7..3dc02ee17957eff6f7473e43ce5d5e90a243099f 100644 (file)
@@ -579,7 +579,6 @@ static 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);
        WRITE_ONCE(rdp->dynticks_nesting, 0); /* Avoid irq-access tearing. */
@@ -600,7 +599,10 @@ static 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);
 }
 
@@ -618,7 +620,14 @@ void rcu_idle_enter(void)
  */
 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 */