diff options
| author | Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> | 2009-06-08 13:17:31 -0400 |
|---|---|---|
| committer | Dave Jones <davej@redhat.com> | 2009-09-01 12:45:18 -0400 |
| commit | 395913d0b1db37092ea3d9d69b832183b1dd84c5 (patch) | |
| tree | 2b1aff8df27bfb02332ee4fe207a989244583c0a | |
| parent | 0e625ac153126a0a62b7635fa9dc91f87ff39e38 (diff) | |
[CPUFREQ] remove rwsem lock from CPUFREQ_GOV_STOP call (second call site)
remove rwsem lock from CPUFREQ_GOV_STOP call (second call site)
commit 42a06f2166f2f6f7bf04f32b4e823eacdceafdc9
Missed a call site for CPUFREQ_GOV_STOP to remove the rwlock taken around the
teardown. To make a long story short, the rwlock write-lock causes a circular
dependency with cancel_delayed_work_sync(), because the timer handler takes the
read lock.
Note that all callers to __cpufreq_set_policy are taking the rwsem. All sysfs
callers (writers) hold the write rwsem at the earliest sysfs calling stage.
However, the rwlock write-lock is not needed upon governor stop.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Acked-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
CC: rjw@sisk.pl
CC: mingo@elte.hu
CC: Shaohua Li <shaohua.li@intel.com>
CC: Pekka Enberg <penberg@cs.helsinki.fi>
CC: Dave Young <hidave.darkstar@gmail.com>
CC: "Rafael J. Wysocki" <rjw@sisk.pl>
CC: Rusty Russell <rusty@rustcorp.com.au>
CC: trenn@suse.de
CC: sven.wegener@stealer.net
CC: cpufreq@vger.kernel.org
Signed-off-by: Dave Jones <davej@redhat.com>
| -rw-r--r-- | drivers/cpufreq/cpufreq.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 4da28444b235..3938c7817095 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
| @@ -61,6 +61,8 @@ static DEFINE_SPINLOCK(cpufreq_driver_lock); | |||
| 61 | * are concerned with are online after they get the lock. | 61 | * are concerned with are online after they get the lock. |
| 62 | * - Governor routines that can be called in cpufreq hotplug path should not | 62 | * - Governor routines that can be called in cpufreq hotplug path should not |
| 63 | * take this sem as top level hotplug notifier handler takes this. | 63 | * take this sem as top level hotplug notifier handler takes this. |
| 64 | * - Lock should not be held across | ||
| 65 | * __cpufreq_governor(data, CPUFREQ_GOV_STOP); | ||
| 64 | */ | 66 | */ |
| 65 | static DEFINE_PER_CPU(int, policy_cpu); | 67 | static DEFINE_PER_CPU(int, policy_cpu); |
| 66 | static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem); | 68 | static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem); |
| @@ -1707,8 +1709,17 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, | |||
| 1707 | dprintk("governor switch\n"); | 1709 | dprintk("governor switch\n"); |
| 1708 | 1710 | ||
| 1709 | /* end old governor */ | 1711 | /* end old governor */ |
| 1710 | if (data->governor) | 1712 | if (data->governor) { |
| 1713 | /* | ||
| 1714 | * Need to release the rwsem around governor | ||
| 1715 | * stop due to lock dependency between | ||
| 1716 | * cancel_delayed_work_sync and the read lock | ||
| 1717 | * taken in the delayed work handler. | ||
| 1718 | */ | ||
| 1719 | unlock_policy_rwsem_write(data->cpu); | ||
| 1711 | __cpufreq_governor(data, CPUFREQ_GOV_STOP); | 1720 | __cpufreq_governor(data, CPUFREQ_GOV_STOP); |
| 1721 | lock_policy_rwsem_write(data->cpu); | ||
| 1722 | } | ||
| 1712 | 1723 | ||
| 1713 | /* start new governor */ | 1724 | /* start new governor */ |
| 1714 | data->governor = policy->governor; | 1725 | data->governor = policy->governor; |
