summaryrefslogtreecommitdiff
path: root/net/wireless/core.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2010-08-30 17:36:40 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-08-31 14:48:47 -0400
commitc3d34d5d9654ec9c2510f9341bfb1030b8f029d1 (patch)
tree1a5db6df49f9b55aa16b0359088dc0536387b3dd /net/wireless/core.c
parent42da2f948d949efd0111309f5827bf0298bcc9a4 (diff)
downloadlinux-3.10-c3d34d5d9654ec9c2510f9341bfb1030b8f029d1.tar.gz
linux-3.10-c3d34d5d9654ec9c2510f9341bfb1030b8f029d1.tar.bz2
linux-3.10-c3d34d5d9654ec9c2510f9341bfb1030b8f029d1.zip
wireless: register wiphy rfkill w/o holding cfg80211_mutex
Otherwise lockdep complains... https://bugzilla.kernel.org/show_bug.cgi?id=17311 [ INFO: possible circular locking dependency detected ] 2.6.36-rc2-git4 #12 ------------------------------------------------------- kworker/0:3/3630 is trying to acquire lock: (rtnl_mutex){+.+.+.}, at: [<ffffffff813396c7>] rtnl_lock+0x12/0x14 but task is already holding lock: (rfkill_global_mutex){+.+.+.}, at: [<ffffffffa014b129>] rfkill_switch_all+0x24/0x49 [rfkill] which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #2 (rfkill_global_mutex){+.+.+.}: [<ffffffff81079ad7>] lock_acquire+0x120/0x15b [<ffffffff813ae869>] __mutex_lock_common+0x54/0x52e [<ffffffff813aede9>] mutex_lock_nested+0x34/0x39 [<ffffffffa014b4ab>] rfkill_register+0x2b/0x29c [rfkill] [<ffffffffa0185ba0>] wiphy_register+0x1ae/0x270 [cfg80211] [<ffffffffa0206f01>] ieee80211_register_hw+0x1b4/0x3cf [mac80211] [<ffffffffa0292e98>] iwl_ucode_callback+0x9e9/0xae3 [iwlagn] [<ffffffff812d3e9d>] request_firmware_work_func+0x54/0x6f [<ffffffff81065d15>] kthread+0x8c/0x94 [<ffffffff8100ac24>] kernel_thread_helper+0x4/0x10 -> #1 (cfg80211_mutex){+.+.+.}: [<ffffffff81079ad7>] lock_acquire+0x120/0x15b [<ffffffff813ae869>] __mutex_lock_common+0x54/0x52e [<ffffffff813aede9>] mutex_lock_nested+0x34/0x39 [<ffffffffa018605e>] cfg80211_get_dev_from_ifindex+0x1b/0x7c [cfg80211] [<ffffffffa0189f36>] cfg80211_wext_giwscan+0x58/0x990 [cfg80211] [<ffffffff8139a3ce>] ioctl_standard_iw_point+0x1a8/0x272 [<ffffffff8139a529>] ioctl_standard_call+0x91/0xa7 [<ffffffff8139a687>] T.723+0xbd/0x12c [<ffffffff8139a727>] wext_handle_ioctl+0x31/0x6d [<ffffffff8133014e>] dev_ioctl+0x63d/0x67a [<ffffffff8131afd9>] sock_ioctl+0x48/0x21d [<ffffffff81102abd>] do_vfs_ioctl+0x4ba/0x509 [<ffffffff81102b5d>] sys_ioctl+0x51/0x74 [<ffffffff81009e02>] system_call_fastpath+0x16/0x1b -> #0 (rtnl_mutex){+.+.+.}: [<ffffffff810796b0>] __lock_acquire+0xa93/0xd9a [<ffffffff81079ad7>] lock_acquire+0x120/0x15b [<ffffffff813ae869>] __mutex_lock_common+0x54/0x52e [<ffffffff813aede9>] mutex_lock_nested+0x34/0x39 [<ffffffff813396c7>] rtnl_lock+0x12/0x14 [<ffffffffa0185cb5>] cfg80211_rfkill_set_block+0x1a/0x7b [cfg80211] [<ffffffffa014aed0>] rfkill_set_block+0x80/0xd5 [rfkill] [<ffffffffa014b07e>] __rfkill_switch_all+0x3f/0x6f [rfkill] [<ffffffffa014b13d>] rfkill_switch_all+0x38/0x49 [rfkill] [<ffffffffa014b821>] rfkill_op_handler+0x105/0x136 [rfkill] [<ffffffff81060708>] process_one_work+0x248/0x403 [<ffffffff81062620>] worker_thread+0x139/0x214 [<ffffffff81065d15>] kthread+0x8c/0x94 [<ffffffff8100ac24>] kernel_thread_helper+0x4/0x10 Signed-off-by: John W. Linville <linville@tuxdriver.com> Acked-by: Johannes Berg <johannes@sipsolutions.net>
Diffstat (limited to 'net/wireless/core.c')
-rw-r--r--net/wireless/core.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 541e2fff5e9..d6d046b9f6f 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -475,12 +475,10 @@ int wiphy_register(struct wiphy *wiphy)
mutex_lock(&cfg80211_mutex);
res = device_add(&rdev->wiphy.dev);
- if (res)
- goto out_unlock;
-
- res = rfkill_register(rdev->rfkill);
- if (res)
- goto out_rm_dev;
+ if (res) {
+ mutex_unlock(&cfg80211_mutex);
+ return res;
+ }
/* set up regulatory info */
wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE);
@@ -509,13 +507,18 @@ int wiphy_register(struct wiphy *wiphy)
cfg80211_debugfs_rdev_add(rdev);
mutex_unlock(&cfg80211_mutex);
+ /*
+ * due to a locking dependency this has to be outside of the
+ * cfg80211_mutex lock
+ */
+ res = rfkill_register(rdev->rfkill);
+ if (res)
+ goto out_rm_dev;
+
return 0;
out_rm_dev:
device_del(&rdev->wiphy.dev);
-
-out_unlock:
- mutex_unlock(&cfg80211_mutex);
return res;
}
EXPORT_SYMBOL(wiphy_register);