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);