Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 20 Mar 2014 04:47:34 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r263416 - head/sys/dev/ath
Message-ID:  <201403200447.s2K4lY2c027137@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201403200447.s2K4lY2c027137>