Re: pppac(4) move ifnet out of KERNEL_LOCK()
Another update. The whole "while ((m = ifq_dequeue(ifq)) != NULL)" wrapped by netlock as it was made for pppx(4). This is to exclude per-packet lock/unlock in output path. 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 - 1.98 +++ sys/net/if_pppx.c 8 Aug 2020 13:28:04 - @@ -1058,7 +1058,7 @@ static intpppac_ioctl(struct ifnet *, u static int pppac_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); -static voidpppac_start(struct ifnet *); +static voidpppac_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,15 +1457,14 @@ 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) { + NET_LOCK(); + while ((m = ifq_dequeue(ifq)) != NULL) { #if NBPFILTER > 0 if (ifp->if_bpf) { bpf_mtap_af(ifp->if_bpf, m->m_pkthdr.ph_family, m, @@ -1489,9 +1486,9 @@ pppac_start(struct ifnet *ifp) mq_enqueue(&sc->sc_mq, m); /* qdrop */ } + NET_UNLOCK(); if (!mq_empty(&sc->sc_mq)) { - KERNEL_ASSERT_LOCKED(); wakeup(sc); selwakeup(&sc->sc_rsel); }
Re: pppac(4) move ifnet out of KERNEL_LOCK()
A little update. I use `ifq' passed to pppac_start() instead of `ifp->if_snd' for consistency reason. 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 - 1.98 +++ sys/net/if_pppx.c 5 Aug 2020 20:09:19 - @@ -1058,7 +1058,7 @@ static intpppac_ioctl(struct ifnet *, u static int pppac_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); -static voidpppac_start(struct ifnet *); +static voidpppac_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,15 +1457,13 @@ 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) { + while ((m = ifq_dequeue(ifq)) != NULL) { #if NBPFILTER > 0 if (ifp->if_bpf) { bpf_mtap_af(ifp->if_bpf, m->m_pkthdr.ph_family, m, @@ -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); }
pppac(4) move ifnet out of KERNEL_LOCK()
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 - 1.98 +++ sys/net/if_pppx.c 5 Aug 2020 13:53:33 - @@ -1058,7 +1058,7 @@ static intpppac_ioctl(struct ifnet *, u static int pppac_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); -static voidpppac_start(struct ifnet *); +static voidpppac_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); }