linux/net
Luis R. Rodriguez a85d0d7f34 cfg80211: fix possible circular lock on reg_regdb_search()
When call_crda() is called we kick off a witch hunt search
for the same regulatory domain on our internal regulatory
database and that work gets kicked off on a workqueue, this
is done while the cfg80211_mutex is held. If that workqueue
kicks off it will first lock reg_regdb_search_mutex and
later cfg80211_mutex but to ensure two CPUs will not contend
against cfg80211_mutex the right thing to do is to have the
reg_regdb_search() wait until the cfg80211_mutex is let go.

The lockdep report is pasted below.

cfg80211: Calling CRDA to update world regulatory domain

======================================================
[ INFO: possible circular locking dependency detected ]
3.3.8 #3 Tainted: G           O
-------------------------------------------------------
kworker/0:1/235 is trying to acquire lock:
 (cfg80211_mutex){+.+...}, at: [<816468a4>] set_regdom+0x78c/0x808 [cfg80211]

but task is already holding lock:
 (reg_regdb_search_mutex){+.+...}, at: [<81646828>] set_regdom+0x710/0x808 [cfg80211]

which lock already depends on the new lock.

the existing dependency chain (in reverse order) is:

-> #2 (reg_regdb_search_mutex){+.+...}:
       [<800a8384>] lock_acquire+0x60/0x88
       [<802950a8>] mutex_lock_nested+0x54/0x31c
       [<81645778>] is_world_regdom+0x9f8/0xc74 [cfg80211]

-> #1 (reg_mutex#2){+.+...}:
       [<800a8384>] lock_acquire+0x60/0x88
       [<802950a8>] mutex_lock_nested+0x54/0x31c
       [<8164539c>] is_world_regdom+0x61c/0xc74 [cfg80211]

-> #0 (cfg80211_mutex){+.+...}:
       [<800a77b8>] __lock_acquire+0x10d4/0x17bc
       [<800a8384>] lock_acquire+0x60/0x88
       [<802950a8>] mutex_lock_nested+0x54/0x31c
       [<816468a4>] set_regdom+0x78c/0x808 [cfg80211]

other info that might help us debug this:

Chain exists of:
  cfg80211_mutex --> reg_mutex#2 --> reg_regdb_search_mutex

 Possible unsafe locking scenario:

       CPU0                    CPU1
       ----                    ----
  lock(reg_regdb_search_mutex);
                               lock(reg_mutex#2);
                               lock(reg_regdb_search_mutex);
  lock(cfg80211_mutex);

 *** DEADLOCK ***

3 locks held by kworker/0:1/235:
 #0:  (events){.+.+..}, at: [<80089a00>] process_one_work+0x230/0x460
 #1:  (reg_regdb_work){+.+...}, at: [<80089a00>] process_one_work+0x230/0x460
 #2:  (reg_regdb_search_mutex){+.+...}, at: [<81646828>] set_regdom+0x710/0x808 [cfg80211]

stack backtrace:
Call Trace:
[<80290fd4>] dump_stack+0x8/0x34
[<80291bc4>] print_circular_bug+0x2ac/0x2d8
[<800a77b8>] __lock_acquire+0x10d4/0x17bc
[<800a8384>] lock_acquire+0x60/0x88
[<802950a8>] mutex_lock_nested+0x54/0x31c
[<816468a4>] set_regdom+0x78c/0x808 [cfg80211]

Reported-by: Felix Fietkau <nbd@openwrt.org>
Tested-by: Felix Fietkau <nbd@openwrt.org>
Cc: stable@vger.kernel.org
Signed-off-by: Luis R. Rodriguez <mcgrof@do-not-panic.com>
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
2012-09-18 20:43:23 -04:00
..
9p net: Fix (nearly-)kernel-doc comments for various functions 2012-07-10 23:13:45 -07:00
802
8021q netpoll: move np->dev and np->dev_name init into __netpoll_setup() 2012-07-17 09:02:36 -07:00
appletalk net: Fix (nearly-)kernel-doc comments for various functions 2012-07-10 23:13:45 -07:00
atm
ax25 Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2012-07-19 11:17:30 -07:00
batman-adv Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2012-07-10 23:56:33 -07:00
bluetooth Bluetooth: Fix not removing power_off delayed work 2012-09-18 20:13:02 -03:00
bridge bridge: make port attributes const 2012-07-30 14:53:22 -07:00
caif netvm: prevent a stream-specific deadlock 2012-07-31 18:42:47 -07:00
can can: gw: Remove pointless casts 2012-07-10 22:36:17 +02:00
ceph Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client 2012-07-31 14:35:28 -07:00
core tcp: Apply device TSO segment limit earlier 2012-08-02 00:19:17 -07:00
dcb net: Fix non-kernel-doc comments with kernel-doc start marker 2012-07-10 23:13:45 -07:00
dccp ipv4: Prepare for change of rt->rt_iif encoding. 2012-07-23 16:36:26 -07:00
decnet ipv4: Restore old dst_free() behavior. 2012-07-31 14:41:38 -07:00
dns_resolver
dsa
ethernet ipx: move peII functions 2012-07-19 10:48:00 -07:00
ieee802154 6lowpan: Change byte order when storing/accessing to len field 2012-07-16 22:52:02 -07:00
ipv4 ipv4: route.c cleanup 2012-08-02 02:54:43 -07:00
ipv6 Merge branch 'akpm' (Andrew's patch-bomb) 2012-07-31 19:25:39 -07:00
ipx ipx: move peII functions 2012-07-19 10:48:00 -07:00
irda irda: Fix typo in irda 2012-07-16 23:23:52 -07:00
iucv
key
l2tp
lapb
llc net: Fix (nearly-)kernel-doc comments for various functions 2012-07-10 23:13:45 -07:00
mac80211 Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211 2012-09-05 14:48:15 -04:00
mac802154 mac802154: sparse warnings: make symbols static 2012-07-12 07:54:45 -07:00
netfilter Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2012-07-19 11:17:30 -07:00
netlabel
netlink genetlink: define lockdep_genl_is_held() when CONFIG_LOCKDEP 2012-07-24 00:01:30 -07:00
netrom
nfc Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem 2012-07-20 12:30:48 -04:00
openvswitch Revert "openvswitch: potential NULL deref in sample()" 2012-07-27 13:45:51 -07:00
packet
phonet
rds rds: set correct msg_namelen 2012-07-23 01:01:44 -07:00
rfkill
rose
rxrpc Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2012-07-10 23:56:33 -07:00
sched ipv4: Prepare for change of rt->rt_iif encoding. 2012-07-23 16:36:26 -07:00
sctp netvm: prevent a stream-specific deadlock 2012-07-31 18:42:47 -07:00
sunrpc Merge branch 'akpm' (Andrew's patch-bomb) 2012-07-31 19:25:39 -07:00
tipc tipc: remove print_buf and deprecated log buffer code 2012-07-13 19:34:43 -04:00
unix Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-08-01 10:26:23 -07:00
wanrouter wanmain: comparing array with NULL 2012-07-24 13:55:21 -07:00
wimax
wireless cfg80211: fix possible circular lock on reg_regdb_search() 2012-09-18 20:43:23 -04:00
x25 net: Fix (nearly-)kernel-doc comments for various functions 2012-07-10 23:13:45 -07:00
xfrm Fix unexpected SA hard expiration after changing date 2012-08-02 00:19:17 -07:00
Kconfig
Makefile
compat.c net: Fix references to out-of-scope variables in put_cmsg_compat() 2012-07-22 17:50:49 -07:00
nonet.c
socket.c net: netprio_cgroup: rework update socket logic 2012-07-22 12:44:01 -07:00
sysctl_net.c