diff options
author | glebius <glebius@FreeBSD.org> | 2012-11-26 20:03:57 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2012-11-26 20:03:57 +0000 |
commit | 6a18eda622e1e5ceebf492ff86b00faf06f68257 (patch) | |
tree | b64e3b399434c943d369192c3006fd7e6352f168 /sys/dev | |
parent | ff9490f069daf7658e130826a0a67a2da9f7b589 (diff) | |
download | FreeBSD-src-6a18eda622e1e5ceebf492ff86b00faf06f68257.zip FreeBSD-src-6a18eda622e1e5ceebf492ff86b00faf06f68257.tar.gz |
drbr_enqueue() awlays consumes mbuf, no matter did it
fail or not. The mbuf pointer is no longer valid, so
can't be reused after.
Fix igb_mq_start() where mbuf pointer was used after
drbr_enqueue().
This eventually leads us to all invocations of
igb_mq_start_locked() called with third argument as NULL.
This allows us to simplify this function.
Submitted by: Karim Fodil-Lemelin <fodillemlinkarim gmail.com>
Reviewed by: jfv
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/e1000/if_igb.c | 40 |
1 files changed, 13 insertions, 27 deletions
diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c index 1318910..cf70965 100644 --- a/sys/dev/e1000/if_igb.c +++ b/sys/dev/e1000/if_igb.c @@ -181,8 +181,7 @@ static int igb_suspend(device_t); static int igb_resume(device_t); #if __FreeBSD_version >= 800000 static int igb_mq_start(struct ifnet *, struct mbuf *); -static int igb_mq_start_locked(struct ifnet *, - struct tx_ring *, struct mbuf *); +static int igb_mq_start_locked(struct ifnet *, struct tx_ring *); static void igb_qflush(struct ifnet *); static void igb_deferred_mq_start(void *, int); #else @@ -845,7 +844,7 @@ igb_resume(device_t dev) /* Process the stack queue only if not depleted */ if (((txr->queue_status & IGB_QUEUE_DEPLETED) == 0) && !drbr_empty(ifp, txr->br)) - igb_mq_start_locked(ifp, txr, NULL); + igb_mq_start_locked(ifp, txr); #else if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) igb_start_locked(txr, ifp); @@ -961,15 +960,14 @@ 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); + if (m) + drbr_enqueue(ifp, txr->br, m); + err = igb_mq_start_locked(ifp, txr); IGB_TX_UNLOCK(txr); } else { err = drbr_enqueue(ifp, txr->br, m); @@ -980,7 +978,7 @@ igb_mq_start(struct ifnet *ifp, struct mbuf *m) } static int -igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m) +igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr) { struct adapter *adapter = txr->adapter; struct mbuf *next; @@ -990,24 +988,13 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m) if (((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) || (txr->queue_status & IGB_QUEUE_DEPLETED) || - adapter->link_active == 0) { - if (m != NULL) - err = drbr_enqueue(ifp, txr->br, m); + adapter->link_active == 0) return (err); - } enq = 0; - if (m == NULL) { - next = drbr_dequeue(ifp, txr->br); - } else if (drbr_needs_enqueue(ifp, txr->br)) { - if ((err = drbr_enqueue(ifp, txr->br, m)) != 0) - return (err); - next = drbr_dequeue(ifp, txr->br); - } else - next = m; /* Process the queue */ - while (next != NULL) { + while ((next = drbr_dequeue(ifp, txr->br)) != NULL) { if ((err = igb_xmit(txr, &next)) != 0) { if (next != NULL) err = drbr_enqueue(ifp, txr->br, next); @@ -1020,7 +1007,6 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m) ETHER_BPF_MTAP(ifp, next); if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) break; - next = drbr_dequeue(ifp, txr->br); } if (enq > 0) { /* Set the watchdog */ @@ -1046,7 +1032,7 @@ igb_deferred_mq_start(void *arg, int pending) IGB_TX_LOCK(txr); if (!drbr_empty(ifp, txr->br)) - igb_mq_start_locked(ifp, txr, NULL); + igb_mq_start_locked(ifp, txr); IGB_TX_UNLOCK(txr); } @@ -1398,7 +1384,7 @@ igb_handle_que(void *context, int pending) /* Process the stack queue only if not depleted */ if (((txr->queue_status & IGB_QUEUE_DEPLETED) == 0) && !drbr_empty(ifp, txr->br)) - igb_mq_start_locked(ifp, txr, NULL); + igb_mq_start_locked(ifp, txr); #else if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) igb_start_locked(txr, ifp); @@ -1449,7 +1435,7 @@ igb_handle_link_locked(struct adapter *adapter) /* Process the stack queue only if not depleted */ if (((txr->queue_status & IGB_QUEUE_DEPLETED) == 0) && !drbr_empty(ifp, txr->br)) - igb_mq_start_locked(ifp, txr, NULL); + igb_mq_start_locked(ifp, txr); #else if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) igb_start_locked(txr, ifp); @@ -1549,7 +1535,7 @@ igb_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) } while (loop-- && more); #if __FreeBSD_version >= 800000 if (!drbr_empty(ifp, txr->br)) - igb_mq_start_locked(ifp, txr, NULL); + igb_mq_start_locked(ifp, txr); #else if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) igb_start_locked(txr, ifp); @@ -1586,7 +1572,7 @@ igb_msix_que(void *arg) /* Process the stack queue only if not depleted */ if (((txr->queue_status & IGB_QUEUE_DEPLETED) == 0) && !drbr_empty(ifp, txr->br)) - igb_mq_start_locked(ifp, txr, NULL); + igb_mq_start_locked(ifp, txr); #else if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) igb_start_locked(txr, ifp); |