From 5effcbfd6c7706c69b3fbe29fdd5fa05cf39e55a Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sun, 15 Mar 2015 21:26:22 +0000 Subject: [PATCH] Add another lock for the TX path. PR: kern/197143 Submitted by: Andriy Voskoboinyk --- sys/dev/wpi/if_wpi.c | 16 +++++++++------- sys/dev/wpi/if_wpivar.h | 14 +++++++++++--- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c index 226ae3d55c47..f34efef6119e 100644 --- a/sys/dev/wpi/if_wpi.c +++ b/sys/dev/wpi/if_wpi.c @@ -396,6 +396,7 @@ wpi_attach(device_t dev) } WPI_LOCK_INIT(sc); + WPI_TX_LOCK_INIT(sc); WPI_RXON_LOCK_INIT(sc); WPI_NT_LOCK_INIT(sc); WPI_TXQ_LOCK_INIT(sc); @@ -726,6 +727,7 @@ wpi_detach(device_t dev) WPI_TXQ_LOCK_DESTROY(sc); WPI_NT_LOCK_DESTROY(sc); WPI_RXON_LOCK_DESTROY(sc); + WPI_TX_LOCK_DESTROY(sc); WPI_LOCK_DESTROY(sc); return 0; } @@ -2845,7 +2847,7 @@ wpi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return ENETDOWN; } - WPI_LOCK(sc); + WPI_TX_LOCK(sc); if (params == NULL) { /* * Legacy path; interpret frame contents to decide @@ -2859,7 +2861,7 @@ wpi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, */ error = wpi_tx_data_raw(sc, m, ni, params); } - WPI_UNLOCK(sc); + WPI_TX_UNLOCK(sc); if (error != 0) { /* NB: m is reclaimed on tx failure */ @@ -2886,7 +2888,7 @@ wpi_start(struct ifnet *ifp) struct ieee80211_node *ni; struct mbuf *m; - WPI_LOCK(sc); + WPI_TX_LOCK(sc); DPRINTF(sc, WPI_DEBUG_XMIT, "%s: called\n", __func__); for (;;) { @@ -2903,15 +2905,13 @@ wpi_start(struct ifnet *ifp) break; ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; if (wpi_tx_data(sc, m, ni) != 0) { - WPI_UNLOCK(sc); ieee80211_free_node(ni); - WPI_LOCK(sc); if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); } } DPRINTF(sc, WPI_DEBUG_XMIT, "%s: done\n", __func__); - WPI_UNLOCK(sc); + WPI_TX_UNLOCK(sc); } static void @@ -5350,9 +5350,11 @@ wpi_set_channel(struct ieee80211com *ic) WPI_LOCK(sc); sc->sc_rxtap.wr_chan_freq = htole16(c->ic_freq); sc->sc_rxtap.wr_chan_flags = htole16(c->ic_flags); + WPI_UNLOCK(sc); + WPI_TX_LOCK(sc); sc->sc_txtap.wt_chan_freq = htole16(c->ic_freq); sc->sc_txtap.wt_chan_flags = htole16(c->ic_flags); - WPI_UNLOCK(sc); + WPI_TX_UNLOCK(sc); /* * Only need to set the channel in Monitor mode. AP scanning and auth diff --git a/sys/dev/wpi/if_wpivar.h b/sys/dev/wpi/if_wpivar.h index bcfc8b89dcb9..66a9f050d81b 100644 --- a/sys/dev/wpi/if_wpivar.h +++ b/sys/dev/wpi/if_wpivar.h @@ -165,6 +165,7 @@ struct wpi_softc { int sc_debug; struct mtx sc_mtx; + struct mtx tx_mtx; /* Shared area. */ struct wpi_dma_info shared_dma; @@ -242,9 +243,10 @@ struct wpi_softc { * 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; + * 3. WPI_TX_LOCK; + * 4. WPI_NT_LOCK / WPI_VAP_LOCK; + * 5. WPI_TXQ_LOCK; + * 6. WPI_TXQ_STATE_LOCK; */ #define WPI_LOCK_INIT(_sc) \ @@ -262,6 +264,12 @@ struct wpi_softc { #define WPI_RXON_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->rxon_mtx, MA_OWNED) #define WPI_RXON_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->rxon_mtx) +#define WPI_TX_LOCK_INIT(_sc) \ + mtx_init(&(_sc)->tx_mtx, "tx path lock", NULL, MTX_DEF) +#define WPI_TX_LOCK(_sc) mtx_lock(&(_sc)->tx_mtx) +#define WPI_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->tx_mtx) +#define WPI_TX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->tx_mtx) + #define WPI_NT_LOCK_INIT(_sc) \ mtx_init(&(_sc)->nt_mtx, "node table lock", NULL, MTX_DEF) #define WPI_NT_LOCK(_sc) mtx_lock(&(_sc)->nt_mtx)