diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/cpuidle/governors/menu.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (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.c | 21 |
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 | ||
170 | static void menu_update(struct cpuidle_device *dev); | 170 | static void menu_update(struct cpuidle_device *dev); |
171 | 171 | ||
172 | /* This implements DIV_ROUND_CLOSEST but avoids 64 bit division */ | ||
173 | static 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 | /* |