|
|
d8f823 |
From d1ac1b641ea39e946e94c155520c590a5a27e23a Mon Sep 17 00:00:00 2001
|
|
|
d8f823 |
From: Jiri Benc <jbenc@redhat.com>
|
|
|
d8f823 |
Date: Wed, 22 Apr 2020 18:18:11 -0400
|
|
|
d8f823 |
Subject: [PATCH 006/312] [netdrv] mlx5e: Allow XSK frames smaller than a page
|
|
|
d8f823 |
MIME-Version: 1.0
|
|
|
d8f823 |
Content-Type: text/plain; charset=UTF-8
|
|
|
d8f823 |
Content-Transfer-Encoding: 8bit
|
|
|
d8f823 |
|
|
|
d8f823 |
Message-id: <5c0604430537e1022e4424f8683b5611f3ccceb3.1587578778.git.jbenc@redhat.com>
|
|
|
d8f823 |
Patchwork-id: 304531
|
|
|
d8f823 |
Patchwork-instance: patchwork
|
|
|
d8f823 |
O-Subject: [RHEL8.3 net 20/46] net/mlx5e: Allow XSK frames smaller than a page
|
|
|
d8f823 |
Bugzilla: 1819630
|
|
|
d8f823 |
RH-Acked-by: Hangbin Liu <haliu@redhat.com>
|
|
|
d8f823 |
RH-Acked-by: Toke Høiland-Jørgensen <toke@redhat.com>
|
|
|
d8f823 |
RH-Acked-by: Ivan Vecera <ivecera@redhat.com>
|
|
|
d8f823 |
|
|
|
d8f823 |
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1819630
|
|
|
d8f823 |
|
|
|
d8f823 |
commit 282c0c798f8ec883c2ac2f1ce2dc06ef9421731c
|
|
|
d8f823 |
Author: Maxim Mikityanskiy <maximmi@mellanox.com>
|
|
|
d8f823 |
Date: Tue Aug 27 02:25:26 2019 +0000
|
|
|
d8f823 |
|
|
|
d8f823 |
net/mlx5e: Allow XSK frames smaller than a page
|
|
|
d8f823 |
|
|
|
d8f823 |
Relax the requirements to the XSK frame size to allow it to be smaller
|
|
|
d8f823 |
than a page and even not a power of two. The current implementation can
|
|
|
d8f823 |
work in this mode, both with Striding RQ and without it.
|
|
|
d8f823 |
|
|
|
d8f823 |
The code that checks `mtu + headroom <= XSK frame size` is modified
|
|
|
d8f823 |
accordingly. Any frame size between 2048 and PAGE_SIZE is accepted.
|
|
|
d8f823 |
|
|
|
d8f823 |
Functions that worked with pages only now work with XSK frames, even if
|
|
|
d8f823 |
their size is different from PAGE_SIZE.
|
|
|
d8f823 |
|
|
|
d8f823 |
With XSK queues, regardless of the frame size, Striding RQ uses the
|
|
|
d8f823 |
stride size of PAGE_SIZE, and UMR MTTs are posted using starting
|
|
|
d8f823 |
addresses of frames, but PAGE_SIZE as page size. MTU guarantees that no
|
|
|
d8f823 |
packet data will overlap with other frames. UMR MTT size is made equal
|
|
|
d8f823 |
to the stride size of the RQ, because UMEM frames may come in random
|
|
|
d8f823 |
order, and we need to handle them one by one. PAGE_SIZE is just a power
|
|
|
d8f823 |
of two that is bigger than any allowed XSK frame size, and also it
|
|
|
d8f823 |
doesn't require making additional changes to the code.
|
|
|
d8f823 |
|
|
|
d8f823 |
Signed-off-by: Maxim Mikityanskiy <maximmi@mellanox.com>
|
|
|
d8f823 |
Reviewed-by: Saeed Mahameed <saeedm@mellanox.com>
|
|
|
d8f823 |
Acked-by: Jonathan Lemon <jonathan.lemon@gmail.com>
|
|
|
d8f823 |
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
|
|
|
d8f823 |
|
|
|
d8f823 |
Signed-off-by: Jiri Benc <jbenc@redhat.com>
|
|
|
d8f823 |
Signed-off-by: Timothy Redaelli <tredaelli@redhat.com>
|
|
|
d8f823 |
Signed-off-by: Frantisek Hrbata <fhrbata@redhat.com>
|
|
|
d8f823 |
---
|
|
|
d8f823 |
.../net/ethernet/mellanox/mlx5/core/en/params.c | 23 ++++++++++++++++++----
|
|
|
d8f823 |
.../net/ethernet/mellanox/mlx5/core/en/params.h | 2 ++
|
|
|
d8f823 |
.../net/ethernet/mellanox/mlx5/core/en/xsk/rx.c | 2 +-
|
|
|
d8f823 |
.../net/ethernet/mellanox/mlx5/core/en/xsk/setup.c | 15 +++++++++-----
|
|
|
d8f823 |
4 files changed, 32 insertions(+), 10 deletions(-)
|
|
|
d8f823 |
|
|
|
d8f823 |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
|
|
|
d8f823 |
index 79301d116667..eb2e1f2138e4 100644
|
|
|
d8f823 |
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
|
|
|
d8f823 |
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
|
|
|
d8f823 |
@@ -25,18 +25,33 @@ u16 mlx5e_get_linear_rq_headroom(struct mlx5e_params *params,
|
|
|
d8f823 |
return headroom;
|
|
|
d8f823 |
}
|
|
|
d8f823 |
|
|
|
d8f823 |
-u32 mlx5e_rx_get_linear_frag_sz(struct mlx5e_params *params,
|
|
|
d8f823 |
- struct mlx5e_xsk_param *xsk)
|
|
|
d8f823 |
+u32 mlx5e_rx_get_min_frag_sz(struct mlx5e_params *params,
|
|
|
d8f823 |
+ struct mlx5e_xsk_param *xsk)
|
|
|
d8f823 |
{
|
|
|
d8f823 |
u32 hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu);
|
|
|
d8f823 |
u16 linear_rq_headroom = mlx5e_get_linear_rq_headroom(params, xsk);
|
|
|
d8f823 |
- u32 frag_sz = linear_rq_headroom + hw_mtu;
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ return linear_rq_headroom + hw_mtu;
|
|
|
d8f823 |
+}
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+u32 mlx5e_rx_get_linear_frag_sz(struct mlx5e_params *params,
|
|
|
d8f823 |
+ struct mlx5e_xsk_param *xsk)
|
|
|
d8f823 |
+{
|
|
|
d8f823 |
+ u32 frag_sz = mlx5e_rx_get_min_frag_sz(params, xsk);
|
|
|
d8f823 |
|
|
|
d8f823 |
/* AF_XDP doesn't build SKBs in place. */
|
|
|
d8f823 |
if (!xsk)
|
|
|
d8f823 |
frag_sz = MLX5_SKB_FRAG_SZ(frag_sz);
|
|
|
d8f823 |
|
|
|
d8f823 |
- /* XDP in mlx5e doesn't support multiple packets per page. */
|
|
|
d8f823 |
+ /* XDP in mlx5e doesn't support multiple packets per page. AF_XDP is a
|
|
|
d8f823 |
+ * special case. It can run with frames smaller than a page, as it
|
|
|
d8f823 |
+ * doesn't allocate pages dynamically. However, here we pretend that
|
|
|
d8f823 |
+ * fragments are page-sized: it allows to treat XSK frames like pages
|
|
|
d8f823 |
+ * by redirecting alloc and free operations to XSK rings and by using
|
|
|
d8f823 |
+ * the fact there are no multiple packets per "page" (which is a frame).
|
|
|
d8f823 |
+ * The latter is important, because frames may come in a random order,
|
|
|
d8f823 |
+ * and we will have trouble assemblying a real page of multiple frames.
|
|
|
d8f823 |
+ */
|
|
|
d8f823 |
if (mlx5e_rx_is_xdp(params, xsk))
|
|
|
d8f823 |
frag_sz = max_t(u32, frag_sz, PAGE_SIZE);
|
|
|
d8f823 |
|
|
|
d8f823 |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/params.h b/drivers/net/ethernet/mellanox/mlx5/core/en/params.h
|
|
|
d8f823 |
index 3a615d663d84..989d8f429438 100644
|
|
|
d8f823 |
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/params.h
|
|
|
d8f823 |
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/params.h
|
|
|
d8f823 |
@@ -76,6 +76,8 @@ static inline bool mlx5e_qid_validate(const struct mlx5e_profile *profile,
|
|
|
d8f823 |
|
|
|
d8f823 |
u16 mlx5e_get_linear_rq_headroom(struct mlx5e_params *params,
|
|
|
d8f823 |
struct mlx5e_xsk_param *xsk);
|
|
|
d8f823 |
+u32 mlx5e_rx_get_min_frag_sz(struct mlx5e_params *params,
|
|
|
d8f823 |
+ struct mlx5e_xsk_param *xsk);
|
|
|
d8f823 |
u32 mlx5e_rx_get_linear_frag_sz(struct mlx5e_params *params,
|
|
|
d8f823 |
struct mlx5e_xsk_param *xsk);
|
|
|
d8f823 |
u8 mlx5e_mpwqe_log_pkts_per_wqe(struct mlx5e_params *params,
|
|
|
d8f823 |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/rx.c
|
|
|
d8f823 |
index 6a55573ec8f2..3783776b6d70 100644
|
|
|
d8f823 |
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/rx.c
|
|
|
d8f823 |
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/rx.c
|
|
|
d8f823 |
@@ -104,7 +104,7 @@ struct sk_buff *mlx5e_xsk_skb_from_cqe_mpwrq_linear(struct mlx5e_rq *rq,
|
|
|
d8f823 |
|
|
|
d8f823 |
/* head_offset is not used in this function, because di->xsk.data and
|
|
|
d8f823 |
* di->addr point directly to the necessary place. Furthermore, in the
|
|
|
d8f823 |
- * current implementation, one page = one packet = one frame, so
|
|
|
d8f823 |
+ * current implementation, UMR pages are mapped to XSK frames, so
|
|
|
d8f823 |
* head_offset should always be 0.
|
|
|
d8f823 |
*/
|
|
|
d8f823 |
WARN_ON_ONCE(head_offset);
|
|
|
d8f823 |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c
|
|
|
d8f823 |
index d3a173e88e24..81efd2fbc75d 100644
|
|
|
d8f823 |
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c
|
|
|
d8f823 |
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c
|
|
|
d8f823 |
@@ -4,18 +4,23 @@
|
|
|
d8f823 |
#include "setup.h"
|
|
|
d8f823 |
#include "en/params.h"
|
|
|
d8f823 |
|
|
|
d8f823 |
+/* It matches XDP_UMEM_MIN_CHUNK_SIZE, but as this constant is private and may
|
|
|
d8f823 |
+ * change unexpectedly, and mlx5e has a minimum valid stride size for striding
|
|
|
d8f823 |
+ * RQ, keep this check in the driver.
|
|
|
d8f823 |
+ */
|
|
|
d8f823 |
+#define MLX5E_MIN_XSK_CHUNK_SIZE 2048
|
|
|
d8f823 |
+
|
|
|
d8f823 |
bool mlx5e_validate_xsk_param(struct mlx5e_params *params,
|
|
|
d8f823 |
struct mlx5e_xsk_param *xsk,
|
|
|
d8f823 |
struct mlx5_core_dev *mdev)
|
|
|
d8f823 |
{
|
|
|
d8f823 |
- /* AF_XDP doesn't support frames larger than PAGE_SIZE, and the current
|
|
|
d8f823 |
- * mlx5e XDP implementation doesn't support multiple packets per page.
|
|
|
d8f823 |
- */
|
|
|
d8f823 |
- if (xsk->chunk_size != PAGE_SIZE)
|
|
|
d8f823 |
+ /* AF_XDP doesn't support frames larger than PAGE_SIZE. */
|
|
|
d8f823 |
+ if (xsk->chunk_size > PAGE_SIZE ||
|
|
|
d8f823 |
+ xsk->chunk_size < MLX5E_MIN_XSK_CHUNK_SIZE)
|
|
|
d8f823 |
return false;
|
|
|
d8f823 |
|
|
|
d8f823 |
/* Current MTU and XSK headroom don't allow packets to fit the frames. */
|
|
|
d8f823 |
- if (mlx5e_rx_get_linear_frag_sz(params, xsk) > xsk->chunk_size)
|
|
|
d8f823 |
+ if (mlx5e_rx_get_min_frag_sz(params, xsk) > xsk->chunk_size)
|
|
|
d8f823 |
return false;
|
|
|
d8f823 |
|
|
|
d8f823 |
/* frag_sz is different for regular and XSK RQs, so ensure that linear
|
|
|
d8f823 |
--
|
|
|
d8f823 |
2.13.6
|
|
|
d8f823 |
|