On Tue, May 30, 2017 at 01:04:07PM +0000, Visa Hankala wrote: > On Mon, May 29, 2017 at 03:33:35PM +0000, Visa Hankala wrote: > > Currently, access to pflow's sc_outputqueue is not serialized properly. > > The producer has the NET_LOCK(), while the consumer does not. > > mpi@ suggested using mbuf_queue to solve the issue. > > mpi@ commented that the pflow output task should be scheduled only > if mq_enqueue succeeds. > > Another issue is that mbuf_queue has a size limit. If a lot of flows > get exported at once, the queue might become full, dropping pflow data. > To make this less likely, I tweaked the limit from 256 (IFQ_MAXLEN) to > 8192. Of course, packet loss can happen in many other places as well. > > Updated patch below. OK? > > 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.