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 <s3er...@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) _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"