Skip to content

Commit ea5b7ff

Browse files
author
Mohammad Kabat
committed
net/mlx5e: Ring the TX doorbell on DMA errors
Bugzilla: https://bugzilla.redhat.com/2112940 Upstream-status: v5.19-rc7 commit 5b759bf Author: Maxim Mikityanskiy <maximmi@nvidia.com> Date: Mon May 30 14:01:37 2022 +0300 net/mlx5e: Ring the TX doorbell on DMA errors TX doorbells may be postponed, because sometimes the driver knows that another packet follows (for example, when xmit_more is true, or when a MPWQE session is closed before transmitting a packet). However, the DMA mapping may fail for the next packet, in which case a new WQE is not posted, the doorbell isn't updated either, and the transmission of the previous packet will be delayed indefinitely. This commit fixes the described rare error flow by posting a NOP and ringing the doorbell on errors to flush all the previous packets. The MPWQE session is closed before that. DMA mapping in the MPWQE flow is moved to the beginning of mlx5e_sq_xmit_mpwqe, because empty sessions are not allowed. Stop room always has enough space for a NOP, because the actual TX WQE is not posted. Fixes: e586b3b ("net/mlx5: Ethernet Datapath files") Signed-off-by: Maxim Mikityanskiy <maximmi@nvidia.com> Reviewed-by: Tariq Toukan <tariqt@nvidia.com> Signed-off-by: Saeed Mahameed <saeedm@nvidia.com> Signed-off-by: Mohammad Kabat <mkabat@redhat.com>
1 parent f05baf7 commit ea5b7ff

File tree

1 file changed

+30
-9
lines changed
  • drivers/net/ethernet/mellanox/mlx5/core

1 file changed

+30
-9
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en_tx.c

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,26 @@ static void mlx5e_tx_check_stop(struct mlx5e_txqsq *sq)
318318
}
319319
}
320320

321+
static void mlx5e_tx_flush(struct mlx5e_txqsq *sq)
322+
{
323+
struct mlx5e_tx_wqe_info *wi;
324+
struct mlx5e_tx_wqe *wqe;
325+
u16 pi;
326+
327+
/* Must not be called when a MPWQE session is active but empty. */
328+
mlx5e_tx_mpwqe_ensure_complete(sq);
329+
330+
pi = mlx5_wq_cyc_ctr2ix(&sq->wq, sq->pc);
331+
wi = &sq->db.wqe_info[pi];
332+
333+
*wi = (struct mlx5e_tx_wqe_info) {
334+
.num_wqebbs = 1,
335+
};
336+
337+
wqe = mlx5e_post_nop(&sq->wq, sq->sqn, &sq->pc);
338+
mlx5e_notify_hw(&sq->wq, sq->pc, sq->uar_map, &wqe->ctrl);
339+
}
340+
321341
static inline void
322342
mlx5e_txwqe_complete(struct mlx5e_txqsq *sq, struct sk_buff *skb,
323343
const struct mlx5e_tx_attr *attr,
@@ -410,6 +430,7 @@ mlx5e_sq_xmit_wqe(struct mlx5e_txqsq *sq, struct sk_buff *skb,
410430
err_drop:
411431
stats->dropped++;
412432
dev_kfree_skb_any(skb);
433+
mlx5e_tx_flush(sq);
413434
}
414435

415436
static bool mlx5e_tx_skb_supports_mpwqe(struct sk_buff *skb, struct mlx5e_tx_attr *attr)
@@ -511,6 +532,13 @@ mlx5e_sq_xmit_mpwqe(struct mlx5e_txqsq *sq, struct sk_buff *skb,
511532
struct mlx5_wqe_ctrl_seg *cseg;
512533
struct mlx5e_xmit_data txd;
513534

535+
txd.data = skb->data;
536+
txd.len = skb->len;
537+
538+
txd.dma_addr = dma_map_single(sq->pdev, txd.data, txd.len, DMA_TO_DEVICE);
539+
if (unlikely(dma_mapping_error(sq->pdev, txd.dma_addr)))
540+
goto err_unmap;
541+
514542
if (!mlx5e_tx_mpwqe_session_is_active(sq)) {
515543
mlx5e_tx_mpwqe_session_start(sq, eseg);
516544
} else if (!mlx5e_tx_mpwqe_same_eseg(sq, eseg)) {
@@ -520,18 +548,9 @@ mlx5e_sq_xmit_mpwqe(struct mlx5e_txqsq *sq, struct sk_buff *skb,
520548

521549
sq->stats->xmit_more += xmit_more;
522550

523-
txd.data = skb->data;
524-
txd.len = skb->len;
525-
526-
txd.dma_addr = dma_map_single(sq->pdev, txd.data, txd.len, DMA_TO_DEVICE);
527-
if (unlikely(dma_mapping_error(sq->pdev, txd.dma_addr)))
528-
goto err_unmap;
529551
mlx5e_dma_push(sq, txd.dma_addr, txd.len, MLX5E_DMA_MAP_SINGLE);
530-
531552
mlx5e_skb_fifo_push(&sq->db.skb_fifo, skb);
532-
533553
mlx5e_tx_mpwqe_add_dseg(sq, &txd);
534-
535554
mlx5e_tx_skb_update_hwts_flags(skb);
536555

537556
if (unlikely(mlx5e_tx_mpwqe_is_full(&sq->mpwqe, sq->max_sq_mpw_wqebbs))) {
@@ -553,6 +572,7 @@ mlx5e_sq_xmit_mpwqe(struct mlx5e_txqsq *sq, struct sk_buff *skb,
553572
mlx5e_dma_unmap_wqe_err(sq, 1);
554573
sq->stats->dropped++;
555574
dev_kfree_skb_any(skb);
575+
mlx5e_tx_flush(sq);
556576
}
557577

558578
void mlx5e_tx_mpwqe_ensure_complete(struct mlx5e_txqsq *sq)
@@ -935,5 +955,6 @@ void mlx5i_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb,
935955
err_drop:
936956
stats->dropped++;
937957
dev_kfree_skb_any(skb);
958+
mlx5e_tx_flush(sq);
938959
}
939960
#endif

0 commit comments

Comments
 (0)