Skip to content

Commit 9917de7

Browse files
committed
Merge tag 'pm-5.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management fixes from Rafael Wysocki: "Fix a recent regression in the timer events oriented (TEO) cpuidle governor causing it to misbehave when idle state 0 is disabled and rename two local variables for improved clarity on top of that" * tag 'pm-5.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: cpuidle: teo: Rename two local variables in teo_select() cpuidle: teo: Fix alternative idle state lookup
2 parents 5d60968 + 4adae7d commit 9917de7

1 file changed

Lines changed: 31 additions & 17 deletions

File tree

  • drivers/cpuidle/governors

drivers/cpuidle/governors/teo.c

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,8 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
382382
alt_intercepts = 2 * idx_intercept_sum > cpu_data->total - idx_hit_sum;
383383
alt_recent = idx_recent_sum > NR_RECENT / 2;
384384
if (alt_recent || alt_intercepts) {
385-
s64 last_enabled_span_ns = duration_ns;
386-
int last_enabled_idx = idx;
385+
s64 first_suitable_span_ns = duration_ns;
386+
int first_suitable_idx = idx;
387387

388388
/*
389389
* Look for the deepest idle state whose target residency had
@@ -397,37 +397,51 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
397397
intercept_sum = 0;
398398
recent_sum = 0;
399399

400-
for (i = idx - 1; i >= idx0; i--) {
400+
for (i = idx - 1; i >= 0; i--) {
401401
struct teo_bin *bin = &cpu_data->state_bins[i];
402402
s64 span_ns;
403403

404404
intercept_sum += bin->intercepts;
405405
recent_sum += bin->recent;
406406

407+
span_ns = teo_middle_of_bin(i, drv);
408+
409+
if ((!alt_recent || 2 * recent_sum > idx_recent_sum) &&
410+
(!alt_intercepts ||
411+
2 * intercept_sum > idx_intercept_sum)) {
412+
if (teo_time_ok(span_ns) &&
413+
!dev->states_usage[i].disable) {
414+
idx = i;
415+
duration_ns = span_ns;
416+
} else {
417+
/*
418+
* The current state is too shallow or
419+
* disabled, so take the first enabled
420+
* deeper state with suitable time span.
421+
*/
422+
idx = first_suitable_idx;
423+
duration_ns = first_suitable_span_ns;
424+
}
425+
break;
426+
}
427+
407428
if (dev->states_usage[i].disable)
408429
continue;
409430

410-
span_ns = teo_middle_of_bin(i, drv);
411431
if (!teo_time_ok(span_ns)) {
412432
/*
413-
* The current state is too shallow, so select
414-
* the first enabled deeper state.
433+
* The current state is too shallow, but if an
434+
* alternative candidate state has been found,
435+
* it may still turn out to be a better choice.
415436
*/
416-
duration_ns = last_enabled_span_ns;
417-
idx = last_enabled_idx;
418-
break;
419-
}
437+
if (first_suitable_idx != idx)
438+
continue;
420439

421-
if ((!alt_recent || 2 * recent_sum > idx_recent_sum) &&
422-
(!alt_intercepts ||
423-
2 * intercept_sum > idx_intercept_sum)) {
424-
idx = i;
425-
duration_ns = span_ns;
426440
break;
427441
}
428442

429-
last_enabled_span_ns = span_ns;
430-
last_enabled_idx = i;
443+
first_suitable_span_ns = span_ns;
444+
first_suitable_idx = i;
431445
}
432446
}
433447

0 commit comments

Comments
 (0)