mirror of
https://github.com/torvalds/linux
synced 2024-10-07 11:53:31 +00:00
cpuidle: teo: Avoid stopping the tick unnecessarily when bailing out
When teo_select() is going to return early in some special cases, make it avoid stopping the tick if the idle state to be returned is shallow. In particular, never stop the tick if state 0 is to be returned. Link: https://lore.kernel.org/linux-pm/CAJZ5v0jJxHj65r2HXBTd3wfbZtsg=_StzwO1kA5STDnaPe_dWA@mail.gmail.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-and-tested-by: Kajetan Puchalski <kajetan.puchalski@arm.com>
This commit is contained in:
parent
3f0b0966b3
commit
04bae4e226
|
@ -382,12 +382,13 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
|
|||
/* Check if there is any choice in the first place. */
|
||||
if (drv->state_count < 2) {
|
||||
idx = 0;
|
||||
goto end;
|
||||
goto out_tick;
|
||||
}
|
||||
|
||||
if (!dev->states_usage[0].disable) {
|
||||
idx = 0;
|
||||
if (drv->states[1].target_residency_ns > duration_ns)
|
||||
goto end;
|
||||
goto out_tick;
|
||||
}
|
||||
|
||||
cpu_data->utilized = teo_cpu_is_utilized(dev->cpu, cpu_data);
|
||||
|
@ -408,11 +409,12 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
|
|||
* anyway.
|
||||
*/
|
||||
if ((!idx && !(drv->states[0].flags & CPUIDLE_FLAG_POLLING) &&
|
||||
teo_time_ok(duration_ns)) || dev->states_usage[1].disable)
|
||||
teo_time_ok(duration_ns)) || dev->states_usage[1].disable) {
|
||||
idx = 0;
|
||||
else /* Assume that state 1 is not a polling one and use it. */
|
||||
idx = 1;
|
||||
|
||||
goto out_tick;
|
||||
}
|
||||
/* Assume that state 1 is not a polling one and use it. */
|
||||
idx = 1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
@ -459,8 +461,15 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
|
|||
/* Avoid unnecessary overhead. */
|
||||
if (idx < 0) {
|
||||
idx = 0; /* No states enabled, must use 0. */
|
||||
goto end;
|
||||
} else if (idx == idx0) {
|
||||
goto out_tick;
|
||||
}
|
||||
|
||||
if (idx == idx0) {
|
||||
/*
|
||||
* This is the first enabled idle state, so use it, but do not
|
||||
* allow the tick to be stopped it is shallow enough.
|
||||
*/
|
||||
duration_ns = drv->states[idx].target_residency_ns;
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
@ -566,24 +575,25 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
|
|||
|
||||
end:
|
||||
/*
|
||||
* Don't stop the tick if the selected state is a polling one or if the
|
||||
* expected idle duration is shorter than the tick period length.
|
||||
* Allow the tick to be stopped unless the selected state is a polling
|
||||
* one or the expected idle duration is shorter than the tick period
|
||||
* length.
|
||||
*/
|
||||
if (((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) ||
|
||||
duration_ns < TICK_NSEC) && !tick_nohz_tick_stopped()) {
|
||||
*stop_tick = false;
|
||||
if ((!(drv->states[idx].flags & CPUIDLE_FLAG_POLLING) &&
|
||||
duration_ns >= TICK_NSEC) || tick_nohz_tick_stopped())
|
||||
return idx;
|
||||
|
||||
/*
|
||||
* The tick is not going to be stopped, so if the target
|
||||
* residency of the state to be returned is not within the time
|
||||
* till the closest timer including the tick, try to correct
|
||||
* that.
|
||||
*/
|
||||
if (idx > idx0 &&
|
||||
drv->states[idx].target_residency_ns > delta_tick)
|
||||
idx = teo_find_shallower_state(drv, dev, idx, delta_tick, false);
|
||||
}
|
||||
/*
|
||||
* The tick is not going to be stopped, so if the target residency of
|
||||
* the state to be returned is not within the time till the closest
|
||||
* timer including the tick, try to correct that.
|
||||
*/
|
||||
if (idx > idx0 &&
|
||||
drv->states[idx].target_residency_ns > delta_tick)
|
||||
idx = teo_find_shallower_state(drv, dev, idx, delta_tick, false);
|
||||
|
||||
out_tick:
|
||||
*stop_tick = false;
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue