diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-18 11:27:54 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-18 11:27:54 -0400 |
| commit | b8ae30ee26d379db436b0b8c8c3ff1b52f69e5d1 (patch) | |
| tree | 506aa0b4bdbf90f61e7e9261c7db90aa1452dcce /drivers | |
| parent | 4d7b4ac22fbec1a03206c6cde353f2fd6942f828 (diff) | |
| parent | 9c6f7e43b4e02c161b53e97ba913855246876c61 (diff) | |
Merge branch 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (49 commits)
stop_machine: Move local variable closer to the usage site in cpu_stop_cpu_callback()
sched, wait: Use wrapper functions
sched: Remove a stale comment
ondemand: Make the iowait-is-busy time a sysfs tunable
ondemand: Solve a big performance issue by counting IOWAIT time as busy
sched: Intoduce get_cpu_iowait_time_us()
sched: Eliminate the ts->idle_lastupdate field
sched: Fold updating of the last_update_time_info into update_ts_time_stats()
sched: Update the idle statistics in get_cpu_idle_time_us()
sched: Introduce a function to update the idle statistics
sched: Add a comment to get_cpu_idle_time_us()
cpu_stop: add dummy implementation for UP
sched: Remove rq argument to the tracepoints
rcu: need barrier() in UP synchronize_sched_expedited()
sched: correctly place paranioa memory barriers in synchronize_sched_expedited()
sched: kill paranoia check in synchronize_sched_expedited()
sched: replace migration_thread with cpu_stop
stop_machine: reimplement using cpu_stop
cpu_stop: implement stop_cpu[s]()
sched: Fix select_idle_sibling() logic in select_task_rq_fair()
...
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/cpufreq/cpufreq_ondemand.c | 75 | ||||
| -rw-r--r-- | drivers/xen/manage.c | 14 |
2 files changed, 75 insertions, 14 deletions
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index bd444dc93cf2..8e9dbdc6c700 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, |
| @@ -249,6 +261,7 @@ static ssize_t show_##file_name \ | |||
| 249 | return sprintf(buf, "%u\n", dbs_tuners_ins.object); \ | 261 | return sprintf(buf, "%u\n", dbs_tuners_ins.object); \ |
| 250 | } | 262 | } |
| 251 | show_one(sampling_rate, sampling_rate); | 263 | show_one(sampling_rate, sampling_rate); |
| 264 | show_one(io_is_busy, io_is_busy); | ||
| 252 | show_one(up_threshold, up_threshold); | 265 | show_one(up_threshold, up_threshold); |
| 253 | show_one(ignore_nice_load, ignore_nice); | 266 | show_one(ignore_nice_load, ignore_nice); |
| 254 | show_one(powersave_bias, powersave_bias); | 267 | show_one(powersave_bias, powersave_bias); |
| @@ -299,6 +312,23 @@ static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b, | |||
| 299 | return count; | 312 | return count; |
| 300 | } | 313 | } |
| 301 | 314 | ||
| 315 | static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b, | ||
| 316 | const char *buf, size_t count) | ||
| 317 | { | ||
| 318 | unsigned int input; | ||
| 319 | int ret; | ||
| 320 | |||
| 321 | ret = sscanf(buf, "%u", &input); | ||
| 322 | if (ret != 1) | ||
| 323 | return -EINVAL; | ||
| 324 | |||
| 325 | mutex_lock(&dbs_mutex); | ||
| 326 | dbs_tuners_ins.io_is_busy = !!input; | ||
| 327 | mutex_unlock(&dbs_mutex); | ||
| 328 | |||
| 329 | return count; | ||
| 330 | } | ||
| 331 | |||
| 302 | static ssize_t store_up_threshold(struct kobject *a, struct attribute *b, | 332 | static ssize_t store_up_threshold(struct kobject *a, struct attribute *b, |
| 303 | const char *buf, size_t count) | 333 | const char *buf, size_t count) |
| 304 | { | 334 | { |
| @@ -381,6 +411,7 @@ static struct global_attr _name = \ | |||
| 381 | __ATTR(_name, 0644, show_##_name, store_##_name) | 411 | __ATTR(_name, 0644, show_##_name, store_##_name) |
| 382 | 412 | ||
| 383 | define_one_rw(sampling_rate); | 413 | define_one_rw(sampling_rate); |
| 414 | define_one_rw(io_is_busy); | ||
| 384 | define_one_rw(up_threshold); | 415 | define_one_rw(up_threshold); |
| 385 | define_one_rw(ignore_nice_load); | 416 | define_one_rw(ignore_nice_load); |
| 386 | define_one_rw(powersave_bias); | 417 | define_one_rw(powersave_bias); |
| @@ -392,6 +423,7 @@ static struct attribute *dbs_attributes[] = { | |||
| 392 | &up_threshold.attr, | 423 | &up_threshold.attr, |
| 393 | &ignore_nice_load.attr, | 424 | &ignore_nice_load.attr, |
| 394 | &powersave_bias.attr, | 425 | &powersave_bias.attr, |
| 426 | &io_is_busy.attr, | ||
| 395 | NULL | 427 | NULL |
| 396 | }; | 428 | }; |
| 397 | 429 | ||
| @@ -470,14 +502,15 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
| 470 | 502 | ||
| 471 | for_each_cpu(j, policy->cpus) { | 503 | for_each_cpu(j, policy->cpus) { |
| 472 | struct cpu_dbs_info_s *j_dbs_info; | 504 | struct cpu_dbs_info_s *j_dbs_info; |
| 473 | cputime64_t cur_wall_time, cur_idle_time; | 505 | cputime64_t cur_wall_time, cur_idle_time, cur_iowait_time; |
| 474 | unsigned int idle_time, wall_time; | 506 | unsigned int idle_time, wall_time, iowait_time; |
| 475 | unsigned int load, load_freq; | 507 | unsigned int load, load_freq; |
| 476 | int freq_avg; | 508 | int freq_avg; |
| 477 | 509 | ||
| 478 | j_dbs_info = &per_cpu(od_cpu_dbs_info, j); | 510 | j_dbs_info = &per_cpu(od_cpu_dbs_info, j); |
| 479 | 511 | ||
| 480 | cur_idle_time = get_cpu_idle_time(j, &cur_wall_time); | 512 | cur_idle_time = get_cpu_idle_time(j, &cur_wall_time); |
| 513 | cur_iowait_time = get_cpu_iowait_time(j, &cur_wall_time); | ||
| 481 | 514 | ||
| 482 | wall_time = (unsigned int) cputime64_sub(cur_wall_time, | 515 | wall_time = (unsigned int) cputime64_sub(cur_wall_time, |
| 483 | j_dbs_info->prev_cpu_wall); | 516 | j_dbs_info->prev_cpu_wall); |
| @@ -487,6 +520,10 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
| 487 | j_dbs_info->prev_cpu_idle); | 520 | j_dbs_info->prev_cpu_idle); |
| 488 | j_dbs_info->prev_cpu_idle = cur_idle_time; | 521 | j_dbs_info->prev_cpu_idle = cur_idle_time; |
| 489 | 522 | ||
| 523 | iowait_time = (unsigned int) cputime64_sub(cur_iowait_time, | ||
| 524 | j_dbs_info->prev_cpu_iowait); | ||
| 525 | j_dbs_info->prev_cpu_iowait = cur_iowait_time; | ||
| 526 | |||
| 490 | if (dbs_tuners_ins.ignore_nice) { | 527 | if (dbs_tuners_ins.ignore_nice) { |
| 491 | cputime64_t cur_nice; | 528 | cputime64_t cur_nice; |
| 492 | unsigned long cur_nice_jiffies; | 529 | unsigned long cur_nice_jiffies; |
| @@ -504,6 +541,16 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
| 504 | idle_time += jiffies_to_usecs(cur_nice_jiffies); | 541 | idle_time += jiffies_to_usecs(cur_nice_jiffies); |
| 505 | } | 542 | } |
| 506 | 543 | ||
| 544 | /* | ||
| 545 | * For the purpose of ondemand, waiting for disk IO is an | ||
| 546 | * indication that you're performance critical, and not that | ||
| 547 | * the system is actually idle. So subtract the iowait time | ||
| 548 | * from the cpu idle time. | ||
| 549 | */ | ||
| 550 | |||
| 551 | if (dbs_tuners_ins.io_is_busy && idle_time >= iowait_time) | ||
| 552 | idle_time -= iowait_time; | ||
| 553 | |||
| 507 | if (unlikely(!wall_time || wall_time < idle_time)) | 554 | if (unlikely(!wall_time || wall_time < idle_time)) |
| 508 | continue; | 555 | continue; |
| 509 | 556 | ||
| @@ -617,6 +664,29 @@ static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) | |||
| 617 | cancel_delayed_work_sync(&dbs_info->work); | 664 | cancel_delayed_work_sync(&dbs_info->work); |
| 618 | } | 665 | } |
| 619 | 666 | ||
| 667 | /* | ||
| 668 | * Not all CPUs want IO time to be accounted as busy; this dependson how | ||
| 669 | * efficient idling at a higher frequency/voltage is. | ||
| 670 | * Pavel Machek says this is not so for various generations of AMD and old | ||
| 671 | * Intel systems. | ||
| 672 | * Mike Chan (androidlcom) calis this is also not true for ARM. | ||
| 673 | * Because of this, whitelist specific known (series) of CPUs by default, and | ||
| 674 | * leave all others up to the user. | ||
| 675 | */ | ||
| 676 | static int should_io_be_busy(void) | ||
| 677 | { | ||
| 678 | #if defined(CONFIG_X86) | ||
| 679 | /* | ||
| 680 | * For Intel, Core 2 (model 15) andl later have an efficient idle. | ||
| 681 | */ | ||
| 682 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && | ||
| 683 | boot_cpu_data.x86 == 6 && | ||
| 684 | boot_cpu_data.x86_model >= 15) | ||
| 685 | return 1; | ||
| 686 | #endif | ||
| 687 | return 0; | ||
| 688 | } | ||
| 689 | |||
| 620 | static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | 690 | static int cpufreq_governor_dbs(struct cpufreq_policy *policy, |
| 621 | unsigned int event) | 691 | unsigned int event) |
| 622 | { | 692 | { |
| @@ -679,6 +749,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 679 | dbs_tuners_ins.sampling_rate = | 749 | dbs_tuners_ins.sampling_rate = |
| 680 | max(min_sampling_rate, | 750 | max(min_sampling_rate, |
| 681 | latency * LATENCY_MULTIPLIER); | 751 | latency * LATENCY_MULTIPLIER); |
| 752 | dbs_tuners_ins.io_is_busy = should_io_be_busy(); | ||
| 682 | } | 753 | } |
| 683 | mutex_unlock(&dbs_mutex); | 754 | mutex_unlock(&dbs_mutex); |
| 684 | 755 | ||
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 2ac4440e7b08..8943b8ccee1a 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c | |||
| @@ -80,12 +80,6 @@ static void do_suspend(void) | |||
| 80 | 80 | ||
| 81 | shutting_down = SHUTDOWN_SUSPEND; | 81 | shutting_down = SHUTDOWN_SUSPEND; |
| 82 | 82 | ||
| 83 | err = stop_machine_create(); | ||
| 84 | if (err) { | ||
| 85 | printk(KERN_ERR "xen suspend: failed to setup stop_machine %d\n", err); | ||
| 86 | goto out; | ||
| 87 | } | ||
| 88 | |||
| 89 | #ifdef CONFIG_PREEMPT | 83 | #ifdef CONFIG_PREEMPT |
| 90 | /* If the kernel is preemptible, we need to freeze all the processes | 84 | /* If the kernel is preemptible, we need to freeze all the processes |
| 91 | to prevent them from being in the middle of a pagetable update | 85 | to prevent them from being in the middle of a pagetable update |
| @@ -93,7 +87,7 @@ static void do_suspend(void) | |||
| 93 | err = freeze_processes(); | 87 | err = freeze_processes(); |
| 94 | if (err) { | 88 | if (err) { |
| 95 | printk(KERN_ERR "xen suspend: freeze failed %d\n", err); | 89 | printk(KERN_ERR "xen suspend: freeze failed %d\n", err); |
| 96 | goto out_destroy_sm; | 90 | goto out; |
| 97 | } | 91 | } |
| 98 | #endif | 92 | #endif |
| 99 | 93 | ||
| @@ -136,12 +130,8 @@ out_resume: | |||
| 136 | out_thaw: | 130 | out_thaw: |
| 137 | #ifdef CONFIG_PREEMPT | 131 | #ifdef CONFIG_PREEMPT |
| 138 | thaw_processes(); | 132 | thaw_processes(); |
| 139 | |||
| 140 | out_destroy_sm: | ||
| 141 | #endif | ||
| 142 | stop_machine_destroy(); | ||
| 143 | |||
| 144 | out: | 133 | out: |
| 134 | #endif | ||
| 145 | shutting_down = SHUTDOWN_INVALID; | 135 | shutting_down = SHUTDOWN_INVALID; |
| 146 | } | 136 | } |
| 147 | #endif /* CONFIG_PM_SLEEP */ | 137 | #endif /* CONFIG_PM_SLEEP */ |
