summaryrefslogtreecommitdiffstats
path: root/drivers/cpuidle
diff options
context:
space:
mode:
authorTuukka Tikkanen <tuukka.tikkanen@linaro.org>2013-08-14 19:02:39 +0300
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-08-23 00:24:16 +0200
commit0e96d5adcfef22f86e4463909728d63f88944749 (patch)
treed7b346092439ab0b0fa2a12f444eef614dfbce9b /drivers/cpuidle
parent939e33b7fcd4980f21ff4c9558eb27fe81d16cdb (diff)
downloadlinux-0e96d5adcfef22f86e4463909728d63f88944749.tar.gz
linux-0e96d5adcfef22f86e4463909728d63f88944749.tar.bz2
linux-0e96d5adcfef22f86e4463909728d63f88944749.zip
cpuidle: Fix variable domains in get_typical_interval()
The menu governor uses a static function get_typical_interval() to try to detect a repeating pattern of wakeups. The previous interval durations are stored as an array of unsigned ints, but the arithmetic in the function is performed exclusively as 64 bit values, even when the value stored in a variable is known not to exceed unsigned int, which may be smaller and more efficient on some platforms. This patch changes the types of varibles used to store some intermediates, the maximum and and the cutoff threshold to unsigned ints. Average and standard deviation are still treated as 64 bit values, even when the values are known to be within the domain of unsigned int, to avoid casts to ensure correct integer promotion for arithmetic operations. Signed-off-by: Tuukka Tikkanen <tuukka.tikkanen@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpuidle')
-rw-r--r--drivers/cpuidle/governors/menu.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index ee88838d7f08..a56081ce170f 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -200,18 +200,19 @@ static u64 div_round64(u64 dividend, u32 divisor)
static void get_typical_interval(struct menu_device *data)
{
int i, divisor;
- uint64_t max, avg, stddev;
- int64_t thresh = LLONG_MAX; /* Discard outliers above this value. */
+ unsigned int max, thresh;
+ uint64_t avg, stddev;
+
+ thresh = UINT_MAX; /* Discard outliers above this value */
again:
- /* first calculate average and standard deviation of the past */
+ /* First calculate the average of past intervals */
max = 0;
avg = 0;
divisor = 0;
- stddev = 0;
for (i = 0; i < INTERVALS; i++) {
- int64_t value = data->intervals[i];
+ unsigned int value = data->intervals[i];
if (value <= thresh) {
avg += value;
divisor++;
@@ -221,8 +222,10 @@ again:
}
do_div(avg, divisor);
+ /* Then try to determine standard deviation */
+ stddev = 0;
for (i = 0; i < INTERVALS; i++) {
- int64_t value = data->intervals[i];
+ unsigned int value = data->intervals[i];
if (value <= thresh) {
int64_t diff = value - avg;
stddev += diff * diff;