diff options
| -rw-r--r-- | drivers/cpufreq/cpufreq_conservative.c | 34 |
1 files changed, 13 insertions, 21 deletions
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 58889f26029a..57490502b21c 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c | |||
| @@ -63,7 +63,12 @@ struct cpu_dbs_info_s { | |||
| 63 | unsigned int down_skip; | 63 | unsigned int down_skip; |
| 64 | unsigned int requested_freq; | 64 | unsigned int requested_freq; |
| 65 | int cpu; | 65 | int cpu; |
| 66 | unsigned int enable:1; | 66 | /* |
| 67 | * percpu mutex that serializes governor limit change with | ||
| 68 | * do_dbs_timer invocation. We do not want do_dbs_timer to run | ||
| 69 | * when user is changing the governor or limits. | ||
| 70 | */ | ||
| 71 | struct mutex timer_mutex; | ||
| 67 | }; | 72 | }; |
| 68 | static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); | 73 | static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); |
| 69 | 74 | ||
| @@ -71,9 +76,7 @@ static unsigned int dbs_enable; /* number of CPUs using this policy */ | |||
| 71 | 76 | ||
| 72 | /* | 77 | /* |
| 73 | * dbs_mutex protects data in dbs_tuners_ins from concurrent changes on | 78 | * dbs_mutex protects data in dbs_tuners_ins from concurrent changes on |
| 74 | * different CPUs. It protects dbs_enable in governor start/stop. It also | 79 | * different CPUs. It protects dbs_enable in governor start/stop. |
| 75 | * serializes governor limit_change with do_dbs_timer. We do not want | ||
| 76 | * do_dbs_timer to run when user is changing the governor or limits. | ||
| 77 | */ | 80 | */ |
| 78 | static DEFINE_MUTEX(dbs_mutex); | 81 | static DEFINE_MUTEX(dbs_mutex); |
| 79 | 82 | ||
| @@ -138,9 +141,6 @@ dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val, | |||
| 138 | 141 | ||
| 139 | struct cpufreq_policy *policy; | 142 | struct cpufreq_policy *policy; |
| 140 | 143 | ||
| 141 | if (!this_dbs_info->enable) | ||
| 142 | return 0; | ||
| 143 | |||
| 144 | policy = this_dbs_info->cur_policy; | 144 | policy = this_dbs_info->cur_policy; |
| 145 | 145 | ||
| 146 | /* | 146 | /* |
| @@ -483,17 +483,12 @@ static void do_dbs_timer(struct work_struct *work) | |||
| 483 | 483 | ||
| 484 | delay -= jiffies % delay; | 484 | delay -= jiffies % delay; |
| 485 | 485 | ||
| 486 | mutex_lock(&dbs_mutex); | 486 | mutex_lock(&dbs_info->timer_mutex); |
| 487 | |||
| 488 | if (!dbs_info->enable) { | ||
| 489 | mutex_unlock(&dbs_mutex); | ||
| 490 | return; | ||
| 491 | } | ||
| 492 | 487 | ||
| 493 | dbs_check_cpu(dbs_info); | 488 | dbs_check_cpu(dbs_info); |
| 494 | 489 | ||
| 495 | queue_delayed_work_on(cpu, kconservative_wq, &dbs_info->work, delay); | 490 | queue_delayed_work_on(cpu, kconservative_wq, &dbs_info->work, delay); |
| 496 | mutex_unlock(&dbs_mutex); | 491 | mutex_unlock(&dbs_info->timer_mutex); |
| 497 | } | 492 | } |
| 498 | 493 | ||
| 499 | static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) | 494 | static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) |
| @@ -502,7 +497,6 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) | |||
| 502 | int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); | 497 | int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); |
| 503 | delay -= jiffies % delay; | 498 | delay -= jiffies % delay; |
| 504 | 499 | ||
| 505 | dbs_info->enable = 1; | ||
| 506 | INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); | 500 | INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); |
| 507 | queue_delayed_work_on(dbs_info->cpu, kconservative_wq, &dbs_info->work, | 501 | queue_delayed_work_on(dbs_info->cpu, kconservative_wq, &dbs_info->work, |
| 508 | delay); | 502 | delay); |
| @@ -510,7 +504,6 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) | |||
| 510 | 504 | ||
| 511 | static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) | 505 | static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) |
| 512 | { | 506 | { |
| 513 | dbs_info->enable = 0; | ||
| 514 | cancel_delayed_work_sync(&dbs_info->work); | 507 | cancel_delayed_work_sync(&dbs_info->work); |
| 515 | } | 508 | } |
| 516 | 509 | ||
| @@ -529,9 +522,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 529 | if ((!cpu_online(cpu)) || (!policy->cur)) | 522 | if ((!cpu_online(cpu)) || (!policy->cur)) |
| 530 | return -EINVAL; | 523 | return -EINVAL; |
| 531 | 524 | ||
| 532 | if (this_dbs_info->enable) /* Already enabled */ | ||
| 533 | break; | ||
| 534 | |||
| 535 | mutex_lock(&dbs_mutex); | 525 | mutex_lock(&dbs_mutex); |
| 536 | 526 | ||
| 537 | rc = sysfs_create_group(&policy->kobj, &dbs_attr_group); | 527 | rc = sysfs_create_group(&policy->kobj, &dbs_attr_group); |
| @@ -555,6 +545,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 555 | this_dbs_info->down_skip = 0; | 545 | this_dbs_info->down_skip = 0; |
| 556 | this_dbs_info->requested_freq = policy->cur; | 546 | this_dbs_info->requested_freq = policy->cur; |
| 557 | 547 | ||
| 548 | mutex_init(&this_dbs_info->timer_mutex); | ||
| 558 | dbs_enable++; | 549 | dbs_enable++; |
| 559 | /* | 550 | /* |
| 560 | * Start the timerschedule work, when this governor | 551 | * Start the timerschedule work, when this governor |
| @@ -596,6 +587,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 596 | mutex_lock(&dbs_mutex); | 587 | mutex_lock(&dbs_mutex); |
| 597 | sysfs_remove_group(&policy->kobj, &dbs_attr_group); | 588 | sysfs_remove_group(&policy->kobj, &dbs_attr_group); |
| 598 | dbs_enable--; | 589 | dbs_enable--; |
| 590 | mutex_destroy(&this_dbs_info->timer_mutex); | ||
| 599 | 591 | ||
| 600 | /* | 592 | /* |
| 601 | * Stop the timerschedule work, when this governor | 593 | * Stop the timerschedule work, when this governor |
| @@ -611,7 +603,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 611 | break; | 603 | break; |
| 612 | 604 | ||
| 613 | case CPUFREQ_GOV_LIMITS: | 605 | case CPUFREQ_GOV_LIMITS: |
| 614 | mutex_lock(&dbs_mutex); | 606 | mutex_lock(&this_dbs_info->timer_mutex); |
| 615 | if (policy->max < this_dbs_info->cur_policy->cur) | 607 | if (policy->max < this_dbs_info->cur_policy->cur) |
| 616 | __cpufreq_driver_target( | 608 | __cpufreq_driver_target( |
| 617 | this_dbs_info->cur_policy, | 609 | this_dbs_info->cur_policy, |
| @@ -620,7 +612,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 620 | __cpufreq_driver_target( | 612 | __cpufreq_driver_target( |
| 621 | this_dbs_info->cur_policy, | 613 | this_dbs_info->cur_policy, |
| 622 | policy->min, CPUFREQ_RELATION_L); | 614 | policy->min, CPUFREQ_RELATION_L); |
| 623 | mutex_unlock(&dbs_mutex); | 615 | mutex_unlock(&this_dbs_info->timer_mutex); |
| 624 | 616 | ||
| 625 | break; | 617 | break; |
| 626 | } | 618 | } |
