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 | |
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')
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_assoc.c | 8 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_auth.c | 8 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_event.c | 2 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_module.c | 10 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_scan.c | 4 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_wx.c | 8 |
6 files changed, 23 insertions, 17 deletions
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c index 4c0feb2dacd8..c4d122ddd72c 100644 --- a/net/ieee80211/softmac/ieee80211softmac_assoc.c +++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c | |||
@@ -53,7 +53,7 @@ ieee80211softmac_assoc(struct ieee80211softmac_device *mac, struct ieee80211soft | |||
53 | /* Set a timer for timeout */ | 53 | /* Set a timer for timeout */ |
54 | /* FIXME: make timeout configurable */ | 54 | /* FIXME: make timeout configurable */ |
55 | if (likely(mac->running)) | 55 | if (likely(mac->running)) |
56 | schedule_delayed_work(&mac->associnfo.timeout, 5 * HZ); | 56 | queue_delayed_work(mac->wq, &mac->associnfo.timeout, 5 * HZ); |
57 | spin_unlock_irqrestore(&mac->lock, flags); | 57 | spin_unlock_irqrestore(&mac->lock, flags); |
58 | } | 58 | } |
59 | 59 | ||
@@ -419,7 +419,7 @@ ieee80211softmac_handle_assoc_response(struct net_device * dev, | |||
419 | network->authenticated = 0; | 419 | network->authenticated = 0; |
420 | /* we don't want to do this more than once ... */ | 420 | /* we don't want to do this more than once ... */ |
421 | network->auth_desynced_once = 1; | 421 | network->auth_desynced_once = 1; |
422 | schedule_delayed_work(&mac->associnfo.work, 0); | 422 | queue_delayed_work(mac->wq, &mac->associnfo.work, 0); |
423 | break; | 423 | break; |
424 | } | 424 | } |
425 | default: | 425 | default: |
@@ -441,7 +441,7 @@ ieee80211softmac_try_reassoc(struct ieee80211softmac_device *mac) | |||
441 | 441 | ||
442 | spin_lock_irqsave(&mac->lock, flags); | 442 | spin_lock_irqsave(&mac->lock, flags); |
443 | mac->associnfo.associating = 1; | 443 | mac->associnfo.associating = 1; |
444 | schedule_delayed_work(&mac->associnfo.work, 0); | 444 | queue_delayed_work(mac->wq, &mac->associnfo.work, 0); |
445 | spin_unlock_irqrestore(&mac->lock, flags); | 445 | spin_unlock_irqrestore(&mac->lock, flags); |
446 | } | 446 | } |
447 | 447 | ||
@@ -483,7 +483,7 @@ ieee80211softmac_handle_reassoc_req(struct net_device * dev, | |||
483 | dprintkl(KERN_INFO PFX "reassoc request from unknown network\n"); | 483 | dprintkl(KERN_INFO PFX "reassoc request from unknown network\n"); |
484 | return 0; | 484 | return 0; |
485 | } | 485 | } |
486 | schedule_delayed_work(&mac->associnfo.work, 0); | 486 | queue_delayed_work(mac->wq, &mac->associnfo.work, 0); |
487 | 487 | ||
488 | return 0; | 488 | return 0; |
489 | } | 489 | } |
diff --git a/net/ieee80211/softmac/ieee80211softmac_auth.c b/net/ieee80211/softmac/ieee80211softmac_auth.c index 855fa0fe641b..a53a751d0702 100644 --- a/net/ieee80211/softmac/ieee80211softmac_auth.c +++ b/net/ieee80211/softmac/ieee80211softmac_auth.c | |||
@@ -62,7 +62,7 @@ ieee80211softmac_auth_req(struct ieee80211softmac_device *mac, | |||
62 | 62 | ||
63 | /* add to list */ | 63 | /* add to list */ |
64 | list_add_tail(&auth->list, &mac->auth_queue); | 64 | list_add_tail(&auth->list, &mac->auth_queue); |
65 | schedule_delayed_work(&auth->work, 0); | 65 | queue_delayed_work(mac->wq, &auth->work, 0); |
66 | spin_unlock_irqrestore(&mac->lock, flags); | 66 | spin_unlock_irqrestore(&mac->lock, flags); |
67 | 67 | ||
68 | return 0; | 68 | return 0; |
@@ -97,7 +97,7 @@ ieee80211softmac_auth_queue(struct work_struct *work) | |||
97 | } | 97 | } |
98 | net->authenticated = 0; | 98 | net->authenticated = 0; |
99 | /* add a timeout call so we eventually give up waiting for an auth reply */ | 99 | /* add a timeout call so we eventually give up waiting for an auth reply */ |
100 | schedule_delayed_work(&auth->work, IEEE80211SOFTMAC_AUTH_TIMEOUT); | 100 | queue_delayed_work(mac->wq, &auth->work, IEEE80211SOFTMAC_AUTH_TIMEOUT); |
101 | auth->retry--; | 101 | auth->retry--; |
102 | spin_unlock_irqrestore(&mac->lock, flags); | 102 | spin_unlock_irqrestore(&mac->lock, flags); |
103 | if (ieee80211softmac_send_mgt_frame(mac, auth->net, IEEE80211_STYPE_AUTH, auth->state)) | 103 | if (ieee80211softmac_send_mgt_frame(mac, auth->net, IEEE80211_STYPE_AUTH, auth->state)) |
@@ -242,7 +242,7 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth) | |||
242 | * request. */ | 242 | * request. */ |
243 | cancel_delayed_work(&aq->work); | 243 | cancel_delayed_work(&aq->work); |
244 | INIT_DELAYED_WORK(&aq->work, &ieee80211softmac_auth_challenge_response); | 244 | INIT_DELAYED_WORK(&aq->work, &ieee80211softmac_auth_challenge_response); |
245 | schedule_delayed_work(&aq->work, 0); | 245 | queue_delayed_work(mac->wq, &aq->work, 0); |
246 | spin_unlock_irqrestore(&mac->lock, flags); | 246 | spin_unlock_irqrestore(&mac->lock, flags); |
247 | return 0; | 247 | return 0; |
248 | case IEEE80211SOFTMAC_AUTH_SHARED_PASS: | 248 | case IEEE80211SOFTMAC_AUTH_SHARED_PASS: |
@@ -408,6 +408,6 @@ ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *de | |||
408 | ieee80211softmac_deauth_from_net(mac, net); | 408 | ieee80211softmac_deauth_from_net(mac, net); |
409 | 409 | ||
410 | /* let's try to re-associate */ | 410 | /* let's try to re-associate */ |
411 | schedule_delayed_work(&mac->associnfo.work, 0); | 411 | queue_delayed_work(mac->wq, &mac->associnfo.work, 0); |
412 | return 0; | 412 | return 0; |
413 | } | 413 | } |
diff --git a/net/ieee80211/softmac/ieee80211softmac_event.c b/net/ieee80211/softmac/ieee80211softmac_event.c index b3e33a4d4869..8cef05b60f16 100644 --- a/net/ieee80211/softmac/ieee80211softmac_event.c +++ b/net/ieee80211/softmac/ieee80211softmac_event.c | |||
@@ -172,7 +172,7 @@ ieee80211softmac_call_events_locked(struct ieee80211softmac_device *mac, int eve | |||
172 | /* User may have subscribed to ANY event, so | 172 | /* User may have subscribed to ANY event, so |
173 | * we tell them which event triggered it. */ | 173 | * we tell them which event triggered it. */ |
174 | eventptr->event_type = event; | 174 | eventptr->event_type = event; |
175 | schedule_delayed_work(&eventptr->work, 0); | 175 | queue_delayed_work(mac->wq, &eventptr->work, 0); |
176 | } | 176 | } |
177 | } | 177 | } |
178 | } | 178 | } |
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); |
diff --git a/net/ieee80211/softmac/ieee80211softmac_scan.c b/net/ieee80211/softmac/ieee80211softmac_scan.c index abea3648680e..bfab8d7db88f 100644 --- a/net/ieee80211/softmac/ieee80211softmac_scan.c +++ b/net/ieee80211/softmac/ieee80211softmac_scan.c | |||
@@ -123,7 +123,7 @@ void ieee80211softmac_scan(struct work_struct *work) | |||
123 | spin_unlock_irqrestore(&sm->lock, flags); | 123 | spin_unlock_irqrestore(&sm->lock, flags); |
124 | break; | 124 | break; |
125 | } | 125 | } |
126 | schedule_delayed_work(&si->softmac_scan, IEEE80211SOFTMAC_PROBE_DELAY); | 126 | queue_delayed_work(sm->wq, &si->softmac_scan, IEEE80211SOFTMAC_PROBE_DELAY); |
127 | spin_unlock_irqrestore(&sm->lock, flags); | 127 | spin_unlock_irqrestore(&sm->lock, flags); |
128 | return; | 128 | return; |
129 | } else { | 129 | } else { |
@@ -190,7 +190,7 @@ int ieee80211softmac_start_scan_implementation(struct net_device *dev) | |||
190 | sm->scaninfo->started = 1; | 190 | sm->scaninfo->started = 1; |
191 | sm->scaninfo->stop = 0; | 191 | sm->scaninfo->stop = 0; |
192 | INIT_COMPLETION(sm->scaninfo->finished); | 192 | INIT_COMPLETION(sm->scaninfo->finished); |
193 | schedule_delayed_work(&sm->scaninfo->softmac_scan, 0); | 193 | queue_delayed_work(sm->wq, &sm->scaninfo->softmac_scan, 0); |
194 | spin_unlock_irqrestore(&sm->lock, flags); | 194 | spin_unlock_irqrestore(&sm->lock, flags); |
195 | return 0; | 195 | return 0; |
196 | } | 196 | } |
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c index 8e8ad08a411c..ac36767b56e8 100644 --- a/net/ieee80211/softmac/ieee80211softmac_wx.c +++ b/net/ieee80211/softmac/ieee80211softmac_wx.c | |||
@@ -91,7 +91,7 @@ check_assoc_again: | |||
91 | /* We must unlock to avoid deadlocks with the assoc workqueue | 91 | /* We must unlock to avoid deadlocks with the assoc workqueue |
92 | * on the associnfo.mutex */ | 92 | * on the associnfo.mutex */ |
93 | mutex_unlock(&sm->associnfo.mutex); | 93 | mutex_unlock(&sm->associnfo.mutex); |
94 | flush_scheduled_work(); | 94 | flush_workqueue(sm->wq); |
95 | /* Avoid race! Check assoc status again. Maybe someone started an | 95 | /* Avoid race! Check assoc status again. Maybe someone started an |
96 | * association while we flushed. */ | 96 | * association while we flushed. */ |
97 | goto check_assoc_again; | 97 | goto check_assoc_again; |
@@ -114,7 +114,7 @@ check_assoc_again: | |||
114 | 114 | ||
115 | sm->associnfo.associating = 1; | 115 | sm->associnfo.associating = 1; |
116 | /* queue lower level code to do work (if necessary) */ | 116 | /* queue lower level code to do work (if necessary) */ |
117 | schedule_delayed_work(&sm->associnfo.work, 0); | 117 | queue_delayed_work(sm->wq, &sm->associnfo.work, 0); |
118 | 118 | ||
119 | mutex_unlock(&sm->associnfo.mutex); | 119 | mutex_unlock(&sm->associnfo.mutex); |
120 | 120 | ||
@@ -349,7 +349,7 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev, | |||
349 | /* force reassociation */ | 349 | /* force reassociation */ |
350 | mac->associnfo.bssvalid = 0; | 350 | mac->associnfo.bssvalid = 0; |
351 | if (mac->associnfo.associated) | 351 | if (mac->associnfo.associated) |
352 | schedule_delayed_work(&mac->associnfo.work, 0); | 352 | queue_delayed_work(mac->wq, &mac->associnfo.work, 0); |
353 | } else if (is_zero_ether_addr(data->ap_addr.sa_data)) { | 353 | } else if (is_zero_ether_addr(data->ap_addr.sa_data)) { |
354 | /* the bssid we have is no longer fixed */ | 354 | /* the bssid we have is no longer fixed */ |
355 | mac->associnfo.bssfixed = 0; | 355 | mac->associnfo.bssfixed = 0; |
@@ -366,7 +366,7 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev, | |||
366 | /* tell the other code that this bssid should be used no matter what */ | 366 | /* tell the other code that this bssid should be used no matter what */ |
367 | mac->associnfo.bssfixed = 1; | 367 | mac->associnfo.bssfixed = 1; |
368 | /* queue associate if new bssid or (old one again and not associated) */ | 368 | /* queue associate if new bssid or (old one again and not associated) */ |
369 | schedule_delayed_work(&mac->associnfo.work, 0); | 369 | queue_delayed_work(mac->wq, &mac->associnfo.work, 0); |
370 | } | 370 | } |
371 | 371 | ||
372 | out: | 372 | out: |