rtwn: narrow the epoch area
Rather than placing the epoch around the entire receive loop which might call into rtwn_rx_frame() and USB and sleep, split the loop into two[1] and leave us with one unlock/lock cycle as well. PR: 249925 Reported by: thj, (rkoberman gmail.com) Tested by: thj Suggested by: adrian [1] Reviewed by: adrian MFC after: 3 days Sponsored by: The FreeBSD Foundation (initially, paniced my iwl lab host) Differential Revision: https://reviews.freebsd.org/D26554
This commit is contained in:
parent
6186bfbd18
commit
3917c9ba65
@ -368,7 +368,7 @@ rtwn_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
|
||||
struct rtwn_softc *sc = &uc->uc_sc;
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct ieee80211_node *ni;
|
||||
struct mbuf *m = NULL, *next;
|
||||
struct mbuf *m0, *m = NULL, *next;
|
||||
struct rtwn_data *data;
|
||||
|
||||
RTWN_ASSERT_LOCKED(sc);
|
||||
@ -400,24 +400,30 @@ rtwn_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
|
||||
* ieee80211_input() because here is at the end of a USB
|
||||
* callback and safe to unlock.
|
||||
*/
|
||||
m0 = m;
|
||||
while (m != NULL) {
|
||||
M_ASSERTPKTHDR(m);
|
||||
m->m_pkthdr.PH_loc.ptr = rtwn_rx_frame(sc, m);
|
||||
m = m->m_nextpkt;
|
||||
}
|
||||
NET_EPOCH_ENTER(et);
|
||||
RTWN_UNLOCK(sc);
|
||||
m = m0;
|
||||
while (m != NULL) {
|
||||
next = m->m_nextpkt;
|
||||
m->m_nextpkt = NULL;
|
||||
|
||||
ni = rtwn_rx_frame(sc, m);
|
||||
|
||||
RTWN_UNLOCK(sc);
|
||||
|
||||
ni = m->m_pkthdr.PH_loc.ptr;
|
||||
m->m_pkthdr.PH_loc.ptr = NULL;
|
||||
if (ni != NULL) {
|
||||
(void)ieee80211_input_mimo(ni, m);
|
||||
ieee80211_free_node(ni);
|
||||
} else {
|
||||
(void)ieee80211_input_mimo_all(ic, m);
|
||||
}
|
||||
RTWN_LOCK(sc);
|
||||
m = next;
|
||||
}
|
||||
RTWN_LOCK(sc);
|
||||
NET_EPOCH_EXIT(et);
|
||||
break;
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user