pair(4)'s output path can run without kernel lock just fine.
NB: Looking at CVS log, it seems this was not done during import because
IFXF_MPSSAFE became a thing afterwards.
Feedback? Objections? OK?
Index: if_pair.c
===================================================================
RCS file: /cvs/src/sys/net/if_pair.c,v
retrieving revision 1.16
diff -u -p -r1.16 if_pair.c
--- if_pair.c 21 Aug 2020 22:59:27 -0000 1.16
+++ if_pair.c 7 Jan 2021 00:20:20 -0000
@@ -37,7 +37,7 @@
void pairattach(int);
int pairioctl(struct ifnet *, u_long, caddr_t);
-void pairstart(struct ifnet *);
+void pairstart(struct ifqueue *);
int pair_clone_create(struct if_clone *, int);
int pair_clone_destroy(struct ifnet *);
int pair_media_change(struct ifnet *);
@@ -116,8 +116,8 @@ pair_clone_create(struct if_clone *ifc,
ifp->if_softc = sc;
ifp->if_ioctl = pairioctl;
- ifp->if_start = pairstart;
- ifp->if_xflags = IFXF_CLONED;
+ ifp->if_qstart = pairstart;
+ ifp->if_xflags = IFXF_CLONED | IFXF_MPSAFE;
ifp->if_hardmtu = ETHER_MAX_HARDMTU_LEN;
ifp->if_capabilities = IFCAP_VLAN_MTU;
@@ -158,8 +158,9 @@ pair_clone_destroy(struct ifnet *ifp)
}
void
-pairstart(struct ifnet *ifp)
+pairstart(struct ifqueue *ifq)
{
+ struct ifnet *ifp = ifq->ifq_if;
struct pair_softc *sc = (struct pair_softc *)ifp->if_softc;
struct mbuf_list ml = MBUF_LIST_INITIALIZER();
struct ifnet *pairedifp;
@@ -167,11 +168,7 @@ pairstart(struct ifnet *ifp)
pairedifp = if_get(sc->sc_pairedif);
- for (;;) {
- m = ifq_dequeue(&ifp->if_snd);
- if (m == NULL)
- break;
-
+ while ((m = ifq_dequeue(ifq)) != NULL) {
#if NBPFILTER > 0
if (ifp->if_bpf)
bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);