We can not call iwn_start directly in the interrupt
context, where the iwn mutex is being held, and iwn_start assumes that we do not have that mutex held. Resolve this issue with what we do for other NICs by splitting the iwn_start procedure into two parts, iwn_start() do the locking, and iwn_start_locked() assumes that the mutex is being held. This resolves panic when WITNESS is enabled.
This commit is contained in:
parent
ed5a2ac45c
commit
9f2c7365ab
@ -138,6 +138,7 @@ uint8_t iwn_plcp_signal(int);
|
||||
int iwn_tx_data(struct iwn_softc *, struct mbuf *,
|
||||
struct ieee80211_node *, struct iwn_tx_ring *);
|
||||
void iwn_start(struct ifnet *);
|
||||
void iwn_start_locked(struct ifnet *);
|
||||
static int iwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
|
||||
const struct ieee80211_bpf_params *);
|
||||
static void iwn_watchdog(struct iwn_softc *);
|
||||
@ -1627,7 +1628,7 @@ iwn_tx_intr(struct iwn_softc *sc, struct iwn_rx_desc *desc)
|
||||
|
||||
sc->sc_tx_timer = 0;
|
||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
iwn_start(ifp);
|
||||
iwn_start_locked(ifp);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2090,6 +2091,16 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
|
||||
|
||||
void
|
||||
iwn_start(struct ifnet *ifp)
|
||||
{
|
||||
struct iwn_softc *sc = ifp->if_softc;
|
||||
|
||||
IWN_LOCK(sc);
|
||||
iwn_start_locked(ifp);
|
||||
IWN_UNLOCK(sc);
|
||||
}
|
||||
|
||||
void
|
||||
iwn_start_locked(struct ifnet *ifp)
|
||||
{
|
||||
struct iwn_softc *sc = ifp->if_softc;
|
||||
struct ieee80211_node *ni;
|
||||
@ -2097,6 +2108,8 @@ iwn_start(struct ifnet *ifp)
|
||||
struct mbuf *m;
|
||||
int pri;
|
||||
|
||||
IWN_LOCK_ASSERT(sc);
|
||||
|
||||
for (;;) {
|
||||
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
|
||||
if (m == NULL)
|
||||
@ -2110,7 +2123,6 @@ iwn_start(struct ifnet *ifp)
|
||||
ieee80211_free_node(ni);
|
||||
continue;
|
||||
}
|
||||
IWN_LOCK(sc);
|
||||
if (txq->queued >= IWN_TX_RING_COUNT - 8) {
|
||||
/* XXX not right */
|
||||
/* ring is nearly full, stop flow */
|
||||
@ -2122,7 +2134,6 @@ iwn_start(struct ifnet *ifp)
|
||||
IWN_UNLOCK(sc);
|
||||
break;
|
||||
}
|
||||
IWN_UNLOCK(sc);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user