aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortuukka.tikkanen@linaro.org <tuukka.tikkanen@linaro.org>2014-02-24 01:29:35 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-03-05 19:45:59 -0500
commit96e95182e95fd4e0069ff4d6ee1888fe9031d154 (patch)
treedfb20bf37e38982972b7fde9a0e7e8729aa3db22
parent61c66d6efa23759f1061d80ced668977fd28337d (diff)
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: Tuukka Tikkanen <tuukka.tikkanen@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/cpuidle/governors/menu.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index b347c101c1f7..71b523293354 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -288,7 +288,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
288 struct menu_device *data = &__get_cpu_var(menu_devices); 288 struct menu_device *data = &__get_cpu_var(menu_devices);
289 int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); 289 int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
290 int i; 290 int i;
291 int multiplier; 291 unsigned int interactivity_req;
292 struct timespec t; 292 struct timespec t;
293 293
294 if (data->needs_update) { 294 if (data->needs_update) {
@@ -310,8 +310,6 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
310 310
311 data->bucket = which_bucket(data->next_timer_us); 311 data->bucket = which_bucket(data->next_timer_us);
312 312
313 multiplier = performance_multiplier();
314
315 /* 313 /*
316 * if the correction factor is 0 (eg first time init or cpu hotplug 314 * if the correction factor is 0 (eg first time init or cpu hotplug
317 * etc), we actually want to start out with a unity factor. 315 * etc), we actually want to start out with a unity factor.
@@ -331,6 +329,15 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
331 get_typical_interval(data); 329 get_typical_interval(data);
332 330
333 /* 331 /*
332 * Performance multiplier defines a minimum predicted idle
333 * duration / latency ratio. Adjust the latency limit if
334 * necessary.
335 */
336 interactivity_req = data->predicted_us / performance_multiplier();
337 if (latency_req > interactivity_req)
338 latency_req = interactivity_req;
339
340 /*
334 * We want to default to C1 (hlt), not to busy polling 341 * We want to default to C1 (hlt), not to busy polling
335 * unless the timer is happening really really soon. 342 * unless the timer is happening really really soon.
336 */ 343 */
@@ -353,8 +360,6 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
353 continue; 360 continue;
354 if (s->exit_latency > latency_req) 361 if (s->exit_latency > latency_req)
355 continue; 362 continue;
356 if (s->exit_latency * multiplier > data->predicted_us)
357 continue;
358 363
359 data->last_state_idx = i; 364 data->last_state_idx = i;
360 } 365 }