]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
rcu/nohz: Turn off tick for offloaded CPUs
authorPaul E. McKenney <paulmck@linux.ibm.com>
Mon, 12 Aug 2019 17:28:08 +0000 (10:28 -0700)
committerPaul E. McKenney <paulmck@linux.ibm.com>
Tue, 13 Aug 2019 21:35:49 +0000 (14:35 -0700)
Historically, no-CBs CPUs allowed the scheduler-clock tick to be
unconditionally disabled on any transition to idle or nohz_full userspace
execution (see the rcu_needs_cpu() implementations).  Unfortunately,
the checks used by rcu_needs_cpu() are defeated now that no-CBs CPUs
use ->cblist, which might make users of battery-powered devices rather
unhappy.  This commit therefore adds explicit rcu_segcblist_is_offloaded()
checks to return to the historical energy-efficient semantics.

Signed-off-by: Paul E. McKenney <paulmck@linux.ibm.com>
kernel/rcu/tree_plugin.h

index c1dfbac8cd39fc67268f5be17f36b9f38bcbb73d..ae927710d670ffa2668858765f942d998b48bfef 100644 (file)
@@ -1226,10 +1226,10 @@ static void rcu_prepare_kthreads(int cpu)
 #if !defined(CONFIG_RCU_FAST_NO_HZ)
 
 /*
- * Check to see if any future RCU-related work will need to be done
- * by the current CPU, even if none need be done immediately, returning
- * 1 if so.  This function is part of the RCU implementation; it is -not-
- * an exported member of the RCU API.
+ * Check to see if any future non-offloaded RCU-related work will need
+ * to be done by the current CPU, even if none need be done immediately,
+ * returning 1 if so.  This function is part of the RCU implementation;
+ * it is -not- an exported member of the RCU API.
  *
  * Because we not have RCU_FAST_NO_HZ, just check whether or not this
  * CPU has RCU callbacks queued.
@@ -1237,7 +1237,8 @@ static void rcu_prepare_kthreads(int cpu)
 int rcu_needs_cpu(u64 basemono, u64 *nextevt)
 {
        *nextevt = KTIME_MAX;
-       return !rcu_segcblist_empty(&this_cpu_ptr(&rcu_data)->cblist);
+       return !rcu_segcblist_empty(&this_cpu_ptr(&rcu_data)->cblist) &&
+              !rcu_segcblist_is_offloaded(&this_cpu_ptr(&rcu_data)->cblist);
 }
 
 /*
@@ -1338,8 +1339,9 @@ int rcu_needs_cpu(u64 basemono, u64 *nextevt)
 
        lockdep_assert_irqs_disabled();
 
-       /* If no callbacks, RCU doesn't need the CPU. */
-       if (rcu_segcblist_empty(&rdp->cblist)) {
+       /* If no non-offloaded callbacks, RCU doesn't need the CPU. */
+       if (rcu_segcblist_empty(&rdp->cblist) ||
+           rcu_segcblist_is_offloaded(&this_cpu_ptr(&rcu_data)->cblist)) {
                *nextevt = KTIME_MAX;
                return 0;
        }