svn commit: r330658 - head/sys/dev/mlx5/mlx5_en

Hans Petter Selasky hselasky at FreeBSD.org
Thu Mar 8 15:53:05 UTC 2018


Author: hselasky
Date: Thu Mar  8 15:53:04 2018
New Revision: 330658
URL: https://svnweb.freebsd.org/changeset/base/330658

Log:
  Fix mlx5en(4) driver to properly call m_defrag().
  
  When the mlx5en(4) driver was converted to using BUSDMA(9) the call to
  m_defrag() was moved after the part of the TX routine that strips the
  header from the mbuf chain. Before it called m_defrag it first trimmed
  off the now-empty mbufs from the start of the chain. This has the side
  effect of also removing the head of the chain that has M_PKTHDR set.
  m_defrag() will not defrag a chain that does not have M_PKTHDR set,
  thus it was effectively never defragging the mbuf chains.
  
  As it turns out, trimming the mbufs in this fashion is unnecessary since
  the call to bus_dmamap_load_mbuf_sg doesn't map empty mbufs anyway, so
  remove it.
  
  Differential Revision:	https://reviews.freebsd.org/D12050
  Submitted by:	mjoras@
  MFC after:	1 week
  Sponsored by:	Mellanox Technologies

Modified:
  head/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c

Modified: head/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c
==============================================================================
--- head/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c	Thu Mar  8 15:47:17 2018	(r330657)
+++ head/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c	Thu Mar  8 15:53:04 2018	(r330658)
@@ -311,22 +311,9 @@ mlx5e_sq_xmit(struct mlx5e_sq *sq, struct mbuf **mbp)
 	}
 	dseg = ((struct mlx5_wqe_data_seg *)&wqe->ctrl) + ds_cnt;
 
-	/* Trim off empty mbufs */
-	while (mb->m_len == 0) {
-		mb = m_free(mb);
-		/* Check if all data has been inlined */
-		if (mb == NULL)
-			goto skip_dma;
-	}
-
 	err = bus_dmamap_load_mbuf_sg(sq->dma_tag, sq->mbuf[pi].dma_map,
 	    mb, segs, &nsegs, BUS_DMA_NOWAIT);
 	if (err == EFBIG) {
-		/*
-		 * Update *mbp before defrag in case it was trimmed in the
-		 * loop above
-		 */
-		*mbp = mb;
 		/* Update statistics */
 		sq->stats.defragged++;
 		/* Too many mbuf fragments */
@@ -343,6 +330,17 @@ mlx5e_sq_xmit(struct mlx5e_sq *sq, struct mbuf **mbp)
 	if (err != 0)
 		goto tx_drop;
 
+	/* Make sure all mbuf data, if any, is written to RAM */
+	if (nsegs != 0) {
+		bus_dmamap_sync(sq->dma_tag, sq->mbuf[pi].dma_map,
+		    BUS_DMASYNC_PREWRITE);
+	} else {
+		/* All data was inlined, free the mbuf. */
+		bus_dmamap_unload(sq->dma_tag, sq->mbuf[pi].dma_map);
+		m_freem(mb);
+		mb = NULL;
+	}
+
 	for (x = 0; x != nsegs; x++) {
 		if (segs[x].ds_len == 0)
 			continue;
@@ -351,7 +349,7 @@ mlx5e_sq_xmit(struct mlx5e_sq *sq, struct mbuf **mbp)
 		dseg->byte_count = cpu_to_be32((uint32_t)segs[x].ds_len);
 		dseg++;
 	}
-skip_dma:
+
 	ds_cnt = (dseg - ((struct mlx5_wqe_data_seg *)&wqe->ctrl));
 
 	wqe->ctrl.opmod_idx_opcode = cpu_to_be32((sq->pc << 8) | opcode);
@@ -368,10 +366,6 @@ skip_dma:
 	sq->mbuf[pi].mbuf = mb;
 	sq->mbuf[pi].num_wqebbs = DIV_ROUND_UP(ds_cnt, MLX5_SEND_WQEBB_NUM_DS);
 	sq->pc += sq->mbuf[pi].num_wqebbs;
-
-	/* Make sure all mbuf data is written to RAM */
-	if (mb != NULL)
-		bus_dmamap_sync(sq->dma_tag, sq->mbuf[pi].dma_map, BUS_DMASYNC_PREWRITE);
 
 	sq->stats.packets++;
 	*mbp = NULL;	/* safety clear */


More information about the svn-src-head mailing list