Author: adrian
Date: Thu Mar 20 04:47:34 2014
New Revision: 263416
URL: http://svnweb.freebsd.org/changeset/base/263416

Log:
  Don't call ath_init() inside the lock.
  
  Yes, this means that sc_invalid is slightly racy, but there are other
  issues here which need fixing.
  
  This fixes a source of eventual LORs - ath_init() grabs ATH_LOCK to do
  work and releases it before it calls ieee80211_start_all().
  ieee80211_start_all() will grab the net80211 comlock to iterate over
  the VAPs.
  
  TODO:
  
  * .. I should just migrate the ieee80211_start_all() work to a
    deferred task so it can be done later; it doesn't have to be
    immediately done.
  
  Tested:
  
  * AR5416, STA mode

Modified:
  head/sys/dev/ath/if_ath.c

Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c   Thu Mar 20 02:28:05 2014        (r263415)
+++ head/sys/dev/ath/if_ath.c   Thu Mar 20 04:47:34 2014        (r263416)
@@ -5948,14 +5948,15 @@ ath_ioctl(struct ifnet *ifp, u_long cmd,
 
        switch (cmd) {
        case SIOCSIFFLAGS:
-               ATH_LOCK(sc);
                if (IS_RUNNING(ifp)) {
                        /*
                         * To avoid rescanning another access point,
                         * do not call ath_init() here.  Instead,
                         * only reflect promisc mode settings.
                         */
+                       ATH_LOCK(sc);
                        ath_mode_init(sc);
+                       ATH_UNLOCK(sc);
                } else if (ifp->if_flags & IFF_UP) {
                        /*
                         * Beware of being called during attach/detach
@@ -5969,14 +5970,15 @@ ath_ioctl(struct ifnet *ifp, u_long cmd,
                        if (!sc->sc_invalid)
                                ath_init(sc);   /* XXX lose error */
                } else {
+                       ATH_LOCK(sc);
                        ath_stop_locked(ifp);
 #ifdef notyet
                        /* XXX must wakeup in places like ath_vap_delete */
                        if (!sc->sc_invalid)
                                ath_hal_setpower(sc->sc_ah, HAL_PM_FULL_SLEEP);
 #endif
+                       ATH_UNLOCK(sc);
                }
-               ATH_UNLOCK(sc);
                break;
        case SIOCGIFMEDIA:
        case SIOCSIFMEDIA:
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to