summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2013-02-25 06:09:24 (GMT)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-03-03 22:03:33 (GMT)
commit66c45d44d42012bd9ad5e5154cd7d2b391b1183e (patch)
tree91f2a3d6e6f549c652d2e3eb3fbb77be29df612c /drivers/net
parente3d7ed9c659eebbf83fc20e8c80bb3c58a24028d (diff)
downloadlinux-fsl-qoriq-66c45d44d42012bd9ad5e5154cd7d2b391b1183e.tar.xz
b43: Fix lockdep splat on module unload
commit 63a02ce1c5c59baa40b99756492e3ec8d6b51483 upstream. On unload, b43 produces a lockdep warning that can be summarized in the following way: ====================================================== [ INFO: possible circular locking dependency detected ] 3.8.0-wl+ #117 Not tainted ------------------------------------------------------- modprobe/5557 is trying to acquire lock: ((&wl->firmware_load)){+.+.+.}, at: [<ffffffff81062160>] flush_work+0x0/0x2a0 but task is already holding lock: (rtnl_mutex){+.+.+.}, at: [<ffffffff813bd7d2>] rtnl_lock+0x12/0x20 which lock already depends on the new lock. [ INFO: possible circular locking dependency detected ] ====================================================== The full output is available at http://lkml.indiana.edu/hypermail/linux/kernel/1302.3/00060.html. To summarize, commit 6b6fa58 added a 'cancel_work_sync(&wl->firmware_load)' call in the wrong place. The fix is to move the cancel_work_sync() call to b43_bcma_remove() and b43_ssb_remove(). Thanks to Johannes Berg and Michael Buesch for help in diagnosing the log output. Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/b43/main.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 806e34c..0568273 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4214,7 +4214,6 @@ redo:
mutex_unlock(&wl->mutex);
cancel_delayed_work_sync(&dev->periodic_work);
cancel_work_sync(&wl->tx_work);
- cancel_work_sync(&wl->firmware_load);
mutex_lock(&wl->mutex);
dev = wl->current_dev;
if (!dev || b43_status(dev) < B43_STAT_STARTED) {
@@ -5434,6 +5433,7 @@ static void b43_bcma_remove(struct bcma_device *core)
/* We must cancel any work here before unregistering from ieee80211,
* as the ieee80211 unreg will destroy the workqueue. */
cancel_work_sync(&wldev->restart_work);
+ cancel_work_sync(&wl->firmware_load);
B43_WARN_ON(!wl);
if (!wldev->fw.ucode.data)
@@ -5510,6 +5510,7 @@ static void b43_ssb_remove(struct ssb_device *sdev)
/* We must cancel any work here before unregistering from ieee80211,
* as the ieee80211 unreg will destroy the workqueue. */
cancel_work_sync(&wldev->restart_work);
+ cancel_work_sync(&wl->firmware_load);
B43_WARN_ON(!wl);
if (!wldev->fw.ucode.data)