diff options
author | jfv <jfv@FreeBSD.org> | 2012-08-06 20:44:05 +0000 |
---|---|---|
committer | jfv <jfv@FreeBSD.org> | 2012-08-06 20:44:05 +0000 |
commit | bfd2c5fd43d74735eb0b6328171adf065fb34158 (patch) | |
tree | 9c1cd71a69d16afca7d53d7d836825a7ee09f864 | |
parent | c1db458e02cc57d3c5d7c0f9f2f734344d3bf52b (diff) | |
download | FreeBSD-src-bfd2c5fd43d74735eb0b6328171adf065fb34158.zip FreeBSD-src-bfd2c5fd43d74735eb0b6328171adf065fb34158.tar.gz |
Correct the mq_start routine to avoid out-of-order
packet delivery, always enqueue when possible. Also
correct the DEPLETED test as multiple bits might be
set. Thanks to Randall Stewart for the changes!
-rw-r--r-- | sys/dev/e1000/if_igb.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c index d81bf0c..d147882 100644 --- a/sys/dev/e1000/if_igb.c +++ b/sys/dev/e1000/if_igb.c @@ -100,7 +100,7 @@ int igb_display_debug_stats = 0; /********************************************************************* * Driver version: *********************************************************************/ -char igb_driver_version[] = "version - 2.3.4"; +char igb_driver_version[] = "version - 2.3.5"; /********************************************************************* @@ -961,7 +961,15 @@ 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)) { - err = igb_mq_start_locked(ifp, txr, m); + 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); IGB_TX_UNLOCK(txr); } else { err = drbr_enqueue(ifp, txr->br, m); @@ -981,7 +989,7 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m) IGB_TX_LOCK_ASSERT(txr); if (((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) || - (txr->queue_status == IGB_QUEUE_DEPLETED) || + (txr->queue_status & IGB_QUEUE_DEPLETED) || adapter->link_active == 0) { if (m != NULL) err = drbr_enqueue(ifp, txr->br, m); |