aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpuidle/governors/menu.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/cpuidle/governors/menu.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/cpuidle/governors/menu.c')
-rw-r--r--drivers/cpuidle/governors/menu.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index 68104434ebb5..f8e57c6303f2 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -18,6 +18,7 @@
18#include <linux/hrtimer.h> 18#include <linux/hrtimer.h>
19#include <linux/tick.h> 19#include <linux/tick.h>
20#include <linux/sched.h> 20#include <linux/sched.h>
21#include <linux/math64.h>
21 22
22#define BUCKETS 12 23#define BUCKETS 12
23#define RESOLUTION 1024 24#define RESOLUTION 1024
@@ -100,7 +101,6 @@ struct menu_device {
100 101
101 unsigned int expected_us; 102 unsigned int expected_us;
102 u64 predicted_us; 103 u64 predicted_us;
103 unsigned int measured_us;
104 unsigned int exit_us; 104 unsigned int exit_us;
105 unsigned int bucket; 105 unsigned int bucket;
106 u64 correction_factor[BUCKETS]; 106 u64 correction_factor[BUCKETS];
@@ -169,6 +169,12 @@ static DEFINE_PER_CPU(struct menu_device, menu_devices);
169 169
170static void menu_update(struct cpuidle_device *dev); 170static void menu_update(struct cpuidle_device *dev);
171 171
172/* This implements DIV_ROUND_CLOSEST but avoids 64 bit division */
173static u64 div_round64(u64 dividend, u32 divisor)
174{
175 return div_u64(dividend + (divisor / 2), divisor);
176}
177
172/** 178/**
173 * menu_select - selects the next idle state to enter 179 * menu_select - selects the next idle state to enter
174 * @dev: the CPU 180 * @dev: the CPU
@@ -180,14 +186,14 @@ static int menu_select(struct cpuidle_device *dev)
180 int i; 186 int i;
181 int multiplier; 187 int multiplier;
182 188
183 data->last_state_idx = 0;
184 data->exit_us = 0;
185
186 if (data->needs_update) { 189 if (data->needs_update) {
187 menu_update(dev); 190 menu_update(dev);
188 data->needs_update = 0; 191 data->needs_update = 0;
189 } 192 }
190 193
194 data->last_state_idx = 0;
195 data->exit_us = 0;
196
191 /* Special case when user has set very strict latency requirement */ 197 /* Special case when user has set very strict latency requirement */
192 if (unlikely(latency_req == 0)) 198 if (unlikely(latency_req == 0))
193 return 0; 199 return 0;
@@ -209,9 +215,8 @@ static int menu_select(struct cpuidle_device *dev)
209 data->correction_factor[data->bucket] = RESOLUTION * DECAY; 215 data->correction_factor[data->bucket] = RESOLUTION * DECAY;
210 216
211 /* Make sure to round up for half microseconds */ 217 /* Make sure to round up for half microseconds */
212 data->predicted_us = DIV_ROUND_CLOSEST( 218 data->predicted_us = div_round64(data->expected_us * data->correction_factor[data->bucket],
213 data->expected_us * data->correction_factor[data->bucket], 219 RESOLUTION * DECAY);
214 RESOLUTION * DECAY);
215 220
216 /* 221 /*
217 * We want to default to C1 (hlt), not to busy polling 222 * We want to default to C1 (hlt), not to busy polling
@@ -288,7 +293,7 @@ static void menu_update(struct cpuidle_device *dev)
288 new_factor = data->correction_factor[data->bucket] 293 new_factor = data->correction_factor[data->bucket]
289 * (DECAY - 1) / DECAY; 294 * (DECAY - 1) / DECAY;
290 295
291 if (data->expected_us > 0 && data->measured_us < MAX_INTERESTING) 296 if (data->expected_us > 0 && measured_us < MAX_INTERESTING)
292 new_factor += RESOLUTION * measured_us / data->expected_us; 297 new_factor += RESOLUTION * measured_us / data->expected_us;
293 else 298 else
294 /* 299 /*