On Wed, May 31, 2017 at 01:52:31AM +1000, Jonathan Matthew wrote: > On Tue, May 30, 2017 at 01:04:07PM +0000, Visa Hankala wrote: > > Index: net/if_pflow.c > > =================================================================== > > RCS file: src/sys/net/if_pflow.c,v > > retrieving revision 1.78 > > diff -u -p -r1.78 if_pflow.c > > --- net/if_pflow.c 27 May 2017 21:44:22 -0000 1.78 > > +++ net/if_pflow.c 30 May 2017 12:40:26 -0000 > > @@ -132,7 +132,7 @@ pflow_output_process(void *arg) > > struct mbuf *m; > > > > KERNEL_LOCK(); > > - while ((m = ml_dequeue(&sc->sc_outputqueue)) != NULL) { > > + while ((m = mq_dequeue(&sc->sc_outputqueue)) != NULL) { > > pflow_sendout_mbuf(sc, m); > > } > > KERNEL_UNLOCK(); > > I'd suggest using mq_delist here rather than dequeueing each mbuf > individually, so you only take the mbuf_queue mutex once per call.
Right. Updated patch below. Index: net/if_pflow.c =================================================================== RCS file: src/sys/net/if_pflow.c,v retrieving revision 1.78 diff -u -p -r1.78 if_pflow.c --- net/if_pflow.c 27 May 2017 21:44:22 -0000 1.78 +++ net/if_pflow.c 30 May 2017 15:57:44 -0000 @@ -128,11 +128,13 @@ pflow_output(struct ifnet *ifp, struct m void pflow_output_process(void *arg) { + struct mbuf_list ml; struct pflow_softc *sc = arg; struct mbuf *m; + mq_delist(&sc->sc_outputqueue, &ml); KERNEL_LOCK(); - while ((m = ml_dequeue(&sc->sc_outputqueue)) != NULL) { + while ((m = ml_dequeue(&ml)) != NULL) { pflow_sendout_mbuf(sc, m); } KERNEL_UNLOCK(); @@ -256,7 +258,7 @@ pflow_clone_create(struct if_clone *ifc, ifp->if_hdrlen = PFLOW_HDRLEN; ifp->if_flags = IFF_UP; ifp->if_flags &= ~IFF_RUNNING; /* not running, need receiver */ - ml_init(&pflowif->sc_outputqueue); + mq_init(&pflowif->sc_outputqueue, 8192, IPL_SOFTNET); pflow_setmtu(pflowif, ETHERMTU); pflow_init_timeouts(pflowif); if_attach(ifp); @@ -288,7 +290,7 @@ pflow_clone_destroy(struct ifnet *ifp) timeout_del(&sc->sc_tmo_tmpl); pflow_flush(sc); task_del(softnettq, &sc->sc_outputtask); - ml_purge(&sc->sc_outputqueue); + mq_purge(&sc->sc_outputqueue); m_freem(sc->send_nam); if (sc->so != NULL) { error = soclose(sc->so); @@ -1089,8 +1091,8 @@ pflow_sendout_v5(struct pflow_softc *sc) getnanotime(&tv); h->time_sec = htonl(tv.tv_sec); /* XXX 2038 */ h->time_nanosec = htonl(tv.tv_nsec); - ml_enqueue(&sc->sc_outputqueue, m); - task_add(softnettq, &sc->sc_outputtask); + if (mq_enqueue(&sc->sc_outputqueue, m) == 0) + task_add(softnettq, &sc->sc_outputtask); return (0); } @@ -1151,8 +1153,8 @@ pflow_sendout_ipfix(struct pflow_softc * h10->flow_sequence = htonl(sc->sc_sequence); sc->sc_sequence += count; h10->observation_dom = htonl(PFLOW_ENGINE_TYPE); - ml_enqueue(&sc->sc_outputqueue, m); - task_add(softnettq, &sc->sc_outputtask); + if (mq_enqueue(&sc->sc_outputqueue, m) == 0) + task_add(softnettq, &sc->sc_outputtask); return (0); } @@ -1193,8 +1195,8 @@ pflow_sendout_ipfix_tmpl(struct pflow_so h10->observation_dom = htonl(PFLOW_ENGINE_TYPE); timeout_add_sec(&sc->sc_tmo_tmpl, PFLOW_TMPL_TIMEOUT); - ml_enqueue(&sc->sc_outputqueue, m); - task_add(softnettq, &sc->sc_outputtask); + if (mq_enqueue(&sc->sc_outputqueue, m) == 0) + task_add(softnettq, &sc->sc_outputtask); return (0); } Index: net/if_pflow.h =================================================================== RCS file: src/sys/net/if_pflow.h,v retrieving revision 1.16 diff -u -p -r1.16 if_pflow.h --- net/if_pflow.h 27 May 2017 21:06:06 -0000 1.16 +++ net/if_pflow.h 30 May 2017 15:57:44 -0000 @@ -184,7 +184,7 @@ struct pflow_softc { struct timeout sc_tmo; struct timeout sc_tmo6; struct timeout sc_tmo_tmpl; - struct mbuf_list sc_outputqueue; + struct mbuf_queue sc_outputqueue; struct task sc_outputtask; struct socket *so; struct mbuf *send_nam;