Skip to content

Commit e57c2bf

Browse files
committed
cpuidle: governors: menu: Refine stopped tick handling
This change is based on the observation that it is not in fact necessary to select a deep idle state every time the scheduler tick has been stopped before the idle state selection takes place. Namely, if the time till the closest timer (that is not the tick) is short enough, a shallow idle state can be selected because the timer will kick the CPU out of that state, so the damage from a possible overly optimistic selection will be limited. Update the menu governor in accordance with the above and use twice the tick period length as the "safe timer range" for allowing the original predicted_ns value to be used even if the tick has been stopped. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Christian Loehle <christian.loehle@arm.com> Link: https://patch.msgid.link/3341782.5fSG56mABF@rafael.j.wysocki
1 parent 11439c4 commit e57c2bf

2 files changed

Lines changed: 14 additions & 6 deletions

File tree

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
/*

0 commit comments

Comments
 (0)