svn commit: r274493 - head/sys/dev/ath

Adrian Chadd adrian at FreeBSD.org
Fri Nov 14 04:26:27 UTC 2014


Author: adrian
Date: Fri Nov 14 04:26:26 2014
New Revision: 274493
URL: https://svnweb.freebsd.org/changeset/base/274493

Log:
  Migrate the callouts from using mutex locks to being mpsafe with
  the locks being held by the callers.
  
  Kill callout_drain() and use callout_stop().

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

Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c	Fri Nov 14 00:25:10 2014	(r274492)
+++ head/sys/dev/ath/if_ath.c	Fri Nov 14 04:26:26 2014	(r274493)
@@ -669,8 +669,8 @@ ath_attach(u_int16_t devid, struct ath_s
 		goto bad;
 	}
 
-	callout_init_mtx(&sc->sc_cal_ch, &sc->sc_mtx, 0);
-	callout_init_mtx(&sc->sc_wd_ch, &sc->sc_mtx, 0);
+	callout_init(&sc->sc_cal_ch, 1);	/* MPSAFE */
+	callout_init(&sc->sc_wd_ch, 1);		/* MPSAFE */
 
 	ATH_TXBUF_LOCK_INIT(sc);
 
@@ -1812,7 +1812,10 @@ ath_suspend(struct ath_softc *sc)
 	 */
 	ath_hal_intrset(sc->sc_ah, 0);
 	taskqueue_block(sc->sc_tq);
-	callout_drain(&sc->sc_cal_ch);
+
+	ATH_LOCK(sc);
+	callout_stop(&sc->sc_cal_ch);
+	ATH_UNLOCK(sc);
 
 	/*
 	 * XXX ensure sc_invalid is 1
@@ -5599,6 +5602,10 @@ ath_calibrate(void *arg)
 	HAL_BOOL aniCal, shortCal = AH_FALSE;
 	int nextcal;
 
+	ATH_UNLOCK_ASSERT(sc);
+
+	ATH_LOCK(sc);
+
 	/*
 	 * Force the hardware awake for ANI work.
 	 */
@@ -5638,6 +5645,7 @@ ath_calibrate(void *arg)
 			taskqueue_enqueue(sc->sc_tq, &sc->sc_resettask);
 			callout_reset(&sc->sc_cal_ch, 1, ath_calibrate, sc);
 			ath_power_restore_power_state(sc);
+			ATH_UNLOCK(sc);
 			return;
 		}
 		/*
@@ -5713,6 +5721,7 @@ restart:
 	 * Restore power state now that we're done.
 	 */
 	ath_power_restore_power_state(sc);
+	ATH_UNLOCK(sc);
 }
 
 static void
@@ -5888,12 +5897,17 @@ ath_newstate(struct ieee80211vap *vap, e
 	 * Now, wake the thing up.
 	 */
 	ath_power_set_power_state(sc, HAL_PM_AWAKE);
+
+	/*
+	 * And stop the calibration callout whilst we have
+	 * ATH_LOCK held.
+	 */
+	callout_stop(&sc->sc_cal_ch);
 	ATH_UNLOCK(sc);
 
 	if (ostate == IEEE80211_S_CSA && nstate == IEEE80211_S_RUN)
 		csa_run_transition = 1;
 
-	callout_drain(&sc->sc_cal_ch);
 	ath_hal_setledstate(ah, leds[nstate]);	/* set LED */
 
 	if (nstate == IEEE80211_S_SCAN) {
@@ -6084,7 +6098,6 @@ ath_newstate(struct ieee80211vap *vap, e
 		ATH_LOCK(sc);
 		ath_power_setselfgen(sc, HAL_PM_AWAKE);
 		ath_power_setpower(sc, HAL_PM_AWAKE);
-		ATH_UNLOCK(sc);
 
 		/*
 		 * Finally, start any timers and the task q thread
@@ -6097,6 +6110,7 @@ ath_newstate(struct ieee80211vap *vap, e
 			DPRINTF(sc, ATH_DEBUG_CALIBRATE,
 			    "%s: calibration disabled\n", __func__);
 		}
+		ATH_UNLOCK(sc);
 
 		taskqueue_unblock(sc->sc_tq);
 	} else if (nstate == IEEE80211_S_INIT) {
@@ -6457,13 +6471,13 @@ ath_watchdog(void *arg)
 	struct ath_softc *sc = arg;
 	int do_reset = 0;
 
+	ATH_LOCK(sc);
+
 	if (sc->sc_wd_timer != 0 && --sc->sc_wd_timer == 0) {
 		struct ifnet *ifp = sc->sc_ifp;
 		uint32_t hangs;
 
-		ATH_LOCK(sc);
 		ath_power_set_power_state(sc, HAL_PM_AWAKE);
-		ATH_UNLOCK(sc);
 
 		if (ath_hal_gethangstate(sc->sc_ah, 0xffff, &hangs) &&
 		    hangs != 0) {
@@ -6475,9 +6489,7 @@ ath_watchdog(void *arg)
 		if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
 		sc->sc_stats.ast_watchdog++;
 
-		ATH_LOCK(sc);
 		ath_power_restore_power_state(sc);
-		ATH_UNLOCK(sc);
 	}
 
 	/*
@@ -6491,6 +6503,8 @@ ath_watchdog(void *arg)
 	}
 
 	callout_schedule(&sc->sc_wd_ch, hz);
+
+	ATH_UNLOCK(sc);
 }
 
 /*


More information about the svn-src-head mailing list