Author: hselasky
Date: Mon Mar 26 21:03:33 2018
New Revision: 331589
URL: https://svnweb.freebsd.org/changeset/base/331589

Log:
  MFC r330658:
  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@
  Sponsored by: Mellanox Technologies

Modified:
  stable/11/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c
==============================================================================
--- stable/11/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c Mon Mar 26 21:02:20 2018        
(r331588)
+++ stable/11/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c Mon Mar 26 21:03:33 2018        
(r331589)
@@ -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 */
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to