diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-08-06 13:13:54 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-08-06 13:13:54 -0400 |
commit | 11e4afb49b7fa1fc8e1ffd850c1806dd86a08204 (patch) | |
tree | 9e57efcb106ae912f7bec718feb3f8ec607559bb /drivers/cpufreq/cpufreq_ondemand.c | |
parent | 162500b3a3ff39d941d29db49b41a16667ae44f0 (diff) | |
parent | 9b2a606d3898fcb2eedb6faded3bb37549590ac4 (diff) |
Merge branches 'gemini' and 'misc' into devel
Diffstat (limited to 'drivers/cpufreq/cpufreq_ondemand.c')
-rw-r--r-- | drivers/cpufreq/cpufreq_ondemand.c | 148 |
1 files changed, 103 insertions, 45 deletions
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index bd444dc93cf2..7b5093664e49 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
@@ -73,6 +73,7 @@ enum {DBS_NORMAL_SAMPLE, DBS_SUB_SAMPLE}; | |||
73 | 73 | ||
74 | struct cpu_dbs_info_s { | 74 | struct cpu_dbs_info_s { |
75 | cputime64_t prev_cpu_idle; | 75 | cputime64_t prev_cpu_idle; |
76 | cputime64_t prev_cpu_iowait; | ||
76 | cputime64_t prev_cpu_wall; | 77 | cputime64_t prev_cpu_wall; |
77 | cputime64_t prev_cpu_nice; | 78 | cputime64_t prev_cpu_nice; |
78 | struct cpufreq_policy *cur_policy; | 79 | struct cpufreq_policy *cur_policy; |
@@ -108,6 +109,7 @@ static struct dbs_tuners { | |||
108 | unsigned int down_differential; | 109 | unsigned int down_differential; |
109 | unsigned int ignore_nice; | 110 | unsigned int ignore_nice; |
110 | unsigned int powersave_bias; | 111 | unsigned int powersave_bias; |
112 | unsigned int io_is_busy; | ||
111 | } dbs_tuners_ins = { | 113 | } dbs_tuners_ins = { |
112 | .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, | 114 | .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, |
113 | .down_differential = DEF_FREQUENCY_DOWN_DIFFERENTIAL, | 115 | .down_differential = DEF_FREQUENCY_DOWN_DIFFERENTIAL, |
@@ -148,6 +150,16 @@ static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) | |||
148 | return idle_time; | 150 | return idle_time; |
149 | } | 151 | } |
150 | 152 | ||
153 | static inline cputime64_t get_cpu_iowait_time(unsigned int cpu, cputime64_t *wall) | ||
154 | { | ||
155 | u64 iowait_time = get_cpu_iowait_time_us(cpu, wall); | ||
156 | |||
157 | if (iowait_time == -1ULL) | ||
158 | return 0; | ||
159 | |||
160 | return iowait_time; | ||
161 | } | ||
162 | |||
151 | /* | 163 | /* |
152 | * Find right freq to be set now with powersave_bias on. | 164 | * Find right freq to be set now with powersave_bias on. |
153 | * Returns the freq_hi to be used right now and will set freq_hi_jiffies, | 165 | * Returns the freq_hi to be used right now and will set freq_hi_jiffies, |
@@ -234,12 +246,8 @@ static ssize_t show_sampling_rate_min(struct kobject *kobj, | |||
234 | return sprintf(buf, "%u\n", min_sampling_rate); | 246 | return sprintf(buf, "%u\n", min_sampling_rate); |
235 | } | 247 | } |
236 | 248 | ||
237 | #define define_one_ro(_name) \ | 249 | define_one_global_ro(sampling_rate_max); |
238 | static struct global_attr _name = \ | 250 | define_one_global_ro(sampling_rate_min); |
239 | __ATTR(_name, 0444, show_##_name, NULL) | ||
240 | |||
241 | define_one_ro(sampling_rate_max); | ||
242 | define_one_ro(sampling_rate_min); | ||
243 | 251 | ||
244 | /* cpufreq_ondemand Governor Tunables */ | 252 | /* cpufreq_ondemand Governor Tunables */ |
245 | #define show_one(file_name, object) \ | 253 | #define show_one(file_name, object) \ |
@@ -249,6 +257,7 @@ static ssize_t show_##file_name \ | |||
249 | return sprintf(buf, "%u\n", dbs_tuners_ins.object); \ | 257 | return sprintf(buf, "%u\n", dbs_tuners_ins.object); \ |
250 | } | 258 | } |
251 | show_one(sampling_rate, sampling_rate); | 259 | show_one(sampling_rate, sampling_rate); |
260 | show_one(io_is_busy, io_is_busy); | ||
252 | show_one(up_threshold, up_threshold); | 261 | show_one(up_threshold, up_threshold); |
253 | show_one(ignore_nice_load, ignore_nice); | 262 | show_one(ignore_nice_load, ignore_nice); |
254 | show_one(powersave_bias, powersave_bias); | 263 | show_one(powersave_bias, powersave_bias); |
@@ -274,12 +283,8 @@ show_one_old(powersave_bias); | |||
274 | show_one_old(sampling_rate_min); | 283 | show_one_old(sampling_rate_min); |
275 | show_one_old(sampling_rate_max); | 284 | show_one_old(sampling_rate_max); |
276 | 285 | ||
277 | #define define_one_ro_old(object, _name) \ | 286 | cpufreq_freq_attr_ro_old(sampling_rate_min); |
278 | static struct freq_attr object = \ | 287 | cpufreq_freq_attr_ro_old(sampling_rate_max); |
279 | __ATTR(_name, 0444, show_##_name##_old, NULL) | ||
280 | |||
281 | define_one_ro_old(sampling_rate_min_old, sampling_rate_min); | ||
282 | define_one_ro_old(sampling_rate_max_old, sampling_rate_max); | ||
283 | 288 | ||
284 | /*** delete after deprecation time ***/ | 289 | /*** delete after deprecation time ***/ |
285 | 290 | ||
@@ -299,6 +304,23 @@ static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b, | |||
299 | return count; | 304 | return count; |
300 | } | 305 | } |
301 | 306 | ||
307 | static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b, | ||
308 | const char *buf, size_t count) | ||
309 | { | ||
310 | unsigned int input; | ||
311 | int ret; | ||
312 | |||
313 | ret = sscanf(buf, "%u", &input); | ||
314 | if (ret != 1) | ||
315 | return -EINVAL; | ||
316 | |||
317 | mutex_lock(&dbs_mutex); | ||
318 | dbs_tuners_ins.io_is_busy = !!input; | ||
319 | mutex_unlock(&dbs_mutex); | ||
320 | |||
321 | return count; | ||
322 | } | ||
323 | |||
302 | static ssize_t store_up_threshold(struct kobject *a, struct attribute *b, | 324 | static ssize_t store_up_threshold(struct kobject *a, struct attribute *b, |
303 | const char *buf, size_t count) | 325 | const char *buf, size_t count) |
304 | { | 326 | { |
@@ -376,14 +398,11 @@ static ssize_t store_powersave_bias(struct kobject *a, struct attribute *b, | |||
376 | return count; | 398 | return count; |
377 | } | 399 | } |
378 | 400 | ||
379 | #define define_one_rw(_name) \ | 401 | define_one_global_rw(sampling_rate); |
380 | static struct global_attr _name = \ | 402 | define_one_global_rw(io_is_busy); |
381 | __ATTR(_name, 0644, show_##_name, store_##_name) | 403 | define_one_global_rw(up_threshold); |
382 | 404 | define_one_global_rw(ignore_nice_load); | |
383 | define_one_rw(sampling_rate); | 405 | define_one_global_rw(powersave_bias); |
384 | define_one_rw(up_threshold); | ||
385 | define_one_rw(ignore_nice_load); | ||
386 | define_one_rw(powersave_bias); | ||
387 | 406 | ||
388 | static struct attribute *dbs_attributes[] = { | 407 | static struct attribute *dbs_attributes[] = { |
389 | &sampling_rate_max.attr, | 408 | &sampling_rate_max.attr, |
@@ -392,6 +411,7 @@ static struct attribute *dbs_attributes[] = { | |||
392 | &up_threshold.attr, | 411 | &up_threshold.attr, |
393 | &ignore_nice_load.attr, | 412 | &ignore_nice_load.attr, |
394 | &powersave_bias.attr, | 413 | &powersave_bias.attr, |
414 | &io_is_busy.attr, | ||
395 | NULL | 415 | NULL |
396 | }; | 416 | }; |
397 | 417 | ||
@@ -415,14 +435,10 @@ write_one_old(up_threshold); | |||
415 | write_one_old(ignore_nice_load); | 435 | write_one_old(ignore_nice_load); |
416 | write_one_old(powersave_bias); | 436 | write_one_old(powersave_bias); |
417 | 437 | ||
418 | #define define_one_rw_old(object, _name) \ | 438 | cpufreq_freq_attr_rw_old(sampling_rate); |
419 | static struct freq_attr object = \ | 439 | cpufreq_freq_attr_rw_old(up_threshold); |
420 | __ATTR(_name, 0644, show_##_name##_old, store_##_name##_old) | 440 | cpufreq_freq_attr_rw_old(ignore_nice_load); |
421 | 441 | cpufreq_freq_attr_rw_old(powersave_bias); | |
422 | define_one_rw_old(sampling_rate_old, sampling_rate); | ||
423 | define_one_rw_old(up_threshold_old, up_threshold); | ||
424 | define_one_rw_old(ignore_nice_load_old, ignore_nice_load); | ||
425 | define_one_rw_old(powersave_bias_old, powersave_bias); | ||
426 | 442 | ||
427 | static struct attribute *dbs_attributes_old[] = { | 443 | static struct attribute *dbs_attributes_old[] = { |
428 | &sampling_rate_max_old.attr, | 444 | &sampling_rate_max_old.attr, |
@@ -443,6 +459,17 @@ static struct attribute_group dbs_attr_group_old = { | |||
443 | 459 | ||
444 | /************************** sysfs end ************************/ | 460 | /************************** sysfs end ************************/ |
445 | 461 | ||
462 | static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq) | ||
463 | { | ||
464 | if (dbs_tuners_ins.powersave_bias) | ||
465 | freq = powersave_bias_target(p, freq, CPUFREQ_RELATION_H); | ||
466 | else if (p->cur == p->max) | ||
467 | return; | ||
468 | |||
469 | __cpufreq_driver_target(p, freq, dbs_tuners_ins.powersave_bias ? | ||
470 | CPUFREQ_RELATION_L : CPUFREQ_RELATION_H); | ||
471 | } | ||
472 | |||
446 | static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | 473 | static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) |
447 | { | 474 | { |
448 | unsigned int max_load_freq; | 475 | unsigned int max_load_freq; |
@@ -470,14 +497,15 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
470 | 497 | ||
471 | for_each_cpu(j, policy->cpus) { | 498 | for_each_cpu(j, policy->cpus) { |
472 | struct cpu_dbs_info_s *j_dbs_info; | 499 | struct cpu_dbs_info_s *j_dbs_info; |
473 | cputime64_t cur_wall_time, cur_idle_time; | 500 | cputime64_t cur_wall_time, cur_idle_time, cur_iowait_time; |
474 | unsigned int idle_time, wall_time; | 501 | unsigned int idle_time, wall_time, iowait_time; |
475 | unsigned int load, load_freq; | 502 | unsigned int load, load_freq; |
476 | int freq_avg; | 503 | int freq_avg; |
477 | 504 | ||
478 | j_dbs_info = &per_cpu(od_cpu_dbs_info, j); | 505 | j_dbs_info = &per_cpu(od_cpu_dbs_info, j); |
479 | 506 | ||
480 | cur_idle_time = get_cpu_idle_time(j, &cur_wall_time); | 507 | cur_idle_time = get_cpu_idle_time(j, &cur_wall_time); |
508 | cur_iowait_time = get_cpu_iowait_time(j, &cur_wall_time); | ||
481 | 509 | ||
482 | wall_time = (unsigned int) cputime64_sub(cur_wall_time, | 510 | wall_time = (unsigned int) cputime64_sub(cur_wall_time, |
483 | j_dbs_info->prev_cpu_wall); | 511 | j_dbs_info->prev_cpu_wall); |
@@ -487,6 +515,10 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
487 | j_dbs_info->prev_cpu_idle); | 515 | j_dbs_info->prev_cpu_idle); |
488 | j_dbs_info->prev_cpu_idle = cur_idle_time; | 516 | j_dbs_info->prev_cpu_idle = cur_idle_time; |
489 | 517 | ||
518 | iowait_time = (unsigned int) cputime64_sub(cur_iowait_time, | ||
519 | j_dbs_info->prev_cpu_iowait); | ||
520 | j_dbs_info->prev_cpu_iowait = cur_iowait_time; | ||
521 | |||
490 | if (dbs_tuners_ins.ignore_nice) { | 522 | if (dbs_tuners_ins.ignore_nice) { |
491 | cputime64_t cur_nice; | 523 | cputime64_t cur_nice; |
492 | unsigned long cur_nice_jiffies; | 524 | unsigned long cur_nice_jiffies; |
@@ -504,6 +536,16 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
504 | idle_time += jiffies_to_usecs(cur_nice_jiffies); | 536 | idle_time += jiffies_to_usecs(cur_nice_jiffies); |
505 | } | 537 | } |
506 | 538 | ||
539 | /* | ||
540 | * For the purpose of ondemand, waiting for disk IO is an | ||
541 | * indication that you're performance critical, and not that | ||
542 | * the system is actually idle. So subtract the iowait time | ||
543 | * from the cpu idle time. | ||
544 | */ | ||
545 | |||
546 | if (dbs_tuners_ins.io_is_busy && idle_time >= iowait_time) | ||
547 | idle_time -= iowait_time; | ||
548 | |||
507 | if (unlikely(!wall_time || wall_time < idle_time)) | 549 | if (unlikely(!wall_time || wall_time < idle_time)) |
508 | continue; | 550 | continue; |
509 | 551 | ||
@@ -520,19 +562,7 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
520 | 562 | ||
521 | /* Check for frequency increase */ | 563 | /* Check for frequency increase */ |
522 | if (max_load_freq > dbs_tuners_ins.up_threshold * policy->cur) { | 564 | if (max_load_freq > dbs_tuners_ins.up_threshold * policy->cur) { |
523 | /* if we are already at full speed then break out early */ | 565 | dbs_freq_increase(policy, policy->max); |
524 | if (!dbs_tuners_ins.powersave_bias) { | ||
525 | if (policy->cur == policy->max) | ||
526 | return; | ||
527 | |||
528 | __cpufreq_driver_target(policy, policy->max, | ||
529 | CPUFREQ_RELATION_H); | ||
530 | } else { | ||
531 | int freq = powersave_bias_target(policy, policy->max, | ||
532 | CPUFREQ_RELATION_H); | ||
533 | __cpufreq_driver_target(policy, freq, | ||
534 | CPUFREQ_RELATION_L); | ||
535 | } | ||
536 | return; | 566 | return; |
537 | } | 567 | } |
538 | 568 | ||
@@ -579,7 +609,9 @@ static void do_dbs_timer(struct work_struct *work) | |||
579 | /* We want all CPUs to do sampling nearly on same jiffy */ | 609 | /* We want all CPUs to do sampling nearly on same jiffy */ |
580 | int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); | 610 | int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); |
581 | 611 | ||
582 | delay -= jiffies % delay; | 612 | if (num_online_cpus() > 1) |
613 | delay -= jiffies % delay; | ||
614 | |||
583 | mutex_lock(&dbs_info->timer_mutex); | 615 | mutex_lock(&dbs_info->timer_mutex); |
584 | 616 | ||
585 | /* Common NORMAL_SAMPLE setup */ | 617 | /* Common NORMAL_SAMPLE setup */ |
@@ -604,7 +636,9 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) | |||
604 | { | 636 | { |
605 | /* We want all CPUs to do sampling nearly on same jiffy */ | 637 | /* We want all CPUs to do sampling nearly on same jiffy */ |
606 | int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); | 638 | int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); |
607 | delay -= jiffies % delay; | 639 | |
640 | if (num_online_cpus() > 1) | ||
641 | delay -= jiffies % delay; | ||
608 | 642 | ||
609 | dbs_info->sample_type = DBS_NORMAL_SAMPLE; | 643 | dbs_info->sample_type = DBS_NORMAL_SAMPLE; |
610 | INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); | 644 | INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); |
@@ -617,6 +651,29 @@ static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) | |||
617 | cancel_delayed_work_sync(&dbs_info->work); | 651 | cancel_delayed_work_sync(&dbs_info->work); |
618 | } | 652 | } |
619 | 653 | ||
654 | /* | ||
655 | * Not all CPUs want IO time to be accounted as busy; this dependson how | ||
656 | * efficient idling at a higher frequency/voltage is. | ||
657 | * Pavel Machek says this is not so for various generations of AMD and old | ||
658 | * Intel systems. | ||
659 | * Mike Chan (androidlcom) calis this is also not true for ARM. | ||
660 | * Because of this, whitelist specific known (series) of CPUs by default, and | ||
661 | * leave all others up to the user. | ||
662 | */ | ||
663 | static int should_io_be_busy(void) | ||
664 | { | ||
665 | #if defined(CONFIG_X86) | ||
666 | /* | ||
667 | * For Intel, Core 2 (model 15) andl later have an efficient idle. | ||
668 | */ | ||
669 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && | ||
670 | boot_cpu_data.x86 == 6 && | ||
671 | boot_cpu_data.x86_model >= 15) | ||
672 | return 1; | ||
673 | #endif | ||
674 | return 0; | ||
675 | } | ||
676 | |||
620 | static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | 677 | static int cpufreq_governor_dbs(struct cpufreq_policy *policy, |
621 | unsigned int event) | 678 | unsigned int event) |
622 | { | 679 | { |
@@ -679,6 +736,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
679 | dbs_tuners_ins.sampling_rate = | 736 | dbs_tuners_ins.sampling_rate = |
680 | max(min_sampling_rate, | 737 | max(min_sampling_rate, |
681 | latency * LATENCY_MULTIPLIER); | 738 | latency * LATENCY_MULTIPLIER); |
739 | dbs_tuners_ins.io_is_busy = should_io_be_busy(); | ||
682 | } | 740 | } |
683 | mutex_unlock(&dbs_mutex); | 741 | mutex_unlock(&dbs_mutex); |
684 | 742 | ||