aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2007-10-03 21:14:23 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:52:22 -0400
commit501d857ec93e797d4872d6b9b265b7472b455ddf (patch)
treef4bbdd316145573af7234960599e45592b73f8fe /net
parent05155c83d13b983ac2c5691575fd471543df31fe (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')
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_assoc.c8
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_auth.c8
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_event.c2
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_module.c10
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_scan.c4
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_wx.c8
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}
144EXPORT_SYMBOL_GPL(free_ieee80211softmac); 150EXPORT_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: