The same as for pppx(4). pipex(4) and pppac(4) are ready to became a little bit more MP capable. Diff below moves pppac(4) related `ifnet' out of KERNEL_LOCK().
The wakeup(9) and selwakeup() are not require KERNEL_LOCK() so this assertion was wrong and can be dropped. Also we detach `ifnet' before pipex_iface_fini(). Index: sys/net/if_pppx.c =================================================================== RCS file: /cvs/src/sys/net/if_pppx.c,v retrieving revision 1.98 diff -u -p -r1.98 if_pppx.c --- sys/net/if_pppx.c 28 Jul 2020 09:53:36 -0000 1.98 +++ sys/net/if_pppx.c 5 Aug 2020 13:53:33 -0000 @@ -1058,7 +1058,7 @@ static int pppac_ioctl(struct ifnet *, u static int pppac_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); -static void pppac_start(struct ifnet *); +static void pppac_qstart(struct ifqueue *); static inline struct pppac_softc * pppac_lookup(dev_t dev) @@ -1107,13 +1107,11 @@ pppacopen(dev_t dev, int flags, int mode ifp->if_hdrlen = sizeof(uint32_t); /* for BPF */; ifp->if_mtu = MAXMCLBYTES - sizeof(uint32_t); ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST; - ifp->if_xflags = IFXF_CLONED; + ifp->if_xflags = IFXF_CLONED | IFXF_MPSAFE; ifp->if_rtrequest = p2p_rtrequest; /* XXX */ ifp->if_output = pppac_output; - ifp->if_start = pppac_start; + ifp->if_qstart = pppac_qstart; ifp->if_ioctl = pppac_ioctl; - /* XXXSMP: be sure pppac_start() called under NET_LOCK() */ - ifq_set_maxlen(&ifp->if_snd, 1); if_counters_alloc(ifp); if_attach(ifp); @@ -1382,10 +1380,10 @@ pppacclose(dev_t dev, int flags, int mod klist_invalidate(&sc->sc_wsel.si_note); splx(s); - pipex_iface_fini(&sc->sc_pipex_iface); - if_detach(ifp); + pipex_iface_fini(&sc->sc_pipex_iface); + LIST_REMOVE(sc, sc_entry); free(sc, M_DEVBUF, sizeof(*sc)); @@ -1459,14 +1457,12 @@ drop: } static void -pppac_start(struct ifnet *ifp) +pppac_qstart(struct ifqueue *ifq) { + struct ifnet *ifp = ifq->ifq_if; struct pppac_softc *sc = ifp->if_softc; struct mbuf *m; - if (!ISSET(ifp->if_flags, IFF_RUNNING)) - return; - while ((m = ifq_dequeue(&ifp->if_snd)) != NULL) { #if NBPFILTER > 0 if (ifp->if_bpf) { @@ -1475,8 +1471,10 @@ pppac_start(struct ifnet *ifp) } #endif + NET_LOCK(); m = pipex_output(m, m->m_pkthdr.ph_family, 0, &sc->sc_pipex_iface); + NET_UNLOCK(); if (m == NULL) continue; @@ -1491,7 +1489,6 @@ pppac_start(struct ifnet *ifp) } if (!mq_empty(&sc->sc_mq)) { - KERNEL_ASSERT_LOCKED(); wakeup(sc); selwakeup(&sc->sc_rsel); }