On Mon, May 29, 2017 at 14:16 +0200, Mike Belopuhov wrote: > Thanks for taking your time to test, but unfortunately I have to > withdraw both diffs. I've realised that there's a ton of drivers > calling ifq_deq_begin manually from their start routines and > there's no simple solution for that that I can find right now. > > I'll try to come up with something that works for all cases ASAP.
Here you go. KERNEL_ASSERT_LOCKED might be better written as NET_ASSERT_LOCKED for the future. I'm not sure I want to keep it there though as it's additional code in a hot path. diff --git sys/net/ifq.c sys/net/ifq.c index d37be87f444..bad95c840ff 100644 --- sys/net/ifq.c +++ sys/net/ifq.c @@ -313,18 +313,28 @@ ifq_deq_commit(struct ifqueue *ifq, struct mbuf *m) cookie = m->m_pkthdr.ph_cookie; ifq->ifq_ops->ifqop_deq_commit(ifq, m, cookie); ifq->ifq_len--; mtx_leave(&ifq->ifq_mtx); + + if (ifq->ifq_serializer == NULL) { + KERNEL_ASSERT_LOCKED(); + ml_purge(&ifq->ifq_free); + } } void ifq_deq_rollback(struct ifqueue *ifq, struct mbuf *m) { KASSERT(m != NULL); mtx_leave(&ifq->ifq_mtx); + + if (ifq->ifq_serializer == NULL) { + KERNEL_ASSERT_LOCKED(); + ml_purge(&ifq->ifq_free); + } } struct mbuf * ifq_dequeue(struct ifqueue *ifq) { @@ -379,21 +389,21 @@ ifq_q_leave(struct ifqueue *ifq, void *q) } void ifq_mfreem(struct ifqueue *ifq, struct mbuf *m) { - IFQ_ASSERT_SERIALIZED(ifq); + /* IFQ_ASSERT_SERIALIZED(ifq); */ ifq->ifq_len--; ifq->ifq_qdrops++; ml_enqueue(&ifq->ifq_free, m); } void ifq_mfreeml(struct ifqueue *ifq, struct mbuf_list *ml) { - IFQ_ASSERT_SERIALIZED(ifq); + /* IFQ_ASSERT_SERIALIZED(ifq); */ ifq->ifq_len -= ml_len(ml); ifq->ifq_qdrops += ml_len(ml); ml_enlist(&ifq->ifq_free, ml); }