From: Dragos Tatulea net_iovs should have the dma address set to 0 so that netmem_dma_unmap_page_attrs() correctly skips the unmap. This was not done in mlx5 when support for devmem tx was added and resulted in the splat below when the platform iommu was enabled. This patch addresses the issue by using netmem_dma_unmap_addr_set() which handles the net_iov case when setting the dma address. A small refactoring of mlx5e_dma_push() was required to be able to use this API. The function was split in two versions and each version called accordingly. Note that netmem_dma_unmap_addr_set() introduces an additional if case. Splat: WARNING: CPU: 14 PID: 2587 at drivers/iommu/dma-iommu.c:1228 iommu_dma_unmap_page+0x7d/0x90 Modules linked in: [...] Unloaded tainted modules: i10nm_edac(E):1 fjes(E):1 CPU: 14 UID: 0 PID: 2587 Comm: ncdevmem Tainted: G S E 6.15.0+ #3 PREEMPT(voluntary) Tainted: [S]=CPU_OUT_OF_SPEC, [E]=UNSIGNED_MODULE Hardware name: HPE ProLiant DL380 Gen10 Plus/ProLiant DL380 Gen10 Plus, BIOS U46 06/01/2022 RIP: 0010:iommu_dma_unmap_page+0x7d/0x90 Code: [...] RSP: 0000:ff6b1e3ea0b2fc58 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ff46ef2d0a2340c8 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000001 RBP: 0000000000000001 R08: 0000000000000000 R09: ffffffff8827a120 R10: 0000000000000000 R11: 0000000000000000 R12: 00000000d8000000 R13: 0000000000000008 R14: 0000000000000001 R15: 0000000000000000 FS: 00007feb69adf740(0000) GS:ff46ef2c779f1000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007feb69cca000 CR3: 0000000154b97006 CR4: 0000000000773ef0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: dma_unmap_page_attrs+0x227/0x250 mlx5e_poll_tx_cq+0x163/0x510 [mlx5_core] mlx5e_napi_poll+0x94/0x720 [mlx5_core] __napi_poll+0x28/0x1f0 net_rx_action+0x33a/0x420 ? mlx5e_completion_event+0x3d/0x40 [mlx5_core] handle_softirqs+0xe8/0x2f0 __irq_exit_rcu+0xcd/0xf0 common_interrupt+0x47/0xa0 asm_common_interrupt+0x26/0x40 RIP: 0033:0x7feb69cd08ec Code: [...] RSP: 002b:00007ffc01b8c880 EFLAGS: 00000246 RAX: 00000000c3a60cf7 RBX: 0000000000045e12 RCX: 000000000000000e RDX: 00000000000035b4 RSI: 0000000000000000 RDI: 00007ffc01b8c8c0 RBP: 00007ffc01b8c8b0 R08: 0000000000000000 R09: 0000000000000064 R10: 00007ffc01b8c8c0 R11: 0000000000000000 R12: 00007feb69cca000 R13: 00007ffc01b90e48 R14: 0000000000427e18 R15: 00007feb69d07000 Cc: Mina Almasry Reported-by: Stanislav Fomichev Closes: https://lore.kernel.org/all/aFM6r9kFHeTdj-25@mini-arch/ Fixes: 5a842c288cfa ("net/mlx5e: Add TX support for netmems") Signed-off-by: Dragos Tatulea Reviewed-by: Carolina Jubran Signed-off-by: Tariq Toukan --- .../net/ethernet/mellanox/mlx5/core/en/txrx.h | 16 +++++++++++++--- .../mellanox/mlx5/core/en_accel/ktls_tx.c | 2 +- drivers/net/ethernet/mellanox/mlx5/core/en_tx.c | 6 +++--- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h index 6501252359b0..5dc04bbfc71b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h @@ -322,14 +322,24 @@ mlx5e_dma_get(struct mlx5e_txqsq *sq, u32 i) } static inline void -mlx5e_dma_push(struct mlx5e_txqsq *sq, dma_addr_t addr, u32 size, - enum mlx5e_dma_map_type map_type) +mlx5e_dma_push_single(struct mlx5e_txqsq *sq, dma_addr_t addr, u32 size) { struct mlx5e_sq_dma *dma = mlx5e_dma_get(sq, sq->dma_fifo_pc++); dma->addr = addr; dma->size = size; - dma->type = map_type; + dma->type = MLX5E_DMA_MAP_SINGLE; +} + +static inline void +mlx5e_dma_push_netmem(struct mlx5e_txqsq *sq, netmem_ref netmem, + dma_addr_t addr, u32 size) +{ + struct mlx5e_sq_dma *dma = mlx5e_dma_get(sq, sq->dma_fifo_pc++); + + netmem_dma_unmap_addr_set(netmem, dma, addr, addr); + dma->size = size; + dma->type = MLX5E_DMA_MAP_PAGE; } static inline diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c index 3db31cc10719..08f06984407b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c @@ -744,7 +744,7 @@ tx_post_resync_dump(struct mlx5e_txqsq *sq, skb_frag_t *frag, u32 tisn) dseg->addr = cpu_to_be64(dma_addr); dseg->lkey = sq->mkey_be; dseg->byte_count = cpu_to_be32(fsz); - mlx5e_dma_push(sq, dma_addr, fsz, MLX5E_DMA_MAP_PAGE); + mlx5e_dma_push_netmem(sq, skb_frag_netmem(frag), dma_addr, fsz); tx_fill_wi(sq, pi, MLX5E_KTLS_DUMP_WQEBBS, fsz, skb_frag_page(frag)); sq->pc += MLX5E_KTLS_DUMP_WQEBBS; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c index e6a301ba3254..319061d31602 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c @@ -196,7 +196,7 @@ mlx5e_txwqe_build_dsegs(struct mlx5e_txqsq *sq, struct sk_buff *skb, dseg->lkey = sq->mkey_be; dseg->byte_count = cpu_to_be32(headlen); - mlx5e_dma_push(sq, dma_addr, headlen, MLX5E_DMA_MAP_SINGLE); + mlx5e_dma_push_single(sq, dma_addr, headlen); num_dma++; dseg++; } @@ -214,7 +214,7 @@ mlx5e_txwqe_build_dsegs(struct mlx5e_txqsq *sq, struct sk_buff *skb, dseg->lkey = sq->mkey_be; dseg->byte_count = cpu_to_be32(fsz); - mlx5e_dma_push(sq, dma_addr, fsz, MLX5E_DMA_MAP_PAGE); + mlx5e_dma_push_netmem(sq, skb_frag_netmem(frag), dma_addr, fsz); num_dma++; dseg++; } @@ -616,7 +616,7 @@ mlx5e_sq_xmit_mpwqe(struct mlx5e_txqsq *sq, struct sk_buff *skb, sq->stats->xmit_more += xmit_more; - mlx5e_dma_push(sq, txd.dma_addr, txd.len, MLX5E_DMA_MAP_SINGLE); + mlx5e_dma_push_single(sq, txd.dma_addr, txd.len); mlx5e_skb_fifo_push(&sq->db.skb_fifo, skb); mlx5e_tx_mpwqe_add_dseg(sq, &txd); mlx5e_tx_skb_update_ts_flags(skb); base-commit: c3886ccaadf8fdc2c91bfbdcdca36ccdc6ef8f70 -- 2.31.1