kern/179232: commit references a PR
dfilter service
dfilter at FreeBSD.ORG
Mon Jun 3 19:40:01 UTC 2013
The following reply was made to PR kern/179232; it has been noted by GNATS.
From: dfilter at FreeBSD.ORG (dfilter service)
To: bug-followup at FreeBSD.org
Cc:
Subject: Re: kern/179232: commit references a PR
Date: Mon, 3 Jun 2013 19:39:50 +0000 (UTC)
Author: adrian
Date: Mon Jun 3 19:39:37 2013
New Revision: 251342
URL: http://svnweb.freebsd.org/changeset/base/251342
Log:
Fix the order of TX shutdown and reset.
* Grab the reset lock first, so any subsequent interrupt, TX, RX work
will fail
* Then shut down interrupts
* Then wait for TX/RX to finish running
At this point no further work will be running, so it's safe to do the
reset path code.
PR: kern/179232
Modified:
head/sys/dev/ath/if_ath.c
Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c Mon Jun 3 19:29:03 2013 (r251341)
+++ head/sys/dev/ath/if_ath.c Mon Jun 3 19:39:37 2013 (r251342)
@@ -2328,12 +2328,27 @@ ath_reset(struct ifnet *ifp, ATH_RESET_T
taskqueue_block(sc->sc_tq);
ATH_PCU_LOCK(sc);
- ath_hal_intrset(ah, 0); /* disable interrupts */
- ath_txrx_stop_locked(sc); /* Ensure TX/RX is stopped */
+
+ /*
+ * Grab the reset lock before TX/RX is stopped.
+ *
+ * This is needed to ensure that when the TX/RX actually does finish,
+ * no further TX/RX/reset runs in parallel with this.
+ */
if (ath_reset_grablock(sc, 1) == 0) {
device_printf(sc->sc_dev, "%s: concurrent reset! Danger!\n",
__func__);
}
+
+ /* disable interrupts */
+ ath_hal_intrset(ah, 0);
+
+ /*
+ * Now, ensure that any in progress TX/RX completes before we
+ * continue.
+ */
+ ath_txrx_stop_locked(sc);
+
ATH_PCU_UNLOCK(sc);
/*
@@ -4871,12 +4886,18 @@ ath_chan_set(struct ath_softc *sc, struc
taskqueue_block(sc->sc_tq);
ATH_PCU_LOCK(sc);
- ath_hal_intrset(ah, 0); /* Stop new RX/TX completion */
- ath_txrx_stop_locked(sc); /* Stop pending RX/TX completion */
+
+ /* Stop new RX/TX/interrupt completion */
if (ath_reset_grablock(sc, 1) == 0) {
device_printf(sc->sc_dev, "%s: concurrent reset! Danger!\n",
__func__);
}
+
+ ath_hal_intrset(ah, 0);
+
+ /* Stop pending RX/TX completion */
+ ath_txrx_stop_locked(sc);
+
ATH_PCU_UNLOCK(sc);
DPRINTF(sc, ATH_DEBUG_RESET, "%s: %u (%u MHz, flags 0x%x)\n",
_______________________________________________
svn-src-all at freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe at freebsd.org"
More information about the freebsd-wireless
mailing list