···181181 */182182 if (s->target_residency > 0)183183 s->target_residency_ns = s->target_residency * NSEC_PER_USEC;184184+ else if (s->target_residency_ns < 0)185185+ s->target_residency_ns = 0;184186185187 if (s->exit_latency > 0)186188 s->exit_latency_ns = s->exit_latency * NSEC_PER_USEC;189189+ else if (s->exit_latency_ns < 0)190190+ s->exit_latency_ns = 0;187191 }188192}189193
+11-6
drivers/cpuidle/governors/menu.c
···271271 u64 predicted_ns;272272 u64 interactivity_req;273273 unsigned long nr_iowaiters;274274- ktime_t delta_next;274274+ ktime_t delta, delta_tick;275275 int i, idx;276276277277 if (data->needs_update) {···280280 }281281282282 /* determine the expected residency time, round up */283283- data->next_timer_ns = tick_nohz_get_sleep_length(&delta_next);283283+ delta = tick_nohz_get_sleep_length(&delta_tick);284284+ if (unlikely(delta < 0)) {285285+ delta = 0;286286+ delta_tick = 0;287287+ }288288+ data->next_timer_ns = delta;284289285290 nr_iowaiters = nr_iowait_cpu(dev->cpu);286291 data->bucket = which_bucket(data->next_timer_ns, nr_iowaiters);···323318 * state selection.324319 */325320 if (predicted_ns < TICK_NSEC)326326- predicted_ns = delta_next;321321+ predicted_ns = data->next_timer_ns;327322 } else {328323 /*329324 * Use the performance multiplier and the user-configurable···382377 * stuck in the shallow one for too long.383378 */384379 if (drv->states[idx].target_residency_ns < TICK_NSEC &&385385- s->target_residency_ns <= delta_next)380380+ s->target_residency_ns <= delta_tick)386381 idx = i;387382388383 return idx;···404399 predicted_ns < TICK_NSEC) && !tick_nohz_tick_stopped()) {405400 *stop_tick = false;406401407407- if (idx > 0 && drv->states[idx].target_residency_ns > delta_next) {402402+ if (idx > 0 && drv->states[idx].target_residency_ns > delta_tick) {408403 /*409404 * The tick is not going to be stopped and the target410405 * residency of the state to be returned is not within···416411 continue;417412418413 idx = i;419419- if (drv->states[i].target_residency_ns <= delta_next)414414+ if (drv->states[i].target_residency_ns <= delta_tick)420415 break;421416 }422417 }
+29-23
drivers/cpuidle/governors/teo.c
···100100 * @intervals: Saved idle duration values.101101 */102102struct teo_cpu {103103- u64 time_span_ns;104104- u64 sleep_length_ns;103103+ s64 time_span_ns;104104+ s64 sleep_length_ns;105105 struct teo_idle_state states[CPUIDLE_STATE_MAX];106106 int interval_idx;107107 u64 intervals[INTERVALS];···117117static void teo_update(struct cpuidle_driver *drv, struct cpuidle_device *dev)118118{119119 struct teo_cpu *cpu_data = per_cpu_ptr(&teo_cpus, dev->cpu);120120- int i, idx_hit = -1, idx_timer = -1;120120+ int i, idx_hit = 0, idx_timer = 0;121121+ unsigned int hits, misses;121122 u64 measured_ns;122123123124 if (cpu_data->time_span_ns >= cpu_data->sleep_length_ns) {···175174 * also increase the "early hits" metric for the state that actually176175 * matches the measured idle duration.177176 */178178- if (idx_timer >= 0) {179179- unsigned int hits = cpu_data->states[idx_timer].hits;180180- unsigned int misses = cpu_data->states[idx_timer].misses;177177+ hits = cpu_data->states[idx_timer].hits;178178+ hits -= hits >> DECAY_SHIFT;181179182182- hits -= hits >> DECAY_SHIFT;183183- misses -= misses >> DECAY_SHIFT;180180+ misses = cpu_data->states[idx_timer].misses;181181+ misses -= misses >> DECAY_SHIFT;184182185185- if (idx_timer > idx_hit) {186186- misses += PULSE;187187- if (idx_hit >= 0)188188- cpu_data->states[idx_hit].early_hits += PULSE;189189- } else {190190- hits += PULSE;191191- }192192-193193- cpu_data->states[idx_timer].misses = misses;194194- cpu_data->states[idx_timer].hits = hits;183183+ if (idx_timer == idx_hit) {184184+ hits += PULSE;185185+ } else {186186+ misses += PULSE;187187+ cpu_data->states[idx_hit].early_hits += PULSE;195188 }189189+190190+ cpu_data->states[idx_timer].misses = misses;191191+ cpu_data->states[idx_timer].hits = hits;196192197193 /*198194 * Save idle duration values corresponding to non-timer wakeups for···214216 */215217static int teo_find_shallower_state(struct cpuidle_driver *drv,216218 struct cpuidle_device *dev, int state_idx,217217- u64 duration_ns)219219+ s64 duration_ns)218220{219221 int i;220222···240242{241243 struct teo_cpu *cpu_data = per_cpu_ptr(&teo_cpus, dev->cpu);242244 s64 latency_req = cpuidle_governor_latency_req(dev->cpu);243243- u64 duration_ns;245245+ int max_early_idx, prev_max_early_idx, constraint_idx, idx0, idx, i;244246 unsigned int hits, misses, early_hits;245245- int max_early_idx, prev_max_early_idx, constraint_idx, idx, i;246247 ktime_t delta_tick;248248+ s64 duration_ns;247249248250 if (dev->last_state_idx >= 0) {249251 teo_update(drv, dev);···262264 prev_max_early_idx = -1;263265 constraint_idx = drv->state_count;264266 idx = -1;267267+ idx0 = idx;265268266269 for (i = 0; i < drv->state_count; i++) {267270 struct cpuidle_state *s = &drv->states[i];···323324 idx = i; /* first enabled state */324325 hits = cpu_data->states[i].hits;325326 misses = cpu_data->states[i].misses;327327+ idx0 = i;326328 }327329328330 if (s->target_residency_ns > duration_ns)···376376377377 if (idx < 0) {378378 idx = 0; /* No states enabled. Must use 0. */379379- } else if (idx > 0) {379379+ } else if (idx > idx0) {380380 unsigned int count = 0;381381 u64 sum = 0;382382383383 /*384384+ * The target residencies of at least two different enabled idle385385+ * states are less than or equal to the current expected idle386386+ * duration. Try to refine the selection using the most recent387387+ * measured idle duration values.388388+ *384389 * Count and sum the most recent idle duration values less than385390 * the current expected idle duration value.386391 */···433428 * till the closest timer including the tick, try to correct434429 * that.435430 */436436- if (idx > 0 && drv->states[idx].target_residency_ns > delta_tick)431431+ if (idx > idx0 &&432432+ drv->states[idx].target_residency_ns > delta_tick)437433 idx = teo_find_shallower_state(drv, dev, idx, delta_tick);438434 }439435
···4949 char name[CPUIDLE_NAME_LEN];5050 char desc[CPUIDLE_DESC_LEN];51515252- u64 exit_latency_ns;5353- u64 target_residency_ns;5252+ s64 exit_latency_ns;5353+ s64 target_residency_ns;5454 unsigned int flags;5555 unsigned int exit_latency; /* in US */5656 int power_usage; /* in mW */
+5-1
kernel/time/tick-sched.c
···11241124 * tick_nohz_get_sleep_length - return the expected length of the current sleep11251125 * @delta_next: duration until the next event if the tick cannot be stopped11261126 *11271127- * Called from power state control code with interrupts disabled11271127+ * Called from power state control code with interrupts disabled.11281128+ *11291129+ * The return value of this function and/or the value returned by it through the11301130+ * @delta_next pointer can be negative which must be taken into account by its11311131+ * callers.11281132 */11291133ktime_t tick_nohz_get_sleep_length(ktime_t *delta_next)11301134{