Author: kp
Date: Wed Jul 22 20:13:12 2020
New Revision: 363430
URL: https://svnweb.freebsd.org/changeset/base/363430

Log:
  bridge: Enter epoch for bridge_input()/bridge_output()
  
  In stable/12 epoch is not as wide as it is in head. The network stack isn't 
yet
  in epoch when bridge_input()/bridge_output() get called, so rather than assert
  this we must enter it ourselves.
  
  This is a direct commit to stable/12.
  
  PR:           248046
  Differential Revision:        https://reviews.freebsd.org/D25715

Modified:
  stable/12/sys/net/if_bridge.c

Modified: stable/12/sys/net/if_bridge.c
==============================================================================
--- stable/12/sys/net/if_bridge.c       Wed Jul 22 19:43:55 2020        
(r363429)
+++ stable/12/sys/net/if_bridge.c       Wed Jul 22 20:13:12 2020        
(r363430)
@@ -605,7 +605,7 @@ vnet_bridge_uninit(const void *unused __unused)
 
        /* Before we can destroy the uma zone, because there are callbacks that
         * use it. */
-       NET_EPOCH_WAIT();
+       epoch_drain_callbacks(net_epoch_preempt);
 
        uma_zdestroy(V_bridge_rtnode_zone);
 }
@@ -2114,17 +2114,20 @@ static int
 bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
     struct rtentry *rt)
 {
+       struct epoch_tracker et;
        struct ether_header *eh;
        struct ifnet *dst_if;
        struct bridge_softc *sc;
        uint16_t vlan;
 
-       MPASS(in_epoch(net_epoch_preempt));
+       NET_EPOCH_ENTER_ET(et);
 
        if (m->m_len < ETHER_HDR_LEN) {
                m = m_pullup(m, ETHER_HDR_LEN);
-               if (m == NULL)
+               if (m == NULL) {
+                       NET_EPOCH_EXIT_ET(et);
                        return (0);
+               }
        }
 
        eh = mtod(m, struct ether_header *);
@@ -2189,6 +2192,7 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struc
                }
                if (used == 0)
                        m_freem(m);
+               NET_EPOCH_EXIT_ET(et);
                return (0);
        }
 
@@ -2200,10 +2204,12 @@ sendunicast:
        bridge_span(sc, m);
        if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0) {
                m_freem(m);
+               NET_EPOCH_EXIT_ET(et);
                return (0);
        }
 
        bridge_enqueue(sc, dst_if, m);
+       NET_EPOCH_EXIT_ET(et);
        return (0);
 }
 
@@ -2400,6 +2406,7 @@ drop:
 static struct mbuf *
 bridge_input(struct ifnet *ifp, struct mbuf *m)
 {
+       struct epoch_tracker et;
        struct bridge_softc *sc = ifp->if_bridge;
        struct bridge_iflist *bif, *bif2;
        struct ifnet *bifp;
@@ -2408,10 +2415,12 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
        uint16_t vlan;
        int error;
 
-       MPASS(in_epoch(net_epoch_preempt));
+       NET_EPOCH_ENTER_ET(et);
 
-       if ((sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+       if ((sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+               NET_EPOCH_EXIT_ET(et);
                return (m);
+       }
 
        bifp = sc->sc_ifp;
        vlan = VLANTAGOF(m);
@@ -2428,10 +2437,12 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
                if_inc_counter(bifp, IFCOUNTER_IPACKETS, 1);
                if_inc_counter(bifp, IFCOUNTER_IBYTES, m->m_pkthdr.len);
                m_freem(m);
+               NET_EPOCH_EXIT_ET(et);
                return (NULL);
        }
        bif = bridge_lookup_member_if(sc, ifp);
        if (bif == NULL) {
+               NET_EPOCH_EXIT_ET(et);
                return (m);
        }
 
@@ -2444,11 +2455,13 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
                if (memcmp(eh->ether_dhost, bstp_etheraddr,
                    ETHER_ADDR_LEN) == 0) {
                        bstp_input(&bif->bif_stp, ifp, m); /* consumes mbuf */
+                       NET_EPOCH_EXIT_ET(et);
                        return (NULL);
                }
 
                if ((bif->bif_flags & IFBIF_STP) &&
                    bif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) {
+                       NET_EPOCH_EXIT_ET(et);
                        return (m);
                }
 
@@ -2459,6 +2472,7 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
                 */
                mc = m_dup(m, M_NOWAIT);
                if (mc == NULL) {
+                       NET_EPOCH_EXIT_ET(et);
                        return (m);
                }
 
@@ -2485,11 +2499,13 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
                }
 
                /* Return the original packet for local processing. */
+               NET_EPOCH_EXIT_ET(et);
                return (m);
        }
 
        if ((bif->bif_flags & IFBIF_STP) &&
            bif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) {
+               NET_EPOCH_EXIT_ET(et);
                return (m);
        }
 
@@ -2539,10 +2555,12 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
                            vlan, bif, 0, IFBAF_DYNAMIC);               \
                        if (error && bif->bif_addrmax) {                \
                                m_freem(m);                             \
+                               NET_EPOCH_EXIT_ET(et);                  \
                                return (NULL);                          \
                        }                                               \
                }                                                       \
                m->m_pkthdr.rcvif = iface;                              \
+               NET_EPOCH_EXIT_ET(et);                                  \
                return (m);                                             \
        }                                                               \
                                                                        \
@@ -2551,6 +2569,7 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
            OR_CARP_CHECK_WE_ARE_SRC((iface))                   \
            ) {                                                         \
                m_freem(m);                                             \
+               NET_EPOCH_EXIT_ET(et);                                  \
                return (NULL);                                          \
        }
 
@@ -2581,6 +2600,7 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
        /* Perform the bridge forwarding function. */
        bridge_forward(sc, bif, m);
 
+       NET_EPOCH_EXIT_ET(et);
        return (NULL);
 }
 
_______________________________________________
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