]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
sched: idle: Make skipping governor callbacks more consistent
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Sat, 7 Mar 2026 16:12:05 +0000 (17:12 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 10 Mar 2026 15:03:02 +0000 (16:03 +0100)
If the cpuidle governor .select() callback is skipped because there
is only one idle state in the cpuidle driver, the .reflect() callback
should be skipped as well, at least for consistency (if not for
correctness), so do it.

Fixes: e5c9ffc6ae1b ("cpuidle: Skip governor when only one idle state is available")
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Christian Loehle <christian.loehle@arm.com>
Reviewed-by: Aboorva Devarajan <aboorvad@linux.ibm.com>
Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
Link: https://patch.msgid.link/12857700.O9o76ZdvQC@rafael.j.wysocki
drivers/cpuidle/cpuidle.c
kernel/sched/idle.c

index 65fbb8e807b9771a152ef777646a28d35555905d..c7876e9e024f9076663063ad21cfc69343fdbbe7 100644 (file)
@@ -359,16 +359,6 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev,
 int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
                   bool *stop_tick)
 {
-       /*
-        * If there is only a single idle state (or none), there is nothing
-        * meaningful for the governor to choose. Skip the governor and
-        * always use state 0 with the tick running.
-        */
-       if (drv->state_count <= 1) {
-               *stop_tick = false;
-               return 0;
-       }
-
        return cpuidle_curr_governor->select(drv, dev, stop_tick);
 }
 
index 3681b6ad9276f2b14b232e5d581781a9cd371297..b9544916512273553f1938611226bbaddac15803 100644 (file)
@@ -221,7 +221,7 @@ static void cpuidle_idle_call(void)
 
                next_state = cpuidle_find_deepest_state(drv, dev, max_latency_ns);
                call_cpuidle(drv, dev, next_state);
-       } else {
+       } else if (drv->state_count > 1) {
                bool stop_tick = true;
 
                /*
@@ -239,6 +239,15 @@ static void cpuidle_idle_call(void)
                 * Give the governor an opportunity to reflect on the outcome
                 */
                cpuidle_reflect(dev, entered_state);
+       } else {
+               tick_nohz_idle_retain_tick();
+
+               /*
+                * If there is only a single idle state (or none), there is
+                * nothing meaningful for the governor to choose.  Skip the
+                * governor and always use state 0.
+                */
+               call_cpuidle(drv, dev, 0);
        }
 
 exit_idle: