igb diver crashes in head at 241037
Karim Fodil-Lemelin
fodillemlinkarim at gmail.com
Mon Nov 19 19:57:34 UTC 2012
Hello -net,
While testing the latest igb driver in CURRENT I came across an issue
with igb_mq_start(). More specifically this code:
...
struct mbuf *pm = NULL;
/*
** Try to queue first to avoid
** out-of-order delivery, but
** settle for it if that fails
*/
if (m && drbr_enqueue(ifp, txr->br, m))
pm = m;
err = igb_mq_start_locked(ifp, txr, pm);
...
The problem comes from the fact that drbr_enqueue() can return an error
and delete the mbuf as seen in drbr_enqueue():
...
error = buf_ring_enqueue(br, m);
if (error)
m_freem(m);
...
When this happens pm is set to m then igb_mq_start_locked() will enqueue
an already freed mbuf with the outcome you can imagine.
When I reverted only that part of r241037 that problem disappeared. I
have attached a patch for those interested.
Best regards,
Karim.
-------------- next part --------------
diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c
index 1318910..be1719a 100644
--- a/sys/dev/e1000/if_igb.c
+++ b/sys/dev/e1000/if_igb.c
@@ -961,15 +961,7 @@ igb_mq_start(struct ifnet *ifp, struct mbuf *m)
que = &adapter->queues[i];
if (((txr->queue_status & IGB_QUEUE_DEPLETED) == 0) &&
IGB_TX_TRYLOCK(txr)) {
- struct mbuf *pm = NULL;
- /*
- ** Try to queue first to avoid
- ** out-of-order delivery, but
- ** settle for it if that fails
- */
- if (m && drbr_enqueue(ifp, txr->br, m))
- pm = m;
- err = igb_mq_start_locked(ifp, txr, pm);
+ err = igb_mq_start_locked(ifp, txr, m);
IGB_TX_UNLOCK(txr);
} else {
err = drbr_enqueue(ifp, txr->br, m);
More information about the freebsd-net
mailing list