Author: bz
Date: Thu Nov  5 15:27:38 2020
New Revision: 367385
URL: https://svnweb.freebsd.org/changeset/base/367385

Log:
  MFC r366268 (and epoch parts of r357093):
  
   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 and leave us with one unlock/lock cycle as well.
  
  PR:           249925

Modified:
  stable/12/sys/dev/rtwn/usb/rtwn_usb_rx.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/dev/rtwn/usb/rtwn_usb_rx.c
==============================================================================
--- stable/12/sys/dev/rtwn/usb/rtwn_usb_rx.c    Thu Nov  5 15:08:56 2020        
(r367384)
+++ stable/12/sys/dev/rtwn/usb/rtwn_usb_rx.c    Thu Nov  5 15:27:38 2020        
(r367385)
@@ -363,11 +363,12 @@ rtwn_rx_frame(struct rtwn_softc *sc, struct mbuf *m)
 void
 rtwn_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
 {
+       struct epoch_tracker et;
        struct rtwn_usb_softc *uc = usbd_xfer_softc(xfer);
        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);
@@ -399,23 +400,31 @@ 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(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(et);
                break;
        default:
                /* needs it to the inactive queue due to a error. */
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to