Module Name: src Committed By: msaitoh Date: Thu Mar 2 05:35:01 UTC 2017
Modified Files: src/sys/dev/pci/ixgbe: ix_txrx.c Log Message: Fix a problem that m_defrag() isn't called in if_transmit path. Now both if_start and if_transmit do m_defrag() correctly. This change improves the performance of TSO. To generate a diff of this commit: cvs rdiff -u -r1.21 -r1.22 src/sys/dev/pci/ixgbe/ix_txrx.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/ixgbe/ix_txrx.c diff -u src/sys/dev/pci/ixgbe/ix_txrx.c:1.21 src/sys/dev/pci/ixgbe/ix_txrx.c:1.22 --- src/sys/dev/pci/ixgbe/ix_txrx.c:1.21 Thu Mar 2 04:33:56 2017 +++ src/sys/dev/pci/ixgbe/ix_txrx.c Thu Mar 2 05:35:01 2017 @@ -59,7 +59,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ /*$FreeBSD: head/sys/dev/ixgbe/ix_txrx.c 301538 2016-06-07 04:51:50Z sephe $*/ -/*$NetBSD: ix_txrx.c,v 1.21 2017/03/02 04:33:56 msaitoh Exp $*/ +/*$NetBSD: ix_txrx.c,v 1.22 2017/03/02 05:35:01 msaitoh Exp $*/ #include "opt_inet.h" #include "opt_inet6.h" @@ -162,17 +162,6 @@ ixgbe_start_locked(struct tx_ring *txr, break; } IFQ_DEQUEUE(&ifp->if_snd, m_head); - if (rc == EFBIG) { - struct mbuf *mtmp; - - if ((mtmp = m_defrag(m_head, M_NOWAIT)) != NULL) { - m_head = mtmp; - rc = ixgbe_xmit(txr, m_head); - if (rc != 0) - adapter->efbig2_tx_dma_setup.ev_count++; - } else - adapter->mbuf_defrag_failed.ev_count++; - } if (rc != 0) { m_freem(m_head); continue; @@ -348,6 +337,7 @@ ixgbe_xmit(struct tx_ring *txr, struct m u32 olinfo_status = 0, cmd_type_len; int i, j, error; int first; + bool remap = TRUE; bus_dmamap_t map; struct ixgbe_tx_buf *txbuf; union ixgbe_adv_tx_desc *txd = NULL; @@ -371,10 +361,12 @@ ixgbe_xmit(struct tx_ring *txr, struct m /* * Map the packet for DMA. */ +retry: error = bus_dmamap_load_mbuf(txr->txtag->dt_dmat, map, m_head, BUS_DMA_NOWAIT); if (__predict_false(error)) { + struct mbuf *m; switch (error) { case EAGAIN: @@ -384,12 +376,25 @@ ixgbe_xmit(struct tx_ring *txr, struct m adapter->enomem_tx_dma_setup.ev_count++; return EAGAIN; case EFBIG: - /* - * XXX Try it again? - * do m_defrag() and retry bus_dmamap_load_mbuf(). - */ - adapter->efbig_tx_dma_setup.ev_count++; - return error; + /* Try it again? - one try */ + if (remap == TRUE) { + remap = FALSE; + /* + * XXX: m_defrag will choke on + * non-MCLBYTES-sized clusters + */ + adapter->efbig_tx_dma_setup.ev_count++; + m = m_defrag(m_head, M_NOWAIT); + if (m == NULL) { + adapter->mbuf_defrag_failed.ev_count++; + return ENOBUFS; + } + m_head = m; + goto retry; + } else { + adapter->efbig2_tx_dma_setup.ev_count++; + return error; + } case EINVAL: adapter->einval_tx_dma_setup.ev_count++; return error;