Commit 4108b3d9 authored by Len Brown's avatar Len Brown Committed by Rafael J. Wysocki

cpuidle: menu: Better idle duration measurement without using CPUIDLE_FLAG_TIME_INVALID

When menu sees CPUIDLE_FLAG_TIME_INVALID, it ignores its timestamps,
and assumes that idle lasted as long as the time till next predicted
timer expiration.

But if an interrupt was seen and serviced before that duration,
it would actually be more accurate to use the measured time
rather than rounding up to the next predicted timer expiration.

And if an interrupt is seen and serviced such that the mesured time
exceeds the time till next predicted timer expiration, then
truncating to that expiration is the right thing to do --
since we can never stay idle past that timer expiration.

So the code can do a better job without
checking for CPUIDLE_FLAG_TIME_INVALID.
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
Acked-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
Reviewed-by: default avatarTuukka Tikkanen <tuukka.tikkanen@linaro.org>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 0c570c18
...@@ -396,8 +396,8 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev) ...@@ -396,8 +396,8 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev)
* power state and occurrence of the wakeup event. * power state and occurrence of the wakeup event.
* *
* If the entered idle state didn't support residency measurements, * If the entered idle state didn't support residency measurements,
* we are basically lost in the dark how much time passed. * we use them anyway if they are short, and if long,
* As a compromise, assume we slept for the whole expected time. * truncate to the whole expected time.
* *
* Any measured amount of time will include the exit latency. * Any measured amount of time will include the exit latency.
* Since we are interested in when the wakeup begun, not when it * Since we are interested in when the wakeup begun, not when it
...@@ -405,22 +405,17 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev) ...@@ -405,22 +405,17 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev)
* the measured amount of time is less than the exit latency, * the measured amount of time is less than the exit latency,
* assume the state was never reached and the exit latency is 0. * assume the state was never reached and the exit latency is 0.
*/ */
if (unlikely(target->flags & CPUIDLE_FLAG_TIME_INVALID)) {
/* Use timer value as is */
measured_us = data->next_timer_us;
} else { /* measured value */
/* Use measured value */ measured_us = cpuidle_get_last_residency(dev);
measured_us = cpuidle_get_last_residency(dev);
/* Deduct exit latency */ /* Deduct exit latency */
if (measured_us > target->exit_latency) if (measured_us > target->exit_latency)
measured_us -= target->exit_latency; measured_us -= target->exit_latency;
/* Make sure our coefficients do not exceed unity */ /* Make sure our coefficients do not exceed unity */
if (measured_us > data->next_timer_us) if (measured_us > data->next_timer_us)
measured_us = data->next_timer_us; measured_us = data->next_timer_us;
}
/* Update our correction ratio */ /* Update our correction ratio */
new_factor = data->correction_factor[data->bucket]; new_factor = data->correction_factor[data->bucket];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment