Author: bz
Date: Tue Sep 29 20:46:25 2020
New Revision: 366268
URL: https://svnweb.freebsd.org/changeset/base/366268

Log:
  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

Modified:
  head/sys/dev/rtwn/usb/rtwn_usb_rx.c

Modified: head/sys/dev/rtwn/usb/rtwn_usb_rx.c
==============================================================================
--- head/sys/dev/rtwn/usb/rtwn_usb_rx.c Tue Sep 29 20:29:07 2020        
(r366267)
+++ head/sys/dev/rtwn/usb/rtwn_usb_rx.c Tue Sep 29 20:46:25 2020        
(r366268)
@@ -368,7 +368,7 @@ rtwn_bulk_rx_callback(struct usb_xfer *xfer, usb_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 @@ tr_setup:
                 * 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:
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to