Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'pm-cpuidle'

* pm-cpuidle:
cpuidle: menu: Avoid pointless checks in menu_select()
sched / idle: Drop default_idle_call() fallback from call_cpuidle()
cpuidle: Don't enable all governors by default
cpuidle: Default to ladder governor on ticking systems
time: nohz: Expose tick_nohz_enabled
cpuidle: menu: Fix menu_select() for CPUIDLE_DRIVER_STATE_START == 0

+28 -22
-2
drivers/cpuidle/Kconfig
··· 19 19 20 20 config CPU_IDLE_GOV_LADDER 21 21 bool "Ladder governor (for periodic timer tick)" 22 - default y 23 22 24 23 config CPU_IDLE_GOV_MENU 25 24 bool "Menu governor (for tickless system)" 26 - default y 27 25 28 26 config DT_IDLE_STATES 29 27 bool
+3 -3
drivers/cpuidle/cpuidle.c
··· 79 79 bool freeze) 80 80 { 81 81 unsigned int latency_req = 0; 82 - int i, ret = -ENXIO; 82 + int i, ret = 0; 83 83 84 - for (i = 0; i < drv->state_count; i++) { 84 + for (i = 1; i < drv->state_count; i++) { 85 85 struct cpuidle_state *s = &drv->states[i]; 86 86 struct cpuidle_state_usage *su = &dev->states_usage[i]; 87 87 ··· 243 243 * @drv: the cpuidle driver 244 244 * @dev: the cpuidle device 245 245 * 246 - * Returns the index of the idle state. 246 + * Returns the index of the idle state. The return value must not be negative. 247 247 */ 248 248 int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) 249 249 {
+9
drivers/cpuidle/governors/ladder.c
··· 17 17 #include <linux/pm_qos.h> 18 18 #include <linux/module.h> 19 19 #include <linux/jiffies.h> 20 + #include <linux/tick.h> 20 21 21 22 #include <asm/io.h> 22 23 #include <asm/uaccess.h> ··· 185 184 */ 186 185 static int __init init_ladder(void) 187 186 { 187 + /* 188 + * When NO_HZ is disabled, or when booting with nohz=off, the ladder 189 + * governor is better so give it a higher rating than the menu 190 + * governor. 191 + */ 192 + if (!tick_nohz_enabled) 193 + ladder_governor.rating = 25; 194 + 188 195 return cpuidle_register_governor(&ladder_governor); 189 196 } 190 197
+13 -10
drivers/cpuidle/governors/menu.c
··· 294 294 data->needs_update = 0; 295 295 } 296 296 297 - data->last_state_idx = CPUIDLE_DRIVER_STATE_START - 1; 298 - 299 297 /* Special case when user has set very strict latency requirement */ 300 298 if (unlikely(latency_req == 0)) 301 299 return 0; ··· 324 326 if (latency_req > interactivity_req) 325 327 latency_req = interactivity_req; 326 328 327 - /* 328 - * We want to default to C1 (hlt), not to busy polling 329 - * unless the timer is happening really really soon. 330 - */ 331 - if (interactivity_req > 20 && 332 - !drv->states[CPUIDLE_DRIVER_STATE_START].disabled && 333 - dev->states_usage[CPUIDLE_DRIVER_STATE_START].disable == 0) 329 + if (CPUIDLE_DRIVER_STATE_START > 0) { 330 + data->last_state_idx = CPUIDLE_DRIVER_STATE_START - 1; 331 + /* 332 + * We want to default to C1 (hlt), not to busy polling 333 + * unless the timer is happening really really soon. 334 + */ 335 + if (interactivity_req > 20 && 336 + !drv->states[CPUIDLE_DRIVER_STATE_START].disabled && 337 + dev->states_usage[CPUIDLE_DRIVER_STATE_START].disable == 0) 338 + data->last_state_idx = CPUIDLE_DRIVER_STATE_START; 339 + } else { 334 340 data->last_state_idx = CPUIDLE_DRIVER_STATE_START; 341 + } 335 342 336 343 /* 337 344 * Find the idle state with the lowest power while satisfying 338 345 * our constraints. 339 346 */ 340 - for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) { 347 + for (i = data->last_state_idx + 1; i < drv->state_count; i++) { 341 348 struct cpuidle_state *s = &drv->states[i]; 342 349 struct cpuidle_state_usage *su = &dev->states_usage[i]; 343 350
+2
include/linux/tick.h
··· 98 98 } 99 99 100 100 #ifdef CONFIG_NO_HZ_COMMON 101 + extern int tick_nohz_enabled; 101 102 extern int tick_nohz_tick_stopped(void); 102 103 extern void tick_nohz_idle_enter(void); 103 104 extern void tick_nohz_idle_exit(void); ··· 107 106 extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time); 108 107 extern u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time); 109 108 #else /* !CONFIG_NO_HZ_COMMON */ 109 + #define tick_nohz_enabled (0) 110 110 static inline int tick_nohz_tick_stopped(void) { return 0; } 111 111 static inline void tick_nohz_idle_enter(void) { } 112 112 static inline void tick_nohz_idle_exit(void) { }
-6
kernel/sched/idle.c
··· 97 97 static int call_cpuidle(struct cpuidle_driver *drv, struct cpuidle_device *dev, 98 98 int next_state) 99 99 { 100 - /* Fall back to the default arch idle method on errors. */ 101 - if (next_state < 0) { 102 - default_idle_call(); 103 - return next_state; 104 - } 105 - 106 100 /* 107 101 * The idle task must be scheduled, it is pointless to go to idle, just 108 102 * update no idle residency and return.
+1 -1
kernel/time/tick-sched.c
··· 387 387 /* 388 388 * NO HZ enabled ? 389 389 */ 390 - static int tick_nohz_enabled __read_mostly = 1; 390 + int tick_nohz_enabled __read_mostly = 1; 391 391 unsigned long tick_nohz_active __read_mostly; 392 392 /* 393 393 * Enable / Disable tickless mode