Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Jul 2020 20:13:13 +0000 (UTC)
From:      Kristof Provost <kp@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r363430 - stable/12/sys/net
Message-ID:  <202007222013.06MKDD85032681@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202007222013.06MKDD85032681>