diff options
author | Tero Kristo <tero.kristo@nokia.com> | 2011-02-24 10:19:23 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2011-05-29 00:35:47 -0400 |
commit | 7467571f4480b273007517b26297c07154c73924 (patch) | |
tree | e933b8cff072f5ec389cd5e20c85e756e49cafeb /drivers/cpuidle | |
parent | 521cb40b0c44418a4fd36dc633f575813d59a43d (diff) |
cpuidle: menu: fixed wrapping timers at 4.294 seconds
Cpuidle menu governor is using u32 as a temporary datatype for storing
nanosecond values which wrap around at 4.294 seconds. This causes errors
in predicted sleep times resulting in higher than should be C state
selection and increased power consumption. This also breaks cpuidle
state residency statistics.
cc: stable@kernel.org # .32.x through .39.x
Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/cpuidle')
-rw-r--r-- | drivers/cpuidle/governors/menu.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index f508690eb958..c47f3d09c1ee 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c | |||
@@ -237,6 +237,7 @@ static int menu_select(struct cpuidle_device *dev) | |||
237 | unsigned int power_usage = -1; | 237 | unsigned int power_usage = -1; |
238 | int i; | 238 | int i; |
239 | int multiplier; | 239 | int multiplier; |
240 | struct timespec t; | ||
240 | 241 | ||
241 | if (data->needs_update) { | 242 | if (data->needs_update) { |
242 | menu_update(dev); | 243 | menu_update(dev); |
@@ -251,8 +252,9 @@ static int menu_select(struct cpuidle_device *dev) | |||
251 | return 0; | 252 | return 0; |
252 | 253 | ||
253 | /* determine the expected residency time, round up */ | 254 | /* determine the expected residency time, round up */ |
255 | t = ktime_to_timespec(tick_nohz_get_sleep_length()); | ||
254 | data->expected_us = | 256 | data->expected_us = |
255 | DIV_ROUND_UP((u32)ktime_to_ns(tick_nohz_get_sleep_length()), 1000); | 257 | t.tv_sec * USEC_PER_SEC + t.tv_nsec / NSEC_PER_USEC; |
256 | 258 | ||
257 | 259 | ||
258 | data->bucket = which_bucket(data->expected_us); | 260 | data->bucket = which_bucket(data->expected_us); |