summaryrefslogtreecommitdiffstats
path: root/drivers/cpuidle/governors/menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpuidle/governors/menu.c')
-rw-r--r--drivers/cpuidle/governors/menu.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index 52ff8aa63f8..c2408bbe9c2 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -143,7 +143,7 @@ static inline int which_bucket(unsigned int duration)
* This allows us to calculate
* E(duration)|iowait
*/
- if (nr_iowait_cpu())
+ if (nr_iowait_cpu(smp_processor_id()))
bucket = BUCKETS/2;
if (duration < 10)
@@ -175,7 +175,7 @@ static inline int performance_multiplier(void)
mult += 2 * get_loadavg();
/* for IO wait tasks (per cpu!) we add 5x each */
- mult += 10 * nr_iowait_cpu();
+ mult += 10 * nr_iowait_cpu(smp_processor_id());
return mult;
}
@@ -234,6 +234,7 @@ static int menu_select(struct cpuidle_device *dev)
{
struct menu_device *data = &__get_cpu_var(menu_devices);
int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
+ unsigned int power_usage = -1;
int i;
int multiplier;
@@ -278,19 +279,27 @@ static int menu_select(struct cpuidle_device *dev)
if (data->expected_us > 5)
data->last_state_idx = CPUIDLE_DRIVER_STATE_START;
-
- /* find the deepest idle state that satisfies our constraints */
+ /*
+ * Find the idle state with the lowest power while satisfying
+ * our constraints.
+ */
for (i = CPUIDLE_DRIVER_STATE_START; i < dev->state_count; i++) {
struct cpuidle_state *s = &dev->states[i];
+ if (s->flags & CPUIDLE_FLAG_IGNORE)
+ continue;
if (s->target_residency > data->predicted_us)
- break;
+ continue;
if (s->exit_latency > latency_req)
- break;
+ continue;
if (s->exit_latency * multiplier > data->predicted_us)
- break;
- data->exit_us = s->exit_latency;
- data->last_state_idx = i;
+ continue;
+
+ if (s->power_usage < power_usage) {
+ power_usage = s->power_usage;
+ data->last_state_idx = i;
+ data->exit_us = s->exit_latency;
+ }
}
return data->last_state_idx;