aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2007-07-31 14:41:04 -0400
committerJohn W. Linville <linville@tuxdriver.com>2007-08-06 15:06:03 -0400
commitfdc8f43b5e49b64b251bb48da95193a13ac0132f (patch)
tree802edd7045beb8b00b344f40368751f8abfcd9e6
parent69dad6e563140ce8578749a8c8651b7f1db8cdbc (diff)
[PATCH] softmac: Fix deadlock of wx_set_essid with assoc work
The essid wireless extension does deadlock against the assoc mutex, as we don't unlock the assoc mutex when flushing the workqueue, which also holds the lock. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_wx.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c
index f13937bf9e8c..d054e9224b3e 100644
--- a/net/ieee80211/softmac/ieee80211softmac_wx.c
+++ b/net/ieee80211/softmac/ieee80211softmac_wx.c
@@ -74,8 +74,8 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
74 struct ieee80211softmac_auth_queue_item *authptr; 74 struct ieee80211softmac_auth_queue_item *authptr;
75 int length = 0; 75 int length = 0;
76 76
77check_assoc_again:
77 mutex_lock(&sm->associnfo.mutex); 78 mutex_lock(&sm->associnfo.mutex);
78
79 /* Check if we're already associating to this or another network 79 /* Check if we're already associating to this or another network
80 * If it's another network, cancel and start over with our new network 80 * If it's another network, cancel and start over with our new network
81 * If it's our network, ignore the change, we're already doing it! 81 * If it's our network, ignore the change, we're already doing it!
@@ -98,13 +98,18 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
98 cancel_delayed_work(&authptr->work); 98 cancel_delayed_work(&authptr->work);
99 sm->associnfo.bssvalid = 0; 99 sm->associnfo.bssvalid = 0;
100 sm->associnfo.bssfixed = 0; 100 sm->associnfo.bssfixed = 0;
101 flush_scheduled_work();
102 sm->associnfo.associating = 0; 101 sm->associnfo.associating = 0;
103 sm->associnfo.associated = 0; 102 sm->associnfo.associated = 0;
103 /* We must unlock to avoid deadlocks with the assoc workqueue
104 * on the associnfo.mutex */
105 mutex_unlock(&sm->associnfo.mutex);
106 flush_scheduled_work();
107 /* Avoid race! Check assoc status again. Maybe someone started an
108 * association while we flushed. */
109 goto check_assoc_again;
104 } 110 }
105 } 111 }
106 112
107
108 sm->associnfo.static_essid = 0; 113 sm->associnfo.static_essid = 0;
109 sm->associnfo.assoc_wait = 0; 114 sm->associnfo.assoc_wait = 0;
110 115