Lines Matching +full:duration +full:- +full:us
2 * menu.c - the menu idle governor
4 * Copyright (C) 2006-2007 Adam Belay <abelay@novell.com>
26 * If (MAX_INTERESTING-1) * RESOLUTION > UINT_MAX, the result of
52 * -----------------------
55 * provides us this duration in the "target_residency" field. So all that we
63 * duration always was 50% of the next timer tick, the correction factor will
69 * duration; if we expect 500 milliseconds of idle time the likelihood of
77 * indexed based on the magnitude of the expected duration as well as the
80 * Repeatable-interval-detector
81 * ----------------------------
86 * For this, we use a different predictor: We track the duration of the last 8
91 * ---------------------------
100 * This rule-of-thumb is implemented using a performance-multiplier:
102 * the predicted duration, the C state is not considered a candidate
136 #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
143 static inline int which_bucket(unsigned int duration, unsigned long nr_iowaiters) in which_bucket() argument
150 * This allows us to calculate in which_bucket()
151 * E(duration)|iowait in which_bucket()
156 if (duration < 10) in which_bucket()
158 if (duration < 100) in which_bucket()
160 if (duration < 1000) in which_bucket()
162 if (duration < 10000) in which_bucket()
164 if (duration < 100000) in which_bucket()
215 unsigned int value = data->intervals[i]; in get_typical_interval()
231 unsigned int value = data->intervals[i]; in get_typical_interval()
233 int64_t diff = (int64_t)value - avg; in get_typical_interval()
244 * small (stddev <= 20 us, variance <= 400 us^2) or standard in get_typical_interval()
252 * Use this result only if there is no timer to wake us up sooner. in get_typical_interval()
273 thresh = max - 1; in get_typical_interval()
278 * menu_select - selects the next idle state to enter
287 int latency_req = cpuidle_governor_latency_req(dev->cpu); in menu_select()
296 if (data->needs_update) { in menu_select()
298 data->needs_update = 0; in menu_select()
308 data->next_timer_us = ktime_to_us(tick_nohz_get_sleep_length(&delta_next)); in menu_select()
311 data->bucket = which_bucket(data->next_timer_us, nr_iowaiters); in menu_select()
318 data->predicted_us = DIV_ROUND_CLOSEST_ULL((uint64_t)data->next_timer_us * in menu_select()
319 data->correction_factor[data->bucket], in menu_select()
323 expected_interval = min(expected_interval, data->next_timer_us); in menu_select()
326 if (drv->states[0].flags & CPUIDLE_FLAG_POLLING) { in menu_select()
327 struct cpuidle_state *s = &drv->states[1]; in menu_select()
334 polling_threshold = max_t(unsigned int, 20, s->target_residency); in menu_select()
335 if (data->next_timer_us > polling_threshold && in menu_select()
336 latency_req > s->exit_latency && !s->disabled && in menu_select()
337 !dev->states_usage[1].disable) in menu_select()
344 data->predicted_us = min(data->predicted_us, expected_interval); in menu_select()
349 * idle duration misprediction is much higher, because the CPU in menu_select()
355 if (data->predicted_us < TICK_USEC) in menu_select()
356 data->predicted_us = ktime_to_us(delta_next); in menu_select()
359 * Use the performance multiplier and the user-configurable in menu_select()
362 interactivity_req = data->predicted_us / performance_multiplier(nr_iowaiters, cpu_load); in menu_select()
367 expected_interval = data->predicted_us; in menu_select()
372 idx = -1; in menu_select()
373 for (i = first_idx; i < drv->state_count; i++) { in menu_select()
374 struct cpuidle_state *s = &drv->states[i]; in menu_select()
375 struct cpuidle_state_usage *su = &dev->states_usage[i]; in menu_select()
377 if (s->disabled || su->disable) in menu_select()
379 if (idx == -1) in menu_select()
381 if (s->target_residency > data->predicted_us) { in menu_select()
382 if (data->predicted_us < TICK_USEC) in menu_select()
392 expected_interval = drv->states[idx].target_residency; in menu_select()
402 if (drv->states[idx].target_residency < TICK_USEC && in menu_select()
403 s->target_residency <= ktime_to_us(delta_next)) in menu_select()
408 if (s->exit_latency > latency_req) { in menu_select()
412 * expected idle duration so that the tick is retained in menu_select()
415 expected_interval = drv->states[idx].target_residency; in menu_select()
421 if (idx == -1) in menu_select()
426 * expected idle duration is shorter than the tick period length. in menu_select()
428 if (((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) || in menu_select()
434 if (idx > 0 && drv->states[idx].target_residency > delta_next_us) { in menu_select()
441 for (i = idx - 1; i >= 0; i--) { in menu_select()
442 if (drv->states[i].disabled || in menu_select()
443 dev->states_usage[i].disable) in menu_select()
447 if (drv->states[i].target_residency <= delta_next_us) in menu_select()
454 data->last_state_idx = idx; in menu_select()
456 return data->last_state_idx; in menu_select()
460 * menu_reflect - records that data structures need update
471 data->last_state_idx = index; in menu_reflect()
472 data->needs_update = 1; in menu_reflect()
473 data->tick_wakeup = tick_nohz_idle_got_tick(); in menu_reflect()
477 * menu_update - attempts to guess what happened after entry
484 int last_idx = data->last_state_idx; in menu_update()
485 struct cpuidle_state *target = &drv->states[last_idx]; in menu_update()
504 if (data->tick_wakeup && data->next_timer_us > TICK_USEC) { in menu_update()
508 * duration predictor had a differing opinion. Since the CPU in menu_update()
512 * duration predictor do a better job next time. in menu_update()
515 } else if ((drv->states[last_idx].flags & CPUIDLE_FLAG_POLLING) && in menu_update()
516 dev->poll_time_limit) { in menu_update()
519 * the idle duration prediction leading to the selection of that in menu_update()
524 measured_us = data->next_timer_us; in menu_update()
530 if (measured_us > 2 * target->exit_latency) in menu_update()
531 measured_us -= target->exit_latency; in menu_update()
537 if (measured_us > data->next_timer_us) in menu_update()
538 measured_us = data->next_timer_us; in menu_update()
541 new_factor = data->correction_factor[data->bucket]; in menu_update()
542 new_factor -= new_factor / DECAY; in menu_update()
544 if (data->next_timer_us > 0 && measured_us < MAX_INTERESTING) in menu_update()
545 new_factor += RESOLUTION * measured_us / data->next_timer_us; in menu_update()
562 data->correction_factor[data->bucket] = new_factor; in menu_update()
564 /* update the repeating-pattern data */ in menu_update()
565 data->intervals[data->interval_ptr++] = measured_us; in menu_update()
566 if (data->interval_ptr >= INTERVALS) in menu_update()
567 data->interval_ptr = 0; in menu_update()
571 * menu_enable_device - scans a CPU's states and does setup
578 struct menu_device *data = &per_cpu(menu_devices, dev->cpu); in menu_enable_device()
588 data->correction_factor[i] = RESOLUTION * DECAY; in menu_enable_device()
602 * init_menu - initializes the governor