X-Git-Url: http://bbs.cooldavid.org/git/?a=blobdiff_plain;f=drivers%2Fcpufreq%2Fcpufreq.c;h=3938c7817095d0747a44045b51cff3c680e6e78a;hb=395913d0b1db37092ea3d9d69b832183b1dd84c5;hp=4da28444b23559e28028cfa2f517993f41071520;hpb=0e625ac153126a0a62b7635fa9dc91f87ff39e38;p=net-next-2.6.git diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 4da28444b23..3938c781709 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -61,6 +61,8 @@ static DEFINE_SPINLOCK(cpufreq_driver_lock); * are concerned with are online after they get the lock. * - Governor routines that can be called in cpufreq hotplug path should not * 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(struct rw_semaphore, cpu_policy_rwsem); @@ -1707,8 +1709,17 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, dprintk("governor switch\n"); /* 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); + lock_policy_rwsem_write(data->cpu); + } /* start new governor */ data->governor = policy->governor;