Skip to content

Commit 455b877

Browse files
committed
Merge branches 'pm-cpuidle', 'pm-cpufreq' and 'pm-powercap' into linux-next
* pm-cpuidle: cpuidle: governors: teo: Rearrange stopped tick handling cpuidle: governors: menu: Refine stopped tick handling * pm-cpufreq: cpufreq: Add debug print for current frequency in __cpufreq_driver_target() * pm-powercap: powercap: intel_rapl: Move MSR default settings into MSR interface driver powercap: intel_rapl: Register PM notifier only when RAPL package exists thermal: intel: int340x: processor: Move RAPL defaults to MMIO driver powercap: intel_rapl: Move TPMI default settings into TPMI interface driver powercap: intel_rapl: Allow interface drivers to configure rapl_defaults powercap: intel_rapl: Use unit conversion macros from units.h powercap: intel_rapl: Use GENMASK() and BIT() macros powercap: intel_rapl: Use shifts for power-of-2 operations powercap: intel_rapl: Simplify rapl_compute_time_window_atom() powercap: intel_rapl: Remove unused TIME_WINDOW macros powercap: intel_rapl: Cleanup coding style powercap: intel_rapl: Add a symbol namespace for intel_rapl exports
4 parents ef5af3b + 106a266 + 54de61a + a1e8632 commit 455b877

10 files changed

Lines changed: 612 additions & 578 deletions

File tree

drivers/cpufreq/cpufreq.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2367,8 +2367,8 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
23672367
target_freq = __resolve_freq(policy, target_freq, policy->min,
23682368
policy->max, relation);
23692369

2370-
pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
2371-
policy->cpu, target_freq, relation, old_target_freq);
2370+
pr_debug("CPU %u: cur %u kHz -> target %u kHz (req %u kHz, rel %u)\n",
2371+
policy->cpu, policy->cur, target_freq, old_target_freq, relation);
23722372

23732373
/*
23742374
* This might look like a redundant call as we are checking it again

drivers/cpuidle/governors/gov.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,10 @@
1010
* check the time till the closest expected timer event.
1111
*/
1212
#define RESIDENCY_THRESHOLD_NS (15 * NSEC_PER_USEC)
13+
/*
14+
* If the closest timer is in this range, the governor idle state selection need
15+
* not be adjusted after the scheduler tick has been stopped.
16+
*/
17+
#define SAFE_TIMER_RANGE_NS (2 * TICK_NSEC)
1318

1419
#endif /* __CPUIDLE_GOVERNOR_H */

drivers/cpuidle/governors/menu.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -261,13 +261,16 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
261261
predicted_ns = min((u64)timer_us * NSEC_PER_USEC, predicted_ns);
262262
/*
263263
* If the tick is already stopped, the cost of possible short
264-
* idle duration misprediction is much higher, because the CPU
265-
* may be stuck in a shallow idle state for a long time as a
266-
* result of it. In that case, say we might mispredict and use
267-
* the known time till the closest timer event for the idle
268-
* state selection.
264+
* idle duration misprediction is higher because the CPU may get
265+
* stuck in a shallow idle state then. To avoid that, if
266+
* predicted_ns is small enough, say it might be mispredicted
267+
* and use the known time till the closest timer for idle state
268+
* selection unless that timer is going to trigger within
269+
* SAFE_TIMER_RANGE_NS in which case it can be regarded as a
270+
* sufficient safety net.
269271
*/
270-
if (tick_nohz_tick_stopped() && predicted_ns < TICK_NSEC)
272+
if (tick_nohz_tick_stopped() && predicted_ns < TICK_NSEC &&
273+
data->next_timer_ns > SAFE_TIMER_RANGE_NS)
271274
predicted_ns = data->next_timer_ns;
272275
} else {
273276
/*

drivers/cpuidle/governors/teo.c

Lines changed: 34 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -407,50 +407,13 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
407407
* better choice.
408408
*/
409409
if (2 * idx_intercept_sum > cpu_data->total - idx_hit_sum) {
410-
int min_idx = idx0;
411-
412-
if (tick_nohz_tick_stopped()) {
413-
/*
414-
* Look for the shallowest idle state below the current
415-
* candidate one whose target residency is at least
416-
* equal to the tick period length.
417-
*/
418-
while (min_idx < idx &&
419-
drv->states[min_idx].target_residency_ns < TICK_NSEC)
420-
min_idx++;
421-
422-
/*
423-
* Avoid selecting a state with a lower index, but with
424-
* the same target residency as the current candidate
425-
* one.
426-
*/
427-
if (drv->states[min_idx].target_residency_ns ==
428-
drv->states[idx].target_residency_ns)
429-
goto constraint;
430-
}
431-
432-
/*
433-
* If the minimum state index is greater than or equal to the
434-
* index of the state with the maximum intercepts metric and
435-
* the corresponding state is enabled, there is no need to look
436-
* at the deeper states.
437-
*/
438-
if (min_idx >= intercept_max_idx &&
439-
!dev->states_usage[min_idx].disable) {
440-
idx = min_idx;
441-
goto constraint;
442-
}
443-
444410
/*
445411
* Look for the deepest enabled idle state, at most as deep as
446412
* the one with the maximum intercepts metric, whose target
447413
* residency had not been greater than the idle duration in over
448414
* a half of the relevant cases in the past.
449-
*
450-
* Take the possible duration limitation present if the tick
451-
* has been stopped already into account.
452415
*/
453-
for (i = idx - 1, intercept_sum = 0; i >= min_idx; i--) {
416+
for (i = idx - 1, intercept_sum = 0; i >= idx0; i--) {
454417
intercept_sum += cpu_data->state_bins[i].intercepts;
455418

456419
if (dev->states_usage[i].disable)
@@ -463,7 +426,6 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
463426
}
464427
}
465428

466-
constraint:
467429
/*
468430
* If there is a latency constraint, it may be necessary to select an
469431
* idle state shallower than the current candidate one.
@@ -472,13 +434,13 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
472434
idx = constraint_idx;
473435

474436
/*
475-
* If either the candidate state is state 0 or its target residency is
476-
* low enough, there is basically nothing more to do, but if the sleep
477-
* length is not updated, the subsequent wakeup will be counted as an
478-
* "intercept" which may be problematic in the cases when timer wakeups
479-
* are dominant. Namely, it may effectively prevent deeper idle states
480-
* from being selected at one point even if no imminent timers are
481-
* scheduled.
437+
* If the tick has not been stopped and either the candidate state is
438+
* state 0 or its target residency is low enough, there is basically
439+
* nothing more to do, but if the sleep length is not updated, the
440+
* subsequent wakeup will be counted as an "intercept". That may be
441+
* problematic in the cases when timer wakeups are dominant because it
442+
* may effectively prevent deeper idle states from being selected at one
443+
* point even if no imminent timers are scheduled.
482444
*
483445
* However, frequent timers in the RESIDENCY_THRESHOLD_NS range on one
484446
* CPU are unlikely (user space has a default 50 us slack value for
@@ -494,14 +456,39 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
494456
* shallow idle states regardless of the wakeup type, so the sleep
495457
* length need not be known in that case.
496458
*/
497-
if ((!idx || drv->states[idx].target_residency_ns < RESIDENCY_THRESHOLD_NS) &&
459+
if (!tick_nohz_tick_stopped() && (!idx ||
460+
drv->states[idx].target_residency_ns < RESIDENCY_THRESHOLD_NS) &&
498461
(2 * cpu_data->short_idles >= cpu_data->total ||
499462
latency_req < LATENCY_THRESHOLD_NS))
500463
goto out_tick;
501464

502465
duration_ns = tick_nohz_get_sleep_length(&delta_tick);
503466
cpu_data->sleep_length_ns = duration_ns;
504467

468+
/*
469+
* If the tick has been stopped and the closest timer is too far away,
470+
* update the selection to prevent the CPU from getting stuck in a
471+
* shallow idle state for too long.
472+
*/
473+
if (tick_nohz_tick_stopped() && duration_ns > SAFE_TIMER_RANGE_NS &&
474+
drv->states[idx].target_residency_ns < TICK_NSEC) {
475+
/*
476+
* Look for the deepest enabled idle state with exit latency
477+
* within the PM QoS limit and with target residency within
478+
* duration_ns.
479+
*/
480+
for (i = constraint_idx; i > idx; i--) {
481+
if (dev->states_usage[i].disable)
482+
continue;
483+
484+
if (drv->states[i].target_residency_ns <= duration_ns) {
485+
idx = i;
486+
break;
487+
}
488+
}
489+
return idx;
490+
}
491+
505492
if (!idx)
506493
goto out_tick;
507494

0 commit comments

Comments
 (0)