aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2007-08-07 12:20:40 +0200
committerWilly Tarreau <w@1wt.eu>2007-08-25 17:24:18 +0200
commitbcc5aca038af561a3ca5b86ce25413d5dfa3244c (patch)
tree9f287cf8bd13b22a00b7a55ec86a88ec4bce75e0
parent0496a0322a9f80a27f289fe61ed0936e9b2c7eb5 (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: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Willy Tarreau <w@1wt.eu>
-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 fb58e03b3fb..c3c39ed53a2 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,
struct ieee80211softmac_auth_queue_item *authptr;
int length = 0;
+check_assoc_again:
mutex_lock(&sm->associnfo.mutex);
-
/* Check if we're already associating to this or another network
* If it's another network, cancel and start over with our new network
* 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,
cancel_delayed_work(&authptr->work);
sm->associnfo.bssvalid = 0;
sm->associnfo.bssfixed = 0;
- flush_scheduled_work();
sm->associnfo.associating = 0;
sm->associnfo.associated = 0;
+ /* We must unlock to avoid deadlocks with the assoc workqueue
+ * on the associnfo.mutex */
+ mutex_unlock(&sm->associnfo.mutex);
+ flush_scheduled_work();
+ /* Avoid race! Check assoc status again. Maybe someone started an
+ * association while we flushed. */
+ goto check_assoc_again;
}
}
-
sm->associnfo.static_essid = 0;
sm->associnfo.assoc_wait = 0;