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);
}