svn commit: r280112 - head/sys/dev/wpi

Adrian Chadd adrian at FreeBSD.org
Sun Mar 15 21:25:08 UTC 2015


Author: adrian
Date: Sun Mar 15 21:25:06 2015
New Revision: 280112
URL: https://svnweb.freebsd.org/changeset/base/280112

Log:
  Add an extra mutex for qfullmsk / ring->queued variables.
  
  PR:		kern/197143
  Submitted by:	Andriy Voskoboinyk <s3erios at gmail.com>

Modified:
  head/sys/dev/wpi/if_wpi.c
  head/sys/dev/wpi/if_wpivar.h

Modified: head/sys/dev/wpi/if_wpi.c
==============================================================================
--- head/sys/dev/wpi/if_wpi.c	Sun Mar 15 21:24:11 2015	(r280111)
+++ head/sys/dev/wpi/if_wpi.c	Sun Mar 15 21:25:06 2015	(r280112)
@@ -399,6 +399,7 @@ wpi_attach(device_t dev)
 	WPI_RXON_LOCK_INIT(sc);
 	WPI_NT_LOCK_INIT(sc);
 	WPI_TXQ_LOCK_INIT(sc);
+	WPI_TXQ_STATE_LOCK_INIT(sc);
 
 	/* Allocate DMA memory for firmware transfers. */
 	if ((error = wpi_alloc_fwmem(sc)) != 0) {
@@ -523,7 +524,7 @@ wpi_attach(device_t dev)
 
 	callout_init_mtx(&sc->calib_to, &sc->rxon_mtx, 0);
 	callout_init_mtx(&sc->scan_timeout, &sc->rxon_mtx, 0);
-	callout_init_mtx(&sc->tx_timeout, &sc->sc_mtx, 0);
+	callout_init_mtx(&sc->tx_timeout, &sc->txq_state_mtx, 0);
 	callout_init_mtx(&sc->watchdog_rfkill, &sc->sc_mtx, 0);
 	TASK_INIT(&sc->sc_reinittask, 0, wpi_hw_reset, sc);
 	TASK_INIT(&sc->sc_radiooff_task, 0, wpi_radio_off, sc);
@@ -721,6 +722,7 @@ wpi_detach(device_t dev)
 		if_free(ifp);
 
 	DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END, __func__);
+	WPI_TXQ_STATE_LOCK_DESTROY(sc);
 	WPI_TXQ_LOCK_DESTROY(sc);
 	WPI_NT_LOCK_DESTROY(sc);
 	WPI_RXON_LOCK_DESTROY(sc);
@@ -1970,6 +1972,7 @@ wpi_tx_done(struct wpi_softc *sc, struct
 	ieee80211_tx_complete(ni, m, (status & 0xff) != 1);
 	WPI_LOCK(sc);
 
+	WPI_TXQ_STATE_LOCK(sc);
 	ring->queued -= 1;
 	if (ring->queued > 0) {
 		callout_reset(&sc->tx_timeout, 5*hz, wpi_tx_timeout, sc);
@@ -1988,6 +1991,7 @@ wpi_tx_done(struct wpi_softc *sc, struct
 		}
 	} else
 		callout_stop(&sc->tx_timeout);
+	WPI_TXQ_STATE_UNLOCK(sc);
 
 	DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END, __func__);
 }
@@ -2524,6 +2528,7 @@ wpi_cmd2(struct wpi_softc *sc, struct wp
 
 	if (ring->qid < WPI_CMD_QUEUE_NUM) {
 		/* Mark TX ring as full if we reach a certain threshold. */
+		WPI_TXQ_STATE_LOCK(sc);
 		if (++ring->queued > WPI_TX_RING_HIMARK) {
 			sc->qfullmsk |= 1 << ring->qid;
 
@@ -2533,6 +2538,7 @@ wpi_cmd2(struct wpi_softc *sc, struct wp
 		}
 
 		callout_reset(&sc->tx_timeout, 5*hz, wpi_tx_timeout, sc);
+		WPI_TXQ_STATE_UNLOCK(sc);
 	}
 
 	DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END, __func__);
@@ -5277,7 +5283,9 @@ wpi_stop_locked(struct wpi_softc *sc)
 	sc->txq_active = 0;
 	WPI_TXQ_UNLOCK(sc);
 
+	WPI_TXQ_STATE_LOCK(sc);
 	callout_stop(&sc->tx_timeout);
+	WPI_TXQ_STATE_UNLOCK(sc);
 
 	WPI_RXON_LOCK(sc);
 	callout_stop(&sc->scan_timeout);

Modified: head/sys/dev/wpi/if_wpivar.h
==============================================================================
--- head/sys/dev/wpi/if_wpivar.h	Sun Mar 15 21:24:11 2015	(r280111)
+++ head/sys/dev/wpi/if_wpivar.h	Sun Mar 15 21:25:06 2015	(r280112)
@@ -172,6 +172,7 @@ struct wpi_softc {
 
 	struct wpi_tx_ring	txq[WPI_NTXQUEUES];
 	struct mtx		txq_mtx;
+	struct mtx		txq_state_mtx;
 	uint32_t		txq_active;
 
 	struct wpi_rx_ring	rxq;
@@ -237,7 +238,14 @@ struct wpi_softc {
 	char			domain[4];	/* Regulatory domain. */
 };
 
-/* WPI_LOCK > WPI_RXON_LOCK > WPI_NT_LOCK / WPI_VAP_LOCK > WPI_TXQ_LOCK */
+/*
+ * Locking order:
+ * 1. WPI_LOCK;
+ * 2. WPI_RXON_LOCK;
+ * 3. WPI_NT_LOCK / WPI_VAP_LOCK;
+ * 4. WPI_TXQ_LOCK;
+ * 5. WPI_TXQ_STATE_LOCK;
+ */
 
 #define WPI_LOCK_INIT(_sc) \
 	mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
@@ -265,3 +273,9 @@ struct wpi_softc {
 #define WPI_TXQ_LOCK(_sc)		mtx_lock(&(_sc)->txq_mtx)
 #define WPI_TXQ_UNLOCK(_sc)		mtx_unlock(&(_sc)->txq_mtx)
 #define WPI_TXQ_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->txq_mtx)
+
+#define WPI_TXQ_STATE_LOCK_INIT(_sc) \
+	mtx_init(&(_sc)->txq_state_mtx, "txq state lock", NULL, MTX_DEF)
+#define WPI_TXQ_STATE_LOCK(_sc)		mtx_lock(&(_sc)->txq_state_mtx)
+#define WPI_TXQ_STATE_UNLOCK(_sc)	mtx_unlock(&(_sc)->txq_state_mtx)
+#define WPI_TXQ_STATE_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->txq_state_mtx)


More information about the svn-src-all mailing list