]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
[PATCH] softmac: Fix deadlock of wx_set_essid with assoc work
authorMichael Buesch <mb@bu3sch.de>
Tue, 7 Aug 2007 10:20:40 +0000 (12:20 +0200)
committerWilly Tarreau <w@1wt.eu>
Sat, 25 Aug 2007 15:24:18 +0000 (17:24 +0200)
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>
net/ieee80211/softmac/ieee80211softmac_wx.c

index fb58e03b3fbda3497245f3b484c01db14a343e4c..c3c39ed53a2a4d91537f3dda600c48e8e138d809 100644 (file)
@@ -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;