diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-07-26 19:13:26 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-08-11 21:35:24 -0400 |
commit | 657e142082bec684725383eccd54e4ace5a2c293 (patch) | |
tree | 650f6b439c9505e55da2520e9dca8fbc78b53e1a | |
parent | 6813e1d7dcf1db51970149e22f1524336a0bfa24 (diff) |
Revert "cpuidle: Quickly notice prediction failure in general case"
commit 228b30234f258a193317874854eee1ca7807186e upstream.
Revert commit e11538d1 (cpuidle: Quickly notice prediction failure in
general case), since it depends on commit 69a37be (cpuidle: Quickly
notice prediction failure for repeat mode) that has been identified
as the source of a significant performance regression in v3.8 and
later.
Requested-by: Jeremy Eder <jeder@redhat.com>
Tested-by: Len Brown <len.brown@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/cpuidle/governors/menu.c | 35 |
1 files changed, 1 insertions, 34 deletions
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index fe343a06b7da..b69a87e22155 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c | |||
@@ -34,7 +34,7 @@ | |||
34 | static DEFINE_PER_CPU(struct hrtimer, menu_hrtimer); | 34 | static DEFINE_PER_CPU(struct hrtimer, menu_hrtimer); |
35 | static DEFINE_PER_CPU(int, hrtimer_status); | 35 | static DEFINE_PER_CPU(int, hrtimer_status); |
36 | /* menu hrtimer mode */ | 36 | /* menu hrtimer mode */ |
37 | enum {MENU_HRTIMER_STOP, MENU_HRTIMER_REPEAT, MENU_HRTIMER_GENERAL}; | 37 | enum {MENU_HRTIMER_STOP, MENU_HRTIMER_REPEAT}; |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * Concepts and ideas behind the menu governor | 40 | * Concepts and ideas behind the menu governor |
@@ -116,13 +116,6 @@ enum {MENU_HRTIMER_STOP, MENU_HRTIMER_REPEAT, MENU_HRTIMER_GENERAL}; | |||
116 | * | 116 | * |
117 | */ | 117 | */ |
118 | 118 | ||
119 | /* | ||
120 | * The C-state residency is so long that is is worthwhile to exit | ||
121 | * from the shallow C-state and re-enter into a deeper C-state. | ||
122 | */ | ||
123 | static unsigned int perfect_cstate_ms __read_mostly = 30; | ||
124 | module_param(perfect_cstate_ms, uint, 0000); | ||
125 | |||
126 | struct menu_device { | 119 | struct menu_device { |
127 | int last_state_idx; | 120 | int last_state_idx; |
128 | int needs_update; | 121 | int needs_update; |
@@ -223,16 +216,6 @@ EXPORT_SYMBOL_GPL(menu_hrtimer_cancel); | |||
223 | static enum hrtimer_restart menu_hrtimer_notify(struct hrtimer *hrtimer) | 216 | static enum hrtimer_restart menu_hrtimer_notify(struct hrtimer *hrtimer) |
224 | { | 217 | { |
225 | int cpu = smp_processor_id(); | 218 | int cpu = smp_processor_id(); |
226 | struct menu_device *data = &per_cpu(menu_devices, cpu); | ||
227 | |||
228 | /* In general case, the expected residency is much larger than | ||
229 | * deepest C-state target residency, but prediction logic still | ||
230 | * predicts a small predicted residency, so the prediction | ||
231 | * history is totally broken if the timer is triggered. | ||
232 | * So reset the correction factor. | ||
233 | */ | ||
234 | if (per_cpu(hrtimer_status, cpu) == MENU_HRTIMER_GENERAL) | ||
235 | data->correction_factor[data->bucket] = RESOLUTION * DECAY; | ||
236 | 219 | ||
237 | per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_STOP; | 220 | per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_STOP; |
238 | 221 | ||
@@ -389,7 +372,6 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) | |||
389 | /* not deepest C-state chosen for low predicted residency */ | 372 | /* not deepest C-state chosen for low predicted residency */ |
390 | if (low_predicted) { | 373 | if (low_predicted) { |
391 | unsigned int timer_us = 0; | 374 | unsigned int timer_us = 0; |
392 | unsigned int perfect_us = 0; | ||
393 | 375 | ||
394 | /* | 376 | /* |
395 | * Set a timer to detect whether this sleep is much | 377 | * Set a timer to detect whether this sleep is much |
@@ -400,28 +382,13 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) | |||
400 | */ | 382 | */ |
401 | timer_us = 2 * (data->predicted_us + MAX_DEVIATION); | 383 | timer_us = 2 * (data->predicted_us + MAX_DEVIATION); |
402 | 384 | ||
403 | perfect_us = perfect_cstate_ms * 1000; | ||
404 | |||
405 | if (repeat && (4 * timer_us < data->expected_us)) { | 385 | if (repeat && (4 * timer_us < data->expected_us)) { |
406 | RCU_NONIDLE(hrtimer_start(hrtmr, | 386 | RCU_NONIDLE(hrtimer_start(hrtmr, |
407 | ns_to_ktime(1000 * timer_us), | 387 | ns_to_ktime(1000 * timer_us), |
408 | HRTIMER_MODE_REL_PINNED)); | 388 | HRTIMER_MODE_REL_PINNED)); |
409 | /* In repeat case, menu hrtimer is started */ | 389 | /* In repeat case, menu hrtimer is started */ |
410 | per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_REPEAT; | 390 | per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_REPEAT; |
411 | } else if (perfect_us < data->expected_us) { | ||
412 | /* | ||
413 | * The next timer is long. This could be because | ||
414 | * we did not make a useful prediction. | ||
415 | * In that case, it makes sense to re-enter | ||
416 | * into a deeper C-state after some time. | ||
417 | */ | ||
418 | RCU_NONIDLE(hrtimer_start(hrtmr, | ||
419 | ns_to_ktime(1000 * timer_us), | ||
420 | HRTIMER_MODE_REL_PINNED)); | ||
421 | /* In general case, menu hrtimer is started */ | ||
422 | per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_GENERAL; | ||
423 | } | 391 | } |
424 | |||
425 | } | 392 | } |
426 | 393 | ||
427 | return data->last_state_idx; | 394 | return data->last_state_idx; |