aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/cpuidle/Kconfig2
-rw-r--r--drivers/cpuidle/cpuidle.c6
-rw-r--r--drivers/cpuidle/governors/ladder.c9
-rw-r--r--drivers/cpuidle/governors/menu.c23
-rw-r--r--include/linux/tick.h2
-rw-r--r--kernel/sched/idle.c6
-rw-r--r--kernel/time/tick-sched.c2
7 files changed, 28 insertions, 22 deletions
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index 8c7930b5a65f..7e48eb5bf0a7 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -19,11 +19,9 @@ config CPU_IDLE_MULTIPLE_DRIVERS
19 19
20config CPU_IDLE_GOV_LADDER 20config CPU_IDLE_GOV_LADDER
21 bool "Ladder governor (for periodic timer tick)" 21 bool "Ladder governor (for periodic timer tick)"
22 default y
23 22
24config CPU_IDLE_GOV_MENU 23config CPU_IDLE_GOV_MENU
25 bool "Menu governor (for tickless system)" 24 bool "Menu governor (for tickless system)"
26 default y
27 25
28config DT_IDLE_STATES 26config DT_IDLE_STATES
29 bool 27 bool
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 17a6dc0e2111..046423b0c5ca 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -79,9 +79,9 @@ static int find_deepest_state(struct cpuidle_driver *drv,
79 bool freeze) 79 bool freeze)
80{ 80{
81 unsigned int latency_req = 0; 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 struct cpuidle_state *s = &drv->states[i]; 85 struct cpuidle_state *s = &drv->states[i];
86 struct cpuidle_state_usage *su = &dev->states_usage[i]; 86 struct cpuidle_state_usage *su = &dev->states_usage[i];
87 87
@@ -243,7 +243,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
243 * @drv: the cpuidle driver 243 * @drv: the cpuidle driver
244 * @dev: the cpuidle device 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 */
248int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) 248int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
249{ 249{
diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c
index 401c0106ed34..63bd5a403e22 100644
--- a/drivers/cpuidle/governors/ladder.c
+++ b/drivers/cpuidle/governors/ladder.c
@@ -17,6 +17,7 @@
17#include <linux/pm_qos.h> 17#include <linux/pm_qos.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/jiffies.h> 19#include <linux/jiffies.h>
20#include <linux/tick.h>
20 21
21#include <asm/io.h> 22#include <asm/io.h>
22#include <asm/uaccess.h> 23#include <asm/uaccess.h>
@@ -184,6 +185,14 @@ static struct cpuidle_governor ladder_governor = {
184 */ 185 */
185static int __init init_ladder(void) 186static int __init init_ladder(void)
186{ 187{
188 /*
189 * When NO_HZ is disabled, or when booting with nohz=off, the ladder
190 * governor is better so give it a higher rating than the menu
191 * governor.
192 */
193 if (!tick_nohz_enabled)
194 ladder_governor.rating = 25;
195
187 return cpuidle_register_governor(&ladder_governor); 196 return cpuidle_register_governor(&ladder_governor);
188} 197}
189 198
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index 7b0971d97cc3..0742b3296673 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -294,8 +294,6 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
294 data->needs_update = 0; 294 data->needs_update = 0;
295 } 295 }
296 296
297 data->last_state_idx = CPUIDLE_DRIVER_STATE_START - 1;
298
299 /* Special case when user has set very strict latency requirement */ 297 /* Special case when user has set very strict latency requirement */
300 if (unlikely(latency_req == 0)) 298 if (unlikely(latency_req == 0))
301 return 0; 299 return 0;
@@ -326,20 +324,25 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
326 if (latency_req > interactivity_req) 324 if (latency_req > interactivity_req)
327 latency_req = interactivity_req; 325 latency_req = interactivity_req;
328 326
329 /* 327 if (CPUIDLE_DRIVER_STATE_START > 0) {
330 * We want to default to C1 (hlt), not to busy polling 328 data->last_state_idx = CPUIDLE_DRIVER_STATE_START - 1;
331 * unless the timer is happening really really soon. 329 /*
332 */ 330 * We want to default to C1 (hlt), not to busy polling
333 if (interactivity_req > 20 && 331 * unless the timer is happening really really soon.
334 !drv->states[CPUIDLE_DRIVER_STATE_START].disabled && 332 */
335 dev->states_usage[CPUIDLE_DRIVER_STATE_START].disable == 0) 333 if (interactivity_req > 20 &&
334 !drv->states[CPUIDLE_DRIVER_STATE_START].disabled &&
335 dev->states_usage[CPUIDLE_DRIVER_STATE_START].disable == 0)
336 data->last_state_idx = CPUIDLE_DRIVER_STATE_START;
337 } else {
336 data->last_state_idx = CPUIDLE_DRIVER_STATE_START; 338 data->last_state_idx = CPUIDLE_DRIVER_STATE_START;
339 }
337 340
338 /* 341 /*
339 * Find the idle state with the lowest power while satisfying 342 * Find the idle state with the lowest power while satisfying
340 * our constraints. 343 * our constraints.
341 */ 344 */
342 for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) { 345 for (i = data->last_state_idx + 1; i < drv->state_count; i++) {
343 struct cpuidle_state *s = &drv->states[i]; 346 struct cpuidle_state *s = &drv->states[i];
344 struct cpuidle_state_usage *su = &dev->states_usage[i]; 347 struct cpuidle_state_usage *su = &dev->states_usage[i];
345 348
diff --git a/include/linux/tick.h b/include/linux/tick.h
index e312219ff823..97fd4e543846 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -98,6 +98,7 @@ static inline void tick_broadcast_exit(void)
98} 98}
99 99
100#ifdef CONFIG_NO_HZ_COMMON 100#ifdef CONFIG_NO_HZ_COMMON
101extern int tick_nohz_enabled;
101extern int tick_nohz_tick_stopped(void); 102extern int tick_nohz_tick_stopped(void);
102extern void tick_nohz_idle_enter(void); 103extern void tick_nohz_idle_enter(void);
103extern void tick_nohz_idle_exit(void); 104extern void tick_nohz_idle_exit(void);
@@ -106,6 +107,7 @@ extern ktime_t tick_nohz_get_sleep_length(void);
106extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time); 107extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time);
107extern u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time); 108extern u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time);
108#else /* !CONFIG_NO_HZ_COMMON */ 109#else /* !CONFIG_NO_HZ_COMMON */
110#define tick_nohz_enabled (0)
109static inline int tick_nohz_tick_stopped(void) { return 0; } 111static inline int tick_nohz_tick_stopped(void) { return 0; }
110static inline void tick_nohz_idle_enter(void) { } 112static inline void tick_nohz_idle_enter(void) { }
111static inline void tick_nohz_idle_exit(void) { } 113static inline void tick_nohz_idle_exit(void) { }
diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c
index 4a2ef5a02fd3..34852ee70d54 100644
--- a/kernel/sched/idle.c
+++ b/kernel/sched/idle.c
@@ -97,12 +97,6 @@ void default_idle_call(void)
97static int call_cpuidle(struct cpuidle_driver *drv, struct cpuidle_device *dev, 97static int call_cpuidle(struct cpuidle_driver *drv, struct cpuidle_device *dev,
98 int next_state) 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 * The idle task must be scheduled, it is pointless to go to idle, just 101 * The idle task must be scheduled, it is pointless to go to idle, just
108 * update no idle residency and return. 102 * update no idle residency and return.
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 9cc20af58c76..9d7a053545f5 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -387,7 +387,7 @@ void __init tick_nohz_init(void)
387/* 387/*
388 * NO HZ enabled ? 388 * NO HZ enabled ?
389 */ 389 */
390static int tick_nohz_enabled __read_mostly = 1; 390int tick_nohz_enabled __read_mostly = 1;
391unsigned long tick_nohz_active __read_mostly; 391unsigned long tick_nohz_active __read_mostly;
392/* 392/*
393 * Enable / Disable tickless mode 393 * Enable / Disable tickless mode