summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2018-03-26 21:03:33 +0000
committerhselasky <hselasky@FreeBSD.org>2018-03-26 21:03:33 +0000
commitc13ebd3912c502d563c09cbd783d449a57211957 (patch)
tree0a2650f983415e04730b654e43ca85549f2afee6
parent2f448c4e181ba811f497129792af64e2f84358ff (diff)
downloadFreeBSD-src-c13ebd3912c502d563c09cbd783d449a57211957.zip
FreeBSD-src-c13ebd3912c502d563c09cbd783d449a57211957.tar.gz
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
-rw-r--r--sys/dev/mlx5/mlx5_en/mlx5_en_tx.c30
1 files changed, 12 insertions, 18 deletions
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c b/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c
index 6f20bd1..69b0a01 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c
@@ -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);
@@ -369,10 +367,6 @@ skip_dma:
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 */
return (0);
OpenPOWER on IntegriCloud