Eliad Peller
fe20b39ec3
cfg80211: fix potential deadlock in regulatory
...
reg_timeout_work() calls restore_regulatory_settings() which
takes cfg80211_mutex.
reg_set_request_processed() already holds cfg80211_mutex
before calling cancel_delayed_work_sync(reg_timeout),
so it might deadlock.
Call the async cancel_delayed_work instead, in order
to avoid the potential deadlock.
This is the relevant lockdep warning:
cfg80211: Calling CRDA for country: XX
======================================================
[ INFO: possible circular locking dependency detected ]
3.4.0-rc5-wl+ #26 Not tainted
-------------------------------------------------------
kworker/0:2/1391 is trying to acquire lock:
(cfg80211_mutex){+.+.+.}, at: [<bf28ae00>] restore_regulatory_settings+0x34/0x418 [cfg80211]
but task is already holding lock:
((reg_timeout).work){+.+...}, at: [<c0059e94>] process_one_work+0x1f0/0x480
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #2 ((reg_timeout).work){+.+...}:
[<c008fd44>] validate_chain+0xb94/0x10f0
[<c0090b68>] __lock_acquire+0x8c8/0x9b0
[<c0090d40>] lock_acquire+0xf0/0x114
[<c005b600>] wait_on_work+0x4c/0x154
[<c005c000>] __cancel_work_timer+0xd4/0x11c
[<c005c064>] cancel_delayed_work_sync+0x1c/0x20
[<bf28b274>] reg_set_request_processed+0x50/0x78 [cfg80211]
[<bf28bd84>] set_regdom+0x550/0x600 [cfg80211]
[<bf294cd8>] nl80211_set_reg+0x218/0x258 [cfg80211]
[<c03c7738>] genl_rcv_msg+0x1a8/0x1e8
[<c03c6a00>] netlink_rcv_skb+0x5c/0xc0
[<c03c7584>] genl_rcv+0x28/0x34
[<c03c6720>] netlink_unicast+0x15c/0x228
[<c03c6c7c>] netlink_sendmsg+0x218/0x298
[<c03933c8>] sock_sendmsg+0xa4/0xc0
[<c039406c>] __sys_sendmsg+0x1e4/0x268
[<c0394228>] sys_sendmsg+0x4c/0x70
[<c0013840>] ret_fast_syscall+0x0/0x3c
-> #1 (reg_mutex){+.+.+.}:
[<c008fd44>] validate_chain+0xb94/0x10f0
[<c0090b68>] __lock_acquire+0x8c8/0x9b0
[<c0090d40>] lock_acquire+0xf0/0x114
[<c04734dc>] mutex_lock_nested+0x48/0x320
[<bf28b2cc>] reg_todo+0x30/0x538 [cfg80211]
[<c0059f44>] process_one_work+0x2a0/0x480
[<c005a4b4>] worker_thread+0x1bc/0x2bc
[<c0061148>] kthread+0x98/0xa4
[<c0014af4>] kernel_thread_exit+0x0/0x8
-> #0 (cfg80211_mutex){+.+.+.}:
[<c008ed58>] print_circular_bug+0x68/0x2cc
[<c008fb28>] validate_chain+0x978/0x10f0
[<c0090b68>] __lock_acquire+0x8c8/0x9b0
[<c0090d40>] lock_acquire+0xf0/0x114
[<c04734dc>] mutex_lock_nested+0x48/0x320
[<bf28ae00>] restore_regulatory_settings+0x34/0x418 [cfg80211]
[<bf28b200>] reg_timeout_work+0x1c/0x20 [cfg80211]
[<c0059f44>] process_one_work+0x2a0/0x480
[<c005a4b4>] worker_thread+0x1bc/0x2bc
[<c0061148>] kthread+0x98/0xa4
[<c0014af4>] kernel_thread_exit+0x0/0x8
other info that might help us debug this:
Chain exists of:
cfg80211_mutex --> reg_mutex --> (reg_timeout).work
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock((reg_timeout).work);
lock(reg_mutex);
lock((reg_timeout).work);
lock(cfg80211_mutex);
*** DEADLOCK ***
2 locks held by kworker/0:2/1391:
#0 : (events){.+.+.+}, at: [<c0059e94>] process_one_work+0x1f0/0x480
#1 : ((reg_timeout).work){+.+...}, at: [<c0059e94>] process_one_work+0x1f0/0x480
stack backtrace:
[<c001b928>] (unwind_backtrace+0x0/0x12c) from [<c0471d3c>] (dump_stack+0x20/0x24)
[<c0471d3c>] (dump_stack+0x20/0x24) from [<c008ef70>] (print_circular_bug+0x280/0x2cc)
[<c008ef70>] (print_circular_bug+0x280/0x2cc) from [<c008fb28>] (validate_chain+0x978/0x10f0)
[<c008fb28>] (validate_chain+0x978/0x10f0) from [<c0090b68>] (__lock_acquire+0x8c8/0x9b0)
[<c0090b68>] (__lock_acquire+0x8c8/0x9b0) from [<c0090d40>] (lock_acquire+0xf0/0x114)
[<c0090d40>] (lock_acquire+0xf0/0x114) from [<c04734dc>] (mutex_lock_nested+0x48/0x320)
[<c04734dc>] (mutex_lock_nested+0x48/0x320) from [<bf28ae00>] (restore_regulatory_settings+0x34/0x418 [cfg80211])
[<bf28ae00>] (restore_regulatory_settings+0x34/0x418 [cfg80211]) from [<bf28b200>] (reg_timeout_work+0x1c/0x20 [cfg80211])
[<bf28b200>] (reg_timeout_work+0x1c/0x20 [cfg80211]) from [<c0059f44>] (process_one_work+0x2a0/0x480)
[<c0059f44>] (process_one_work+0x2a0/0x480) from [<c005a4b4>] (worker_thread+0x1bc/0x2bc)
[<c005a4b4>] (worker_thread+0x1bc/0x2bc) from [<c0061148>] (kthread+0x98/0xa4)
[<c0061148>] (kthread+0x98/0xa4) from [<c0014af4>] (kernel_thread_exit+0x0/0x8)
cfg80211: Calling CRDA to update world regulatory domain
cfg80211: World regulatory domain updated:
cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
cfg80211: (2457000 KHz - 2482000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)
cfg80211: (2474000 KHz - 2494000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)
cfg80211: (5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
cfg80211: (5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
Cc: stable@kernel.org
Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
2012-06-13 10:17:53 +02:00
..
2009-12-21 18:56:10 -05:00
2012-05-16 13:08:15 -04:00
2012-05-16 12:46:32 -04:00
2012-05-16 12:46:33 -04:00
2009-12-21 18:56:10 -05:00
2012-04-05 15:25:50 -07:00
2009-10-30 16:49:18 -04:00
2012-05-08 21:53:49 -04:00
2009-10-07 16:39:49 -04:00
2012-01-04 14:30:41 -05:00
2012-06-04 15:21:28 -04:00
2011-12-07 15:19:39 -05:00
2012-05-15 13:45:03 -04:00
2012-05-15 13:45:03 -04:00
2011-09-13 15:45:02 -04:00
2011-08-09 15:42:36 -04:00
2010-12-06 16:01:29 -05:00
2012-05-08 21:53:59 -04:00
2012-05-09 20:49:19 -04:00
2012-05-16 13:08:16 -04:00
2012-04-11 16:23:59 -04:00
2011-10-31 19:30:30 -04:00
2012-06-13 10:17:53 +02:00
2012-01-04 14:30:41 -05:00
2012-01-04 14:30:41 -05:00
2012-05-14 18:00:48 -04:00
2012-02-06 14:50:37 -05:00
2011-08-22 14:21:40 -04:00
2012-06-09 10:31:56 +02:00
2012-04-13 14:32:49 -04:00
2011-08-08 14:26:29 -04:00
2012-04-15 12:44:40 -04:00
2010-09-20 13:41:40 -04:00
2010-01-17 19:16:02 -08:00
2012-05-09 20:49:19 -04:00
2012-05-09 20:49:19 -04:00