You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
5.4 KiB
139 lines
5.4 KiB
From aacfc2f99d074a34d4a246df7d775bd6e463cd8f Mon Sep 17 00:00:00 2001
|
|
From: Alaa Hleihel <ahleihel@redhat.com>
|
|
Date: Tue, 12 May 2020 10:55:17 -0400
|
|
Subject: [PATCH 201/312] [netdrv] net/mlx5e: Don't trigger IRQ multiple times
|
|
on XSK wakeup to avoid WQ overruns
|
|
|
|
Message-id: <20200512105530.4207-112-ahleihel@redhat.com>
|
|
Patchwork-id: 306983
|
|
Patchwork-instance: patchwork
|
|
O-Subject: [RHEL8.3 BZ 1789382 111/124] net/mlx5e: Don't trigger IRQ multiple times on XSK wakeup to avoid WQ overruns
|
|
Bugzilla: 1789382
|
|
RH-Acked-by: Tony Camuso <tcamuso@redhat.com>
|
|
RH-Acked-by: Kamal Heib <kheib@redhat.com>
|
|
RH-Acked-by: Jarod Wilson <jarod@redhat.com>
|
|
|
|
Bugzilla: http://bugzilla.redhat.com/1789382
|
|
Upstream: v5.7-rc3
|
|
|
|
commit e7e0004abdd6f83ae4be5613b29ed396beff576c
|
|
Author: Maxim Mikityanskiy <maximmi@mellanox.com>
|
|
Date: Tue Feb 11 16:02:35 2020 +0200
|
|
|
|
net/mlx5e: Don't trigger IRQ multiple times on XSK wakeup to avoid WQ overruns
|
|
|
|
XSK wakeup function triggers NAPI by posting a NOP WQE to a special XSK
|
|
ICOSQ. When the application floods the driver with wakeup requests by
|
|
calling sendto() in a certain pattern that ends up in mlx5e_trigger_irq,
|
|
the XSK ICOSQ may overflow.
|
|
|
|
Multiple NOPs are not required and won't accelerate the process, so
|
|
avoid posting a second NOP if there is one already on the way. This way
|
|
we also avoid increasing the queue size (which might not help anyway).
|
|
|
|
Fixes: db05815b36cb ("net/mlx5e: Add XSK zero-copy support")
|
|
Signed-off-by: Maxim Mikityanskiy <maximmi@mellanox.com>
|
|
Reviewed-by: Tariq Toukan <tariqt@mellanox.com>
|
|
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
|
|
|
|
Signed-off-by: Alaa Hleihel <ahleihel@redhat.com>
|
|
Signed-off-by: Frantisek Hrbata <fhrbata@redhat.com>
|
|
---
|
|
drivers/net/ethernet/mellanox/mlx5/core/en.h | 3 ++-
|
|
drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c | 3 +++
|
|
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 8 +++++---
|
|
drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c | 6 +++++-
|
|
4 files changed, 15 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
|
|
index 58a7f28b146f..2e3a4ba96793 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
|
|
@@ -366,6 +366,7 @@ enum {
|
|
MLX5E_SQ_STATE_AM,
|
|
MLX5E_SQ_STATE_TLS,
|
|
MLX5E_SQ_STATE_VLAN_NEED_L2_INLINE,
|
|
+ MLX5E_SQ_STATE_PENDING_XSK_TX,
|
|
};
|
|
|
|
struct mlx5e_sq_wqe_info {
|
|
@@ -947,7 +948,7 @@ void mlx5e_page_release_dynamic(struct mlx5e_rq *rq,
|
|
void mlx5e_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
|
|
void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
|
|
bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq);
|
|
-void mlx5e_poll_ico_cq(struct mlx5e_cq *cq);
|
|
+int mlx5e_poll_ico_cq(struct mlx5e_cq *cq);
|
|
bool mlx5e_post_rx_mpwqes(struct mlx5e_rq *rq);
|
|
void mlx5e_dealloc_rx_wqe(struct mlx5e_rq *rq, u16 ix);
|
|
void mlx5e_dealloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix);
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c
|
|
index 03abb8cb96be..c054759ed7eb 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c
|
|
@@ -33,6 +33,9 @@ int mlx5e_xsk_async_xmit(struct net_device *dev, u32 qid)
|
|
if (unlikely(!test_bit(MLX5E_SQ_STATE_ENABLED, &c->xskicosq.state)))
|
|
return 0;
|
|
|
|
+ if (test_and_set_bit(MLX5E_SQ_STATE_PENDING_XSK_TX, &c->xskicosq.state))
|
|
+ return 0;
|
|
+
|
|
spin_lock(&c->xskicosq_lock);
|
|
mlx5e_trigger_irq(&c->xskicosq);
|
|
spin_unlock(&c->xskicosq_lock);
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
|
|
index b2109bbcb985..1d606e13a336 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
|
|
@@ -590,7 +590,7 @@ bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq)
|
|
return !!err;
|
|
}
|
|
|
|
-void mlx5e_poll_ico_cq(struct mlx5e_cq *cq)
|
|
+int mlx5e_poll_ico_cq(struct mlx5e_cq *cq)
|
|
{
|
|
struct mlx5e_icosq *sq = container_of(cq, struct mlx5e_icosq, cq);
|
|
struct mlx5_cqe64 *cqe;
|
|
@@ -598,11 +598,11 @@ void mlx5e_poll_ico_cq(struct mlx5e_cq *cq)
|
|
int i;
|
|
|
|
if (unlikely(!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state)))
|
|
- return;
|
|
+ return 0;
|
|
|
|
cqe = mlx5_cqwq_get_cqe(&cq->wq);
|
|
if (likely(!cqe))
|
|
- return;
|
|
+ return 0;
|
|
|
|
/* sq->cc must be updated only after mlx5_cqwq_update_db_record(),
|
|
* otherwise a cq overrun may occur
|
|
@@ -651,6 +651,8 @@ void mlx5e_poll_ico_cq(struct mlx5e_cq *cq)
|
|
sq->cc = sqcc;
|
|
|
|
mlx5_cqwq_update_db_record(&cq->wq);
|
|
+
|
|
+ return i;
|
|
}
|
|
|
|
bool mlx5e_post_rx_mpwqes(struct mlx5e_rq *rq)
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c
|
|
index 5dcdd18143e6..333d813b0019 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c
|
|
@@ -138,7 +138,11 @@ int mlx5e_napi_poll(struct napi_struct *napi, int budget)
|
|
mlx5e_post_rx_wqes,
|
|
rq);
|
|
if (xsk_open) {
|
|
- mlx5e_poll_ico_cq(&c->xskicosq.cq);
|
|
+ if (mlx5e_poll_ico_cq(&c->xskicosq.cq))
|
|
+ /* Don't clear the flag if nothing was polled to prevent
|
|
+ * queueing more WQEs and overflowing XSKICOSQ.
|
|
+ */
|
|
+ clear_bit(MLX5E_SQ_STATE_PENDING_XSK_TX, &c->xskicosq.state);
|
|
busy |= mlx5e_poll_xdpsq_cq(&xsksq->cq);
|
|
busy_xsk |= mlx5e_napi_xsk_post(xsksq, xskrq);
|
|
}
|
|
--
|
|
2.13.6
|
|
|