Add an extra mutex for qfullmsk / ring->queued variables.
PR: kern/197143 Submitted by: Andriy Voskoboinyk <s3erios@gmail.com>
This commit is contained in:
parent
a6b6ca52c6
commit
fc5870b418
@ -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 wpi_rx_desc *desc)
|
||||
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 wpi_rx_desc *desc)
|
||||
}
|
||||
} 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 wpi_buf *buf)
|
||||
|
||||
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 wpi_buf *buf)
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user