diff options
author | venkatesh.pallipadi@intel.com <venkatesh.pallipadi@intel.com> | 2009-07-02 20:08:30 -0400 |
---|---|---|
committer | Dave Jones <davej@redhat.com> | 2009-07-06 21:38:27 -0400 |
commit | 7d26e2d5e2da37e92c6c7644b26b294dedd8c982 (patch) | |
tree | 44d1637ac603fad42cbbf28ba7a89c9e194c4d0f /drivers/cpufreq/cpufreq_conservative.c | |
parent | faf80d62e44dc627efb741f48db50c1858d1667c (diff) |
[CPUFREQ] Eliminate the recent lockdep warnings in cpufreq
Commit b14893a62c73af0eca414cfed505b8c09efc613c although it was very
much needed to properly cleanup ondemand timer, opened-up a can of worms
related to locking dependencies in cpufreq.
Patch here defines the need for dbs_mutex and cleans up its usage in
ondemand governor. This also resolves the lockdep warnings reported here
http://lkml.indiana.edu/hypermail/linux/kernel/0906.1/01925.html
http://lkml.indiana.edu/hypermail/linux/kernel/0907.0/00820.html
and few others..
Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Dave Jones <davej@redhat.com>
Diffstat (limited to 'drivers/cpufreq/cpufreq_conservative.c')
-rw-r--r-- | drivers/cpufreq/cpufreq_conservative.c | 27 |
1 files changed, 11 insertions, 16 deletions
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 7fc58af748b4..58889f26029a 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c | |||
@@ -70,15 +70,10 @@ static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); | |||
70 | static unsigned int dbs_enable; /* number of CPUs using this policy */ | 70 | static unsigned int dbs_enable; /* number of CPUs using this policy */ |
71 | 71 | ||
72 | /* | 72 | /* |
73 | * DEADLOCK ALERT! There is a ordering requirement between cpu_hotplug | 73 | * dbs_mutex protects data in dbs_tuners_ins from concurrent changes on |
74 | * lock and dbs_mutex. cpu_hotplug lock should always be held before | 74 | * different CPUs. It protects dbs_enable in governor start/stop. It also |
75 | * dbs_mutex. If any function that can potentially take cpu_hotplug lock | 75 | * serializes governor limit_change with do_dbs_timer. We do not want |
76 | * (like __cpufreq_driver_target()) is being called with dbs_mutex taken, then | 76 | * do_dbs_timer to run when user is changing the governor or limits. |
77 | * cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock | ||
78 | * is recursive for the same process. -Venki | ||
79 | * DEADLOCK ALERT! (2) : do_dbs_timer() must not take the dbs_mutex, because it | ||
80 | * would deadlock with cancel_delayed_work_sync(), which is needed for proper | ||
81 | * raceless workqueue teardown. | ||
82 | */ | 77 | */ |
83 | static DEFINE_MUTEX(dbs_mutex); | 78 | static DEFINE_MUTEX(dbs_mutex); |
84 | 79 | ||
@@ -488,18 +483,17 @@ static void do_dbs_timer(struct work_struct *work) | |||
488 | 483 | ||
489 | delay -= jiffies % delay; | 484 | delay -= jiffies % delay; |
490 | 485 | ||
491 | if (lock_policy_rwsem_write(cpu) < 0) | 486 | mutex_lock(&dbs_mutex); |
492 | return; | ||
493 | 487 | ||
494 | if (!dbs_info->enable) { | 488 | if (!dbs_info->enable) { |
495 | unlock_policy_rwsem_write(cpu); | 489 | mutex_unlock(&dbs_mutex); |
496 | return; | 490 | return; |
497 | } | 491 | } |
498 | 492 | ||
499 | dbs_check_cpu(dbs_info); | 493 | dbs_check_cpu(dbs_info); |
500 | 494 | ||
501 | queue_delayed_work_on(cpu, kconservative_wq, &dbs_info->work, delay); | 495 | queue_delayed_work_on(cpu, kconservative_wq, &dbs_info->work, delay); |
502 | unlock_policy_rwsem_write(cpu); | 496 | mutex_unlock(&dbs_mutex); |
503 | } | 497 | } |
504 | 498 | ||
505 | static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) | 499 | static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) |
@@ -590,15 +584,16 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
590 | &dbs_cpufreq_notifier_block, | 584 | &dbs_cpufreq_notifier_block, |
591 | CPUFREQ_TRANSITION_NOTIFIER); | 585 | CPUFREQ_TRANSITION_NOTIFIER); |
592 | } | 586 | } |
593 | dbs_timer_init(this_dbs_info); | ||
594 | |||
595 | mutex_unlock(&dbs_mutex); | 587 | mutex_unlock(&dbs_mutex); |
596 | 588 | ||
589 | dbs_timer_init(this_dbs_info); | ||
590 | |||
597 | break; | 591 | break; |
598 | 592 | ||
599 | case CPUFREQ_GOV_STOP: | 593 | case CPUFREQ_GOV_STOP: |
600 | mutex_lock(&dbs_mutex); | ||
601 | dbs_timer_exit(this_dbs_info); | 594 | dbs_timer_exit(this_dbs_info); |
595 | |||
596 | mutex_lock(&dbs_mutex); | ||
602 | sysfs_remove_group(&policy->kobj, &dbs_attr_group); | 597 | sysfs_remove_group(&policy->kobj, &dbs_attr_group); |
603 | dbs_enable--; | 598 | dbs_enable--; |
604 | 599 | ||