mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 13:14:07 +08:00
cpufreq: Drop rwsem lock around CPUFREQ_GOV_POLICY_EXIT
With the rwsem lock around __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT), we get circular dependency when we call sysfs_remove_group(). ====================================================== [ INFO: possible circular locking dependency detected ] 3.9.0-rc7+ #15 Not tainted ------------------------------------------------------- cat/2387 is trying to acquire lock: (&per_cpu(cpu_policy_rwsem, cpu)){+++++.}, at: [<c02f6179>] lock_policy_rwsem_read+0x25/0x34 but task is already holding lock: (s_active#41){++++.+}, at: [<c00f9bf7>] sysfs_read_file+0x4f/0xcc which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (s_active#41){++++.+}: [<c0055a79>] lock_acquire+0x61/0xbc [<c00fabf1>] sysfs_addrm_finish+0xc1/0x128 [<c00f9819>] sysfs_hash_and_remove+0x35/0x64 [<c00fbe6f>] remove_files.isra.0+0x1b/0x24 [<c00fbea5>] sysfs_remove_group+0x2d/0xa8 [<c02f9a0b>] cpufreq_governor_interactive+0x13b/0x35c [<c02f61df>] __cpufreq_governor+0x2b/0x8c [<c02f6579>] __cpufreq_set_policy+0xa9/0xf8 [<c02f6b75>] store_scaling_governor+0x61/0x100 [<c02f6f4d>] store+0x39/0x60 [<c00f9b81>] sysfs_write_file+0xed/0x114 [<c00b3fd1>] vfs_write+0x65/0xd8 [<c00b424b>] sys_write+0x2f/0x50 [<c000cdc1>] ret_fast_syscall+0x1/0x52 -> #0 (&per_cpu(cpu_policy_rwsem, cpu)){+++++.}: [<c0055253>] __lock_acquire+0xef3/0x13dc [<c0055a79>] lock_acquire+0x61/0xbc [<c03ee1f5>] down_read+0x25/0x30 [<c02f6179>] lock_policy_rwsem_read+0x25/0x34 [<c02f6edd>] show+0x21/0x58 [<c00f9c0f>] sysfs_read_file+0x67/0xcc [<c00b40a7>] vfs_read+0x63/0xd8 [<c00b41fb>] sys_read+0x2f/0x50 [<c000cdc1>] ret_fast_syscall+0x1/0x52 other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(s_active#41); lock(&per_cpu(cpu_policy_rwsem, cpu)); lock(s_active#41); lock(&per_cpu(cpu_policy_rwsem, cpu)); *** DEADLOCK *** 2 locks held by cat/2387: #0: (&buffer->mutex){+.+.+.}, at: [<c00f9bcd>] sysfs_read_file+0x25/0xcc #1: (s_active#41){++++.+}, at: [<c00f9bf7>] sysfs_read_file+0x4f/0xcc stack backtrace: [<c0011d55>] (unwind_backtrace+0x1/0x9c) from [<c03e9a09>] (print_circular_bug+0x19d/0x1e8) [<c03e9a09>] (print_circular_bug+0x19d/0x1e8) from [<c0055253>] (__lock_acquire+0xef3/0x13dc) [<c0055253>] (__lock_acquire+0xef3/0x13dc) from [<c0055a79>] (lock_acquire+0x61/0xbc) [<c0055a79>] (lock_acquire+0x61/0xbc) from [<c03ee1f5>] (down_read+0x25/0x30) [<c03ee1f5>] (down_read+0x25/0x30) from [<c02f6179>] (lock_policy_rwsem_read+0x25/0x34) [<c02f6179>] (lock_policy_rwsem_read+0x25/0x34) from [<c02f6edd>] (show+0x21/0x58) [<c02f6edd>] (show+0x21/0x58) from [<c00f9c0f>] (sysfs_read_file+0x67/0xcc) [<c00f9c0f>] (sysfs_read_file+0x67/0xcc) from [<c00b40a7>] (vfs_read+0x63/0xd8) [<c00b40a7>] (vfs_read+0x63/0xd8) from [<c00b41fb>] (sys_read+0x2f/0x50) [<c00b41fb>] (sys_read+0x2f/0x50) from [<c000cdc1>] (ret_fast_syscall+0x1/0x52) This lock isn't required while calling __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT). Remove it. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
c7788792a5
commit
955ef48335
@ -1729,18 +1729,23 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
|
||||
/* end old governor */
|
||||
if (data->governor) {
|
||||
__cpufreq_governor(data, CPUFREQ_GOV_STOP);
|
||||
unlock_policy_rwsem_write(policy->cpu);
|
||||
__cpufreq_governor(data,
|
||||
CPUFREQ_GOV_POLICY_EXIT);
|
||||
lock_policy_rwsem_write(policy->cpu);
|
||||
}
|
||||
|
||||
/* start new governor */
|
||||
data->governor = policy->governor;
|
||||
if (!__cpufreq_governor(data, CPUFREQ_GOV_POLICY_INIT)) {
|
||||
if (!__cpufreq_governor(data, CPUFREQ_GOV_START))
|
||||
if (!__cpufreq_governor(data, CPUFREQ_GOV_START)) {
|
||||
failed = 0;
|
||||
else
|
||||
} else {
|
||||
unlock_policy_rwsem_write(policy->cpu);
|
||||
__cpufreq_governor(data,
|
||||
CPUFREQ_GOV_POLICY_EXIT);
|
||||
lock_policy_rwsem_write(policy->cpu);
|
||||
}
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
|
Loading…
Reference in New Issue
Block a user