aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c75
-rw-r--r--drivers/xen/manage.c14
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
74struct cpu_dbs_info_s { 74struct 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
153static 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}
251show_one(sampling_rate, sampling_rate); 263show_one(sampling_rate, sampling_rate);
264show_one(io_is_busy, io_is_busy);
252show_one(up_threshold, up_threshold); 265show_one(up_threshold, up_threshold);
253show_one(ignore_nice_load, ignore_nice); 266show_one(ignore_nice_load, ignore_nice);
254show_one(powersave_bias, powersave_bias); 267show_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
315static 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
302static ssize_t store_up_threshold(struct kobject *a, struct attribute *b, 332static 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
383define_one_rw(sampling_rate); 413define_one_rw(sampling_rate);
414define_one_rw(io_is_busy);
384define_one_rw(up_threshold); 415define_one_rw(up_threshold);
385define_one_rw(ignore_nice_load); 416define_one_rw(ignore_nice_load);
386define_one_rw(powersave_bias); 417define_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 */
676static 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
620static int cpufreq_governor_dbs(struct cpufreq_policy *policy, 690static 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:
136out_thaw: 130out_thaw:
137#ifdef CONFIG_PREEMPT 131#ifdef CONFIG_PREEMPT
138 thaw_processes(); 132 thaw_processes();
139
140out_destroy_sm:
141#endif
142 stop_machine_destroy();
143
144out: 133out:
134#endif
145 shutting_down = SHUTDOWN_INVALID; 135 shutting_down = SHUTDOWN_INVALID;
146} 136}
147#endif /* CONFIG_PM_SLEEP */ 137#endif /* CONFIG_PM_SLEEP */