[CPUFREQ] remove rwsem lock from CPUFREQ_GOV_STOP call (second call site)
remove rwsem lock from CPUFREQ_GOV_STOP call (second call site)
commit 42a06f2166
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>
This commit is contained in:
Родитель
0e625ac153
Коммит
395913d0b1
|
@ -61,6 +61,8 @@ static DEFINE_SPINLOCK(cpufreq_driver_lock);
|
||||||
* are concerned with are online after they get the lock.
|
* are concerned with are online after they get the lock.
|
||||||
* - Governor routines that can be called in cpufreq hotplug path should not
|
* - Governor routines that can be called in cpufreq hotplug path should not
|
||||||
* take this sem as top level hotplug notifier handler takes this.
|
* take this sem as top level hotplug notifier handler takes this.
|
||||||
|
* - Lock should not be held across
|
||||||
|
* __cpufreq_governor(data, CPUFREQ_GOV_STOP);
|
||||||
*/
|
*/
|
||||||
static DEFINE_PER_CPU(int, policy_cpu);
|
static DEFINE_PER_CPU(int, policy_cpu);
|
||||||
static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem);
|
static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem);
|
||||||
|
@ -1707,8 +1709,17 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
|
||||||
dprintk("governor switch\n");
|
dprintk("governor switch\n");
|
||||||
|
|
||||||
/* end old governor */
|
/* end old governor */
|
||||||
if (data->governor)
|
if (data->governor) {
|
||||||
|
/*
|
||||||
|
* Need to release the rwsem around governor
|
||||||
|
* stop due to lock dependency between
|
||||||
|
* cancel_delayed_work_sync and the read lock
|
||||||
|
* taken in the delayed work handler.
|
||||||
|
*/
|
||||||
|
unlock_policy_rwsem_write(data->cpu);
|
||||||
__cpufreq_governor(data, CPUFREQ_GOV_STOP);
|
__cpufreq_governor(data, CPUFREQ_GOV_STOP);
|
||||||
|
lock_policy_rwsem_write(data->cpu);
|
||||||
|
}
|
||||||
|
|
||||||
/* start new governor */
|
/* start new governor */
|
||||||
data->governor = policy->governor;
|
data->governor = policy->governor;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче