aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/cpufreq_ondemand.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2009-08-14 01:41:02 -0400
committerTejun Heo <tj@kernel.org>2009-08-14 01:45:31 -0400
commit384be2b18a5f9475eab9ca2bdfa95cc1a04ef59c (patch)
tree04c93f391a1b65c8bf8d7ba8643c07d26c26590a /drivers/cpufreq/cpufreq_ondemand.c
parenta76761b621bcd8336065c4fe3a74f046858bc34c (diff)
parent142d44b0dd6741a64a7bdbe029110e7c1dcf1d23 (diff)
Merge branch 'percpu-for-linus' into percpu-for-next
Conflicts: arch/sparc/kernel/smp_64.c arch/x86/kernel/cpu/perf_counter.c arch/x86/kernel/setup_percpu.c drivers/cpufreq/cpufreq_ondemand.c mm/percpu.c Conflicts in core and arch percpu codes are mostly from commit ed78e1e078dd44249f88b1dd8c76dafb39567161 which substituted many num_possible_cpus() with nr_cpu_ids. As for-next branch has moved all the first chunk allocators into mm/percpu.c, the changes are moved from arch code to mm/percpu.c. Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'drivers/cpufreq/cpufreq_ondemand.c')
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c77
1 files changed, 32 insertions, 45 deletions
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 36f292a7bd01..d7a528c80de8 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -70,23 +70,21 @@ struct cpu_dbs_info_s {
70 unsigned int freq_lo_jiffies; 70 unsigned int freq_lo_jiffies;
71 unsigned int freq_hi_jiffies; 71 unsigned int freq_hi_jiffies;
72 int cpu; 72 int cpu;
73 unsigned int enable:1, 73 unsigned int sample_type:1;
74 sample_type:1; 74 /*
75 * percpu mutex that serializes governor limit change with
76 * do_dbs_timer invocation. We do not want do_dbs_timer to run
77 * when user is changing the governor or limits.
78 */
79 struct mutex timer_mutex;
75}; 80};
76static DEFINE_PER_CPU(struct cpu_dbs_info_s, od_cpu_dbs_info); 81static DEFINE_PER_CPU(struct cpu_dbs_info_s, od_cpu_dbs_info);
77 82
78static unsigned int dbs_enable; /* number of CPUs using this policy */ 83static unsigned int dbs_enable; /* number of CPUs using this policy */
79 84
80/* 85/*
81 * DEADLOCK ALERT! There is a ordering requirement between cpu_hotplug 86 * dbs_mutex protects data in dbs_tuners_ins from concurrent changes on
82 * lock and dbs_mutex. cpu_hotplug lock should always be held before 87 * different CPUs. It protects dbs_enable in governor start/stop.
83 * dbs_mutex. If any function that can potentially take cpu_hotplug lock
84 * (like __cpufreq_driver_target()) is being called with dbs_mutex taken, then
85 * cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock
86 * is recursive for the same process. -Venki
87 * DEADLOCK ALERT! (2) : do_dbs_timer() must not take the dbs_mutex, because it
88 * would deadlock with cancel_delayed_work_sync(), which is needed for proper
89 * raceless workqueue teardown.
90 */ 88 */
91static DEFINE_MUTEX(dbs_mutex); 89static DEFINE_MUTEX(dbs_mutex);
92 90
@@ -193,13 +191,18 @@ static unsigned int powersave_bias_target(struct cpufreq_policy *policy,
193 return freq_hi; 191 return freq_hi;
194} 192}
195 193
194static void ondemand_powersave_bias_init_cpu(int cpu)
195{
196 struct cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
197 dbs_info->freq_table = cpufreq_frequency_get_table(cpu);
198 dbs_info->freq_lo = 0;
199}
200
196static void ondemand_powersave_bias_init(void) 201static void ondemand_powersave_bias_init(void)
197{ 202{
198 int i; 203 int i;
199 for_each_online_cpu(i) { 204 for_each_online_cpu(i) {
200 struct cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, i); 205 ondemand_powersave_bias_init_cpu(i);
201 dbs_info->freq_table = cpufreq_frequency_get_table(i);
202 dbs_info->freq_lo = 0;
203 } 206 }
204} 207}
205 208
@@ -241,12 +244,10 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
241 unsigned int input; 244 unsigned int input;
242 int ret; 245 int ret;
243 ret = sscanf(buf, "%u", &input); 246 ret = sscanf(buf, "%u", &input);
247 if (ret != 1)
248 return -EINVAL;
244 249
245 mutex_lock(&dbs_mutex); 250 mutex_lock(&dbs_mutex);
246 if (ret != 1) {
247 mutex_unlock(&dbs_mutex);
248 return -EINVAL;
249 }
250 dbs_tuners_ins.sampling_rate = max(input, min_sampling_rate); 251 dbs_tuners_ins.sampling_rate = max(input, min_sampling_rate);
251 mutex_unlock(&dbs_mutex); 252 mutex_unlock(&dbs_mutex);
252 253
@@ -260,13 +261,12 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused,
260 int ret; 261 int ret;
261 ret = sscanf(buf, "%u", &input); 262 ret = sscanf(buf, "%u", &input);
262 263
263 mutex_lock(&dbs_mutex);
264 if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || 264 if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD ||
265 input < MIN_FREQUENCY_UP_THRESHOLD) { 265 input < MIN_FREQUENCY_UP_THRESHOLD) {
266 mutex_unlock(&dbs_mutex);
267 return -EINVAL; 266 return -EINVAL;
268 } 267 }
269 268
269 mutex_lock(&dbs_mutex);
270 dbs_tuners_ins.up_threshold = input; 270 dbs_tuners_ins.up_threshold = input;
271 mutex_unlock(&dbs_mutex); 271 mutex_unlock(&dbs_mutex);
272 272
@@ -364,9 +364,6 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
364 struct cpufreq_policy *policy; 364 struct cpufreq_policy *policy;
365 unsigned int j; 365 unsigned int j;
366 366
367 if (!this_dbs_info->enable)
368 return;
369
370 this_dbs_info->freq_lo = 0; 367 this_dbs_info->freq_lo = 0;
371 policy = this_dbs_info->cur_policy; 368 policy = this_dbs_info->cur_policy;
372 369
@@ -494,14 +491,7 @@ static void do_dbs_timer(struct work_struct *work)
494 int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); 491 int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
495 492
496 delay -= jiffies % delay; 493 delay -= jiffies % delay;
497 494 mutex_lock(&dbs_info->timer_mutex);
498 if (lock_policy_rwsem_write(cpu) < 0)
499 return;
500
501 if (!dbs_info->enable) {
502 unlock_policy_rwsem_write(cpu);
503 return;
504 }
505 495
506 /* Common NORMAL_SAMPLE setup */ 496 /* Common NORMAL_SAMPLE setup */
507 dbs_info->sample_type = DBS_NORMAL_SAMPLE; 497 dbs_info->sample_type = DBS_NORMAL_SAMPLE;
@@ -518,7 +508,7 @@ static void do_dbs_timer(struct work_struct *work)
518 dbs_info->freq_lo, CPUFREQ_RELATION_H); 508 dbs_info->freq_lo, CPUFREQ_RELATION_H);
519 } 509 }
520 queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, delay); 510 queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, delay);
521 unlock_policy_rwsem_write(cpu); 511 mutex_unlock(&dbs_info->timer_mutex);
522} 512}
523 513
524static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) 514static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
@@ -527,8 +517,6 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
527 int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); 517 int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
528 delay -= jiffies % delay; 518 delay -= jiffies % delay;
529 519
530 dbs_info->enable = 1;
531 ondemand_powersave_bias_init();
532 dbs_info->sample_type = DBS_NORMAL_SAMPLE; 520 dbs_info->sample_type = DBS_NORMAL_SAMPLE;
533 INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); 521 INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer);
534 queue_delayed_work_on(dbs_info->cpu, kondemand_wq, &dbs_info->work, 522 queue_delayed_work_on(dbs_info->cpu, kondemand_wq, &dbs_info->work,
@@ -537,7 +525,6 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
537 525
538static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) 526static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
539{ 527{
540 dbs_info->enable = 0;
541 cancel_delayed_work_sync(&dbs_info->work); 528 cancel_delayed_work_sync(&dbs_info->work);
542} 529}
543 530
@@ -556,19 +543,15 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
556 if ((!cpu_online(cpu)) || (!policy->cur)) 543 if ((!cpu_online(cpu)) || (!policy->cur))
557 return -EINVAL; 544 return -EINVAL;
558 545
559 if (this_dbs_info->enable) /* Already enabled */
560 break;
561
562 mutex_lock(&dbs_mutex); 546 mutex_lock(&dbs_mutex);
563 dbs_enable++;
564 547
565 rc = sysfs_create_group(&policy->kobj, &dbs_attr_group); 548 rc = sysfs_create_group(&policy->kobj, &dbs_attr_group);
566 if (rc) { 549 if (rc) {
567 dbs_enable--;
568 mutex_unlock(&dbs_mutex); 550 mutex_unlock(&dbs_mutex);
569 return rc; 551 return rc;
570 } 552 }
571 553
554 dbs_enable++;
572 for_each_cpu(j, policy->cpus) { 555 for_each_cpu(j, policy->cpus) {
573 struct cpu_dbs_info_s *j_dbs_info; 556 struct cpu_dbs_info_s *j_dbs_info;
574 j_dbs_info = &per_cpu(od_cpu_dbs_info, j); 557 j_dbs_info = &per_cpu(od_cpu_dbs_info, j);
@@ -582,6 +565,8 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
582 } 565 }
583 } 566 }
584 this_dbs_info->cpu = cpu; 567 this_dbs_info->cpu = cpu;
568 ondemand_powersave_bias_init_cpu(cpu);
569 mutex_init(&this_dbs_info->timer_mutex);
585 /* 570 /*
586 * Start the timerschedule work, when this governor 571 * Start the timerschedule work, when this governor
587 * is used for first time 572 * is used for first time
@@ -599,29 +584,31 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
599 max(min_sampling_rate, 584 max(min_sampling_rate,
600 latency * LATENCY_MULTIPLIER); 585 latency * LATENCY_MULTIPLIER);
601 } 586 }
602 dbs_timer_init(this_dbs_info);
603
604 mutex_unlock(&dbs_mutex); 587 mutex_unlock(&dbs_mutex);
588
589 dbs_timer_init(this_dbs_info);
605 break; 590 break;
606 591
607 case CPUFREQ_GOV_STOP: 592 case CPUFREQ_GOV_STOP:
608 mutex_lock(&dbs_mutex);
609 dbs_timer_exit(this_dbs_info); 593 dbs_timer_exit(this_dbs_info);
594
595 mutex_lock(&dbs_mutex);
610 sysfs_remove_group(&policy->kobj, &dbs_attr_group); 596 sysfs_remove_group(&policy->kobj, &dbs_attr_group);
597 mutex_destroy(&this_dbs_info->timer_mutex);
611 dbs_enable--; 598 dbs_enable--;
612 mutex_unlock(&dbs_mutex); 599 mutex_unlock(&dbs_mutex);
613 600
614 break; 601 break;
615 602
616 case CPUFREQ_GOV_LIMITS: 603 case CPUFREQ_GOV_LIMITS:
617 mutex_lock(&dbs_mutex); 604 mutex_lock(&this_dbs_info->timer_mutex);
618 if (policy->max < this_dbs_info->cur_policy->cur) 605 if (policy->max < this_dbs_info->cur_policy->cur)
619 __cpufreq_driver_target(this_dbs_info->cur_policy, 606 __cpufreq_driver_target(this_dbs_info->cur_policy,
620 policy->max, CPUFREQ_RELATION_H); 607 policy->max, CPUFREQ_RELATION_H);
621 else if (policy->min > this_dbs_info->cur_policy->cur) 608 else if (policy->min > this_dbs_info->cur_policy->cur)
622 __cpufreq_driver_target(this_dbs_info->cur_policy, 609 __cpufreq_driver_target(this_dbs_info->cur_policy,
623 policy->min, CPUFREQ_RELATION_L); 610 policy->min, CPUFREQ_RELATION_L);
624 mutex_unlock(&dbs_mutex); 611 mutex_unlock(&this_dbs_info->timer_mutex);
625 break; 612 break;
626 } 613 }
627 return 0; 614 return 0;