aboutsummaryrefslogtreecommitdiffstats
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.c50
1 files changed, 30 insertions, 20 deletions
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index 27fc733cb5b9..03d38c291de6 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -196,7 +196,7 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev);
196 * of points is below a threshold. If it is... then use the 196 * of points is below a threshold. If it is... then use the
197 * average of these 8 points as the estimated value. 197 * average of these 8 points as the estimated value.
198 */ 198 */
199static void get_typical_interval(struct menu_device *data) 199static unsigned int get_typical_interval(struct menu_device *data)
200{ 200{
201 int i, divisor; 201 int i, divisor;
202 unsigned int max, thresh, avg; 202 unsigned int max, thresh, avg;
@@ -253,9 +253,7 @@ again:
253 if (likely(variance <= U64_MAX/36)) { 253 if (likely(variance <= U64_MAX/36)) {
254 if ((((u64)avg*avg > variance*36) && (divisor * 4 >= INTERVALS * 3)) 254 if ((((u64)avg*avg > variance*36) && (divisor * 4 >= INTERVALS * 3))
255 || variance <= 400) { 255 || variance <= 400) {
256 if (data->next_timer_us > avg) 256 return avg;
257 data->predicted_us = avg;
258 return;
259 } 257 }
260 } 258 }
261 259
@@ -269,7 +267,7 @@ again:
269 * with sporadic activity with a bunch of short pauses. 267 * with sporadic activity with a bunch of short pauses.
270 */ 268 */
271 if ((divisor * 4) <= INTERVALS * 3) 269 if ((divisor * 4) <= INTERVALS * 3)
272 return; 270 return UINT_MAX;
273 271
274 thresh = max - 1; 272 thresh = max - 1;
275 goto again; 273 goto again;
@@ -286,6 +284,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
286 int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); 284 int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
287 int i; 285 int i;
288 unsigned int interactivity_req; 286 unsigned int interactivity_req;
287 unsigned int expected_interval;
289 unsigned long nr_iowaiters, cpu_load; 288 unsigned long nr_iowaiters, cpu_load;
290 289
291 if (data->needs_update) { 290 if (data->needs_update) {
@@ -312,32 +311,43 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
312 data->correction_factor[data->bucket], 311 data->correction_factor[data->bucket],
313 RESOLUTION * DECAY); 312 RESOLUTION * DECAY);
314 313
315 get_typical_interval(data); 314 expected_interval = get_typical_interval(data);
316 315 expected_interval = min(expected_interval, data->next_timer_us);
317 /*
318 * Performance multiplier defines a minimum predicted idle
319 * duration / latency ratio. Adjust the latency limit if
320 * necessary.
321 */
322 interactivity_req = data->predicted_us / performance_multiplier(nr_iowaiters, cpu_load);
323 if (latency_req > interactivity_req)
324 latency_req = interactivity_req;
325 316
326 if (CPUIDLE_DRIVER_STATE_START > 0) { 317 if (CPUIDLE_DRIVER_STATE_START > 0) {
327 data->last_state_idx = CPUIDLE_DRIVER_STATE_START - 1; 318 struct cpuidle_state *s = &drv->states[CPUIDLE_DRIVER_STATE_START];
319 unsigned int polling_threshold;
320
328 /* 321 /*
329 * We want to default to C1 (hlt), not to busy polling 322 * We want to default to C1 (hlt), not to busy polling
330 * unless the timer is happening really really soon. 323 * unless the timer is happening really really soon, or
324 * C1's exit latency exceeds the user configured limit.
331 */ 325 */
332 if (interactivity_req > 20 && 326 polling_threshold = max_t(unsigned int, 20, s->target_residency);
333 !drv->states[CPUIDLE_DRIVER_STATE_START].disabled && 327 if (data->next_timer_us > polling_threshold &&
334 dev->states_usage[CPUIDLE_DRIVER_STATE_START].disable == 0) 328 latency_req > s->exit_latency && !s->disabled &&
329 !dev->states_usage[CPUIDLE_DRIVER_STATE_START].disable)
335 data->last_state_idx = CPUIDLE_DRIVER_STATE_START; 330 data->last_state_idx = CPUIDLE_DRIVER_STATE_START;
331 else
332 data->last_state_idx = CPUIDLE_DRIVER_STATE_START - 1;
336 } else { 333 } else {
337 data->last_state_idx = CPUIDLE_DRIVER_STATE_START; 334 data->last_state_idx = CPUIDLE_DRIVER_STATE_START;
338 } 335 }
339 336
340 /* 337 /*
338 * Use the lowest expected idle interval to pick the idle state.
339 */
340 data->predicted_us = min(data->predicted_us, expected_interval);
341
342 /*
343 * Use the performance multiplier and the user-configurable
344 * latency_req to determine the maximum exit latency.
345 */
346 interactivity_req = data->predicted_us / performance_multiplier(nr_iowaiters, cpu_load);
347 if (latency_req > interactivity_req)
348 latency_req = interactivity_req;
349
350 /*
341 * Find the idle state with the lowest power while satisfying 351 * Find the idle state with the lowest power while satisfying
342 * our constraints. 352 * our constraints.
343 */ 353 */