diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2007-10-03 21:14:23 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:52:22 -0400 |
commit | 501d857ec93e797d4872d6b9b265b7472b455ddf (patch) | |
tree | f4bbdd316145573af7234960599e45592b73f8fe /net/ieee80211/softmac/ieee80211softmac_module.c | |
parent | 05155c83d13b983ac2c5691575fd471543df31fe (diff) |
[IEEE80211]: Fix softmac lockdep reports.
It seems I was actually able to hit this deadlock, on my quad G5 softmac
locks up more often than not. This fixes it by using an own workqueue
that can safely be flushed under RTNL.
Not sure if the patch is correct with the workqueue naming. And don't
think with the patch it doesn't continually lock up. It still does, just
doesn't invoke lockdep warnings all the time.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ieee80211/softmac/ieee80211softmac_module.c')
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_module.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/net/ieee80211/softmac/ieee80211softmac_module.c b/net/ieee80211/softmac/ieee80211softmac_module.c index 6398e6e67493..07505ca859af 100644 --- a/net/ieee80211/softmac/ieee80211softmac_module.c +++ b/net/ieee80211/softmac/ieee80211softmac_module.c | |||
@@ -36,8 +36,13 @@ struct net_device *alloc_ieee80211softmac(int sizeof_priv) | |||
36 | dev = alloc_ieee80211(sizeof(*softmac) + sizeof_priv); | 36 | dev = alloc_ieee80211(sizeof(*softmac) + sizeof_priv); |
37 | if (!dev) | 37 | if (!dev) |
38 | return NULL; | 38 | return NULL; |
39 | |||
40 | softmac = ieee80211_priv(dev); | 39 | softmac = ieee80211_priv(dev); |
40 | softmac->wq = create_freezeable_workqueue("softmac"); | ||
41 | if (!softmac->wq) { | ||
42 | free_ieee80211(dev); | ||
43 | return NULL; | ||
44 | } | ||
45 | |||
41 | softmac->dev = dev; | 46 | softmac->dev = dev; |
42 | softmac->ieee = netdev_priv(dev); | 47 | softmac->ieee = netdev_priv(dev); |
43 | spin_lock_init(&softmac->lock); | 48 | spin_lock_init(&softmac->lock); |
@@ -105,7 +110,7 @@ ieee80211softmac_clear_pending_work(struct ieee80211softmac_device *sm) | |||
105 | cancel_delayed_work(&eventptr->work); | 110 | cancel_delayed_work(&eventptr->work); |
106 | 111 | ||
107 | spin_unlock_irqrestore(&sm->lock, flags); | 112 | spin_unlock_irqrestore(&sm->lock, flags); |
108 | flush_scheduled_work(); | 113 | flush_workqueue(sm->wq); |
109 | 114 | ||
110 | /* now we should be save and no longer need locking... */ | 115 | /* now we should be save and no longer need locking... */ |
111 | spin_lock_irqsave(&sm->lock, flags); | 116 | spin_lock_irqsave(&sm->lock, flags); |
@@ -139,6 +144,7 @@ void free_ieee80211softmac(struct net_device *dev) | |||
139 | ieee80211softmac_clear_pending_work(sm); | 144 | ieee80211softmac_clear_pending_work(sm); |
140 | kfree(sm->scaninfo); | 145 | kfree(sm->scaninfo); |
141 | kfree(sm->wpa.IE); | 146 | kfree(sm->wpa.IE); |
147 | destroy_workqueue(sm->wq); | ||
142 | free_ieee80211(dev); | 148 | free_ieee80211(dev); |
143 | } | 149 | } |
144 | EXPORT_SYMBOL_GPL(free_ieee80211softmac); | 150 | EXPORT_SYMBOL_GPL(free_ieee80211softmac); |