aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpuidle/governors/menu.c
diff options
context:
space:
mode:
authorTuukka Tikkanen <tuukka.tikkanen@linaro.org>2013-08-14 12:02:39 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-08-22 18:24:16 -0400
commit0e96d5adcfef22f86e4463909728d63f88944749 (patch)
treed7b346092439ab0b0fa2a12f444eef614dfbce9b /drivers/cpuidle/governors/menu.c
parent939e33b7fcd4980f21ff4c9558eb27fe81d16cdb (diff)
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/governors/menu.c')
-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)
200static void get_typical_interval(struct menu_device *data) 200static void get_typical_interval(struct menu_device *data)
201{ 201{
202 int i, divisor; 202 int i, divisor;
203 uint64_t max, avg, stddev; 203 unsigned int max, thresh;
204 int64_t thresh = LLONG_MAX; /* Discard outliers above this value. */ 204 uint64_t avg, stddev;
205
206 thresh = UINT_MAX; /* Discard outliers above this value */
205 207
206again: 208again:
207 209
208 /* first calculate average and standard deviation of the past */ 210 /* First calculate the average of past intervals */
209 max = 0; 211 max = 0;
210 avg = 0; 212 avg = 0;
211 divisor = 0; 213 divisor = 0;
212 stddev = 0;
213 for (i = 0; i < INTERVALS; i++) { 214 for (i = 0; i < INTERVALS; i++) {
214 int64_t value = data->intervals[i]; 215 unsigned int value = data->intervals[i];
215 if (value <= thresh) { 216 if (value <= thresh) {
216 avg += value; 217 avg += value;
217 divisor++; 218 divisor++;
@@ -221,8 +222,10 @@ again:
221 } 222 }
222 do_div(avg, divisor); 223 do_div(avg, divisor);
223 224
225 /* Then try to determine standard deviation */
226 stddev = 0;
224 for (i = 0; i < INTERVALS; i++) { 227 for (i = 0; i < INTERVALS; i++) {
225 int64_t value = data->intervals[i]; 228 unsigned int value = data->intervals[i];
226 if (value <= thresh) { 229 if (value <= thresh) {
227 int64_t diff = value - avg; 230 int64_t diff = value - avg;
228 stddev += diff * diff; 231 stddev += diff * diff;