Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge back earlier cpuidle updates for v5.13.

+54 -34
+4
drivers/cpuidle/driver.c
··· 181 181 */ 182 182 if (s->target_residency > 0) 183 183 s->target_residency_ns = s->target_residency * NSEC_PER_USEC; 184 + else if (s->target_residency_ns < 0) 185 + s->target_residency_ns = 0; 184 186 185 187 if (s->exit_latency > 0) 186 188 s->exit_latency_ns = s->exit_latency * NSEC_PER_USEC; 189 + else if (s->exit_latency_ns < 0) 190 + s->exit_latency_ns = 0; 187 191 } 188 192 } 189 193
+11 -6
drivers/cpuidle/governors/menu.c
··· 271 271 u64 predicted_ns; 272 272 u64 interactivity_req; 273 273 unsigned long nr_iowaiters; 274 - ktime_t delta_next; 274 + ktime_t delta, delta_tick; 275 275 int i, idx; 276 276 277 277 if (data->needs_update) { ··· 280 280 } 281 281 282 282 /* determine the expected residency time, round up */ 283 - data->next_timer_ns = tick_nohz_get_sleep_length(&delta_next); 283 + delta = tick_nohz_get_sleep_length(&delta_tick); 284 + if (unlikely(delta < 0)) { 285 + delta = 0; 286 + delta_tick = 0; 287 + } 288 + data->next_timer_ns = delta; 284 289 285 290 nr_iowaiters = nr_iowait_cpu(dev->cpu); 286 291 data->bucket = which_bucket(data->next_timer_ns, nr_iowaiters); ··· 323 318 * state selection. 324 319 */ 325 320 if (predicted_ns < TICK_NSEC) 326 - predicted_ns = delta_next; 321 + predicted_ns = data->next_timer_ns; 327 322 } else { 328 323 /* 329 324 * Use the performance multiplier and the user-configurable ··· 382 377 * stuck in the shallow one for too long. 383 378 */ 384 379 if (drv->states[idx].target_residency_ns < TICK_NSEC && 385 - s->target_residency_ns <= delta_next) 380 + s->target_residency_ns <= delta_tick) 386 381 idx = i; 387 382 388 383 return idx; ··· 404 399 predicted_ns < TICK_NSEC) && !tick_nohz_tick_stopped()) { 405 400 *stop_tick = false; 406 401 407 - if (idx > 0 && drv->states[idx].target_residency_ns > delta_next) { 402 + if (idx > 0 && drv->states[idx].target_residency_ns > delta_tick) { 408 403 /* 409 404 * The tick is not going to be stopped and the target 410 405 * residency of the state to be returned is not within ··· 416 411 continue; 417 412 418 413 idx = i; 419 - if (drv->states[i].target_residency_ns <= delta_next) 414 + if (drv->states[i].target_residency_ns <= delta_tick) 420 415 break; 421 416 } 422 417 }
+29 -23
drivers/cpuidle/governors/teo.c
··· 100 100 * @intervals: Saved idle duration values. 101 101 */ 102 102 struct teo_cpu { 103 - u64 time_span_ns; 104 - u64 sleep_length_ns; 103 + s64 time_span_ns; 104 + s64 sleep_length_ns; 105 105 struct teo_idle_state states[CPUIDLE_STATE_MAX]; 106 106 int interval_idx; 107 107 u64 intervals[INTERVALS]; ··· 117 117 static void teo_update(struct cpuidle_driver *drv, struct cpuidle_device *dev) 118 118 { 119 119 struct teo_cpu *cpu_data = per_cpu_ptr(&teo_cpus, dev->cpu); 120 - int i, idx_hit = -1, idx_timer = -1; 120 + int i, idx_hit = 0, idx_timer = 0; 121 + unsigned int hits, misses; 121 122 u64 measured_ns; 122 123 123 124 if (cpu_data->time_span_ns >= cpu_data->sleep_length_ns) { ··· 175 174 * also increase the "early hits" metric for the state that actually 176 175 * matches the measured idle duration. 177 176 */ 178 - if (idx_timer >= 0) { 179 - unsigned int hits = cpu_data->states[idx_timer].hits; 180 - unsigned int misses = cpu_data->states[idx_timer].misses; 177 + hits = cpu_data->states[idx_timer].hits; 178 + hits -= hits >> DECAY_SHIFT; 181 179 182 - hits -= hits >> DECAY_SHIFT; 183 - misses -= misses >> DECAY_SHIFT; 180 + misses = cpu_data->states[idx_timer].misses; 181 + misses -= misses >> DECAY_SHIFT; 184 182 185 - if (idx_timer > idx_hit) { 186 - misses += PULSE; 187 - if (idx_hit >= 0) 188 - cpu_data->states[idx_hit].early_hits += PULSE; 189 - } else { 190 - hits += PULSE; 191 - } 192 - 193 - cpu_data->states[idx_timer].misses = misses; 194 - cpu_data->states[idx_timer].hits = hits; 183 + if (idx_timer == idx_hit) { 184 + hits += PULSE; 185 + } else { 186 + misses += PULSE; 187 + cpu_data->states[idx_hit].early_hits += PULSE; 195 188 } 189 + 190 + cpu_data->states[idx_timer].misses = misses; 191 + cpu_data->states[idx_timer].hits = hits; 196 192 197 193 /* 198 194 * Save idle duration values corresponding to non-timer wakeups for ··· 214 216 */ 215 217 static int teo_find_shallower_state(struct cpuidle_driver *drv, 216 218 struct cpuidle_device *dev, int state_idx, 217 - u64 duration_ns) 219 + s64 duration_ns) 218 220 { 219 221 int i; 220 222 ··· 240 242 { 241 243 struct teo_cpu *cpu_data = per_cpu_ptr(&teo_cpus, dev->cpu); 242 244 s64 latency_req = cpuidle_governor_latency_req(dev->cpu); 243 - u64 duration_ns; 245 + int max_early_idx, prev_max_early_idx, constraint_idx, idx0, idx, i; 244 246 unsigned int hits, misses, early_hits; 245 - int max_early_idx, prev_max_early_idx, constraint_idx, idx, i; 246 247 ktime_t delta_tick; 248 + s64 duration_ns; 247 249 248 250 if (dev->last_state_idx >= 0) { 249 251 teo_update(drv, dev); ··· 262 264 prev_max_early_idx = -1; 263 265 constraint_idx = drv->state_count; 264 266 idx = -1; 267 + idx0 = idx; 265 268 266 269 for (i = 0; i < drv->state_count; i++) { 267 270 struct cpuidle_state *s = &drv->states[i]; ··· 323 324 idx = i; /* first enabled state */ 324 325 hits = cpu_data->states[i].hits; 325 326 misses = cpu_data->states[i].misses; 327 + idx0 = i; 326 328 } 327 329 328 330 if (s->target_residency_ns > duration_ns) ··· 376 376 377 377 if (idx < 0) { 378 378 idx = 0; /* No states enabled. Must use 0. */ 379 - } else if (idx > 0) { 379 + } else if (idx > idx0) { 380 380 unsigned int count = 0; 381 381 u64 sum = 0; 382 382 383 383 /* 384 + * The target residencies of at least two different enabled idle 385 + * states are less than or equal to the current expected idle 386 + * duration. Try to refine the selection using the most recent 387 + * measured idle duration values. 388 + * 384 389 * Count and sum the most recent idle duration values less than 385 390 * the current expected idle duration value. 386 391 */ ··· 433 428 * till the closest timer including the tick, try to correct 434 429 * that. 435 430 */ 436 - if (idx > 0 && drv->states[idx].target_residency_ns > delta_tick) 431 + if (idx > idx0 && 432 + drv->states[idx].target_residency_ns > delta_tick) 437 433 idx = teo_find_shallower_state(drv, dev, idx, delta_tick); 438 434 } 439 435
+3 -2
drivers/idle/intel_idle.c
··· 744 744 .name = "C6", 745 745 .desc = "MWAIT 0x20", 746 746 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 747 - .exit_latency = 128, 748 - .target_residency = 384, 747 + .exit_latency = 170, 748 + .target_residency = 600, 749 749 .enter = &intel_idle, 750 750 .enter_s2idle = intel_idle_s2idle, }, 751 751 { ··· 1156 1156 X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE, &idle_cpu_skl), 1157 1157 X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, &idle_cpu_skx), 1158 1158 X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &idle_cpu_icx), 1159 + X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &idle_cpu_icx), 1159 1160 X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL, &idle_cpu_knl), 1160 1161 X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM, &idle_cpu_knl), 1161 1162 X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT, &idle_cpu_bxt),
+2 -2
include/linux/cpuidle.h
··· 49 49 char name[CPUIDLE_NAME_LEN]; 50 50 char desc[CPUIDLE_DESC_LEN]; 51 51 52 - u64 exit_latency_ns; 53 - u64 target_residency_ns; 52 + s64 exit_latency_ns; 53 + s64 target_residency_ns; 54 54 unsigned int flags; 55 55 unsigned int exit_latency; /* in US */ 56 56 int power_usage; /* in mW */
+5 -1
kernel/time/tick-sched.c
··· 1124 1124 * tick_nohz_get_sleep_length - return the expected length of the current sleep 1125 1125 * @delta_next: duration until the next event if the tick cannot be stopped 1126 1126 * 1127 - * Called from power state control code with interrupts disabled 1127 + * Called from power state control code with interrupts disabled. 1128 + * 1129 + * The return value of this function and/or the value returned by it through the 1130 + * @delta_next pointer can be negative which must be taken into account by its 1131 + * callers. 1128 1132 */ 1129 1133 ktime_t tick_nohz_get_sleep_length(ktime_t *delta_next) 1130 1134 {