Commit 96e95182 authored by tuukka.tikkanen@linaro.org's avatar tuukka.tikkanen@linaro.org Committed by Rafael J. Wysocki

cpuidle: Move perf multiplier calculation out of the selection loop

The menu governor performance multiplier defines a minimum predicted
idle duration to latency ratio. Instead of checking this separately
in every iteration of the state selection loop, adjust the overall
latency restriction for the whole loop if this restriction is tighter
than what is set by the QoS subsystem.

The original test
s->exit_latency * multiplier > data->predicted_us
becomes
s->exit_latency > data->predicted_us / multiplier
by dividing both sides of the comparison by "multiplier".

While division is likely to be several times slower than multiplication,
the minor performance hit allows making a generic sleep state selection
function based on (sleep duration, maximum latency) tuple.
Signed-off-by: default avatarTuukka Tikkanen <tuukka.tikkanen@linaro.org>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 61c66d6e
...@@ -288,7 +288,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) ...@@ -288,7 +288,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
struct menu_device *data = &__get_cpu_var(menu_devices); struct menu_device *data = &__get_cpu_var(menu_devices);
int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
int i; int i;
int multiplier; unsigned int interactivity_req;
struct timespec t; struct timespec t;
if (data->needs_update) { if (data->needs_update) {
...@@ -310,8 +310,6 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) ...@@ -310,8 +310,6 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
data->bucket = which_bucket(data->next_timer_us); data->bucket = which_bucket(data->next_timer_us);
multiplier = performance_multiplier();
/* /*
* if the correction factor is 0 (eg first time init or cpu hotplug * if the correction factor is 0 (eg first time init or cpu hotplug
* etc), we actually want to start out with a unity factor. * etc), we actually want to start out with a unity factor.
...@@ -330,6 +328,15 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) ...@@ -330,6 +328,15 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
get_typical_interval(data); get_typical_interval(data);
/*
* Performance multiplier defines a minimum predicted idle
* duration / latency ratio. Adjust the latency limit if
* necessary.
*/
interactivity_req = data->predicted_us / performance_multiplier();
if (latency_req > interactivity_req)
latency_req = interactivity_req;
/* /*
* We want to default to C1 (hlt), not to busy polling * We want to default to C1 (hlt), not to busy polling
* unless the timer is happening really really soon. * unless the timer is happening really really soon.
...@@ -353,8 +360,6 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) ...@@ -353,8 +360,6 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
continue; continue;
if (s->exit_latency > latency_req) if (s->exit_latency > latency_req)
continue; continue;
if (s->exit_latency * multiplier > data->predicted_us)
continue;
data->last_state_idx = i; data->last_state_idx = i;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment