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;

Reply via email to