Commit a069e977 authored by Maxim Mikityanskiy's avatar Maxim Mikityanskiy Committed by Daniel Borkmann

net/mlx5e: Calculate linear RX frag size considering XSK

Additional conditions introduced:

- XSK implies XDP.
- Headroom includes the XSK headroom if it exists.
- No space is reserved for struct shared_skb_info in XSK mode.
- Fragment size smaller than the XSK chunk size is not allowed.

A new auxiliary function mlx5e_get_linear_rq_headroom with the support
for XSK is introduced. Use this function in the implementation of
mlx5e_get_rq_headroom. Change headroom to u32 to match the headroom
field in struct xdp_umem.
Signed-off-by: default avatarMaxim Mikityanskiy <maximmi@mellanox.com>
Signed-off-by: default avatarTariq Toukan <tariqt@mellanox.com>
Acked-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parent 6ed9350f
...@@ -3,33 +3,62 @@ ...@@ -3,33 +3,62 @@
#include "en/params.h" #include "en/params.h"
u32 mlx5e_rx_get_linear_frag_sz(struct mlx5e_params *params) static inline bool mlx5e_rx_is_xdp(struct mlx5e_params *params,
struct mlx5e_xsk_param *xsk)
{ {
u16 hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu); return params->xdp_prog || xsk;
u16 linear_rq_headroom = params->xdp_prog ? }
XDP_PACKET_HEADROOM : MLX5_RX_HEADROOM;
u32 frag_sz; static inline u16 mlx5e_get_linear_rq_headroom(struct mlx5e_params *params,
struct mlx5e_xsk_param *xsk)
{
u16 headroom = NET_IP_ALIGN;
if (mlx5e_rx_is_xdp(params, xsk)) {
headroom += XDP_PACKET_HEADROOM;
if (xsk)
headroom += xsk->headroom;
} else {
headroom += MLX5_RX_HEADROOM;
}
return headroom;
}
u32 mlx5e_rx_get_linear_frag_sz(struct mlx5e_params *params,
struct mlx5e_xsk_param *xsk)
{
u32 hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu);
u16 linear_rq_headroom = mlx5e_get_linear_rq_headroom(params, xsk);
u32 frag_sz = linear_rq_headroom + hw_mtu;
linear_rq_headroom += NET_IP_ALIGN; /* AF_XDP doesn't build SKBs in place. */
if (!xsk)
frag_sz = MLX5_SKB_FRAG_SZ(frag_sz);
frag_sz = MLX5_SKB_FRAG_SZ(linear_rq_headroom + hw_mtu); /* XDP in mlx5e doesn't support multiple packets per page. */
if (mlx5e_rx_is_xdp(params, xsk))
frag_sz = max_t(u32, frag_sz, PAGE_SIZE);
if (params->xdp_prog && frag_sz < PAGE_SIZE) /* Even if we can go with a smaller fragment size, we must not put
frag_sz = PAGE_SIZE; * multiple packets into a single frame.
*/
if (xsk)
frag_sz = max_t(u32, frag_sz, xsk->chunk_size);
return frag_sz; return frag_sz;
} }
u8 mlx5e_mpwqe_log_pkts_per_wqe(struct mlx5e_params *params) u8 mlx5e_mpwqe_log_pkts_per_wqe(struct mlx5e_params *params)
{ {
u32 linear_frag_sz = mlx5e_rx_get_linear_frag_sz(params); u32 linear_frag_sz = mlx5e_rx_get_linear_frag_sz(params, NULL);
return MLX5_MPWRQ_LOG_WQE_SZ - order_base_2(linear_frag_sz); return MLX5_MPWRQ_LOG_WQE_SZ - order_base_2(linear_frag_sz);
} }
bool mlx5e_rx_is_linear_skb(struct mlx5e_params *params) bool mlx5e_rx_is_linear_skb(struct mlx5e_params *params)
{ {
u32 frag_sz = mlx5e_rx_get_linear_frag_sz(params); u32 frag_sz = mlx5e_rx_get_linear_frag_sz(params, NULL);
return !params->lro_en && frag_sz <= PAGE_SIZE; return !params->lro_en && frag_sz <= PAGE_SIZE;
} }
...@@ -39,7 +68,7 @@ bool mlx5e_rx_is_linear_skb(struct mlx5e_params *params) ...@@ -39,7 +68,7 @@ bool mlx5e_rx_is_linear_skb(struct mlx5e_params *params)
bool mlx5e_rx_mpwqe_is_linear_skb(struct mlx5_core_dev *mdev, bool mlx5e_rx_mpwqe_is_linear_skb(struct mlx5_core_dev *mdev,
struct mlx5e_params *params) struct mlx5e_params *params)
{ {
u32 frag_sz = mlx5e_rx_get_linear_frag_sz(params); u32 frag_sz = mlx5e_rx_get_linear_frag_sz(params, NULL);
s8 signed_log_num_strides_param; s8 signed_log_num_strides_param;
u8 log_num_strides; u8 log_num_strides;
...@@ -75,7 +104,7 @@ u8 mlx5e_mpwqe_get_log_stride_size(struct mlx5_core_dev *mdev, ...@@ -75,7 +104,7 @@ u8 mlx5e_mpwqe_get_log_stride_size(struct mlx5_core_dev *mdev,
struct mlx5e_params *params) struct mlx5e_params *params)
{ {
if (mlx5e_rx_mpwqe_is_linear_skb(mdev, params)) if (mlx5e_rx_mpwqe_is_linear_skb(mdev, params))
return order_base_2(mlx5e_rx_get_linear_frag_sz(params)); return order_base_2(mlx5e_rx_get_linear_frag_sz(params, NULL));
return MLX5_MPWRQ_DEF_LOG_STRIDE_SZ(mdev); return MLX5_MPWRQ_DEF_LOG_STRIDE_SZ(mdev);
} }
...@@ -90,15 +119,9 @@ u8 mlx5e_mpwqe_get_log_num_strides(struct mlx5_core_dev *mdev, ...@@ -90,15 +119,9 @@ u8 mlx5e_mpwqe_get_log_num_strides(struct mlx5_core_dev *mdev,
u16 mlx5e_get_rq_headroom(struct mlx5_core_dev *mdev, u16 mlx5e_get_rq_headroom(struct mlx5_core_dev *mdev,
struct mlx5e_params *params) struct mlx5e_params *params)
{ {
u16 linear_rq_headroom = params->xdp_prog ? bool is_linear_skb = (params->rq_wq_type == MLX5_WQ_TYPE_CYCLIC) ?
XDP_PACKET_HEADROOM : MLX5_RX_HEADROOM;
bool is_linear_skb;
linear_rq_headroom += NET_IP_ALIGN;
is_linear_skb = (params->rq_wq_type == MLX5_WQ_TYPE_CYCLIC) ?
mlx5e_rx_is_linear_skb(params) : mlx5e_rx_is_linear_skb(params) :
mlx5e_rx_mpwqe_is_linear_skb(mdev, params); mlx5e_rx_mpwqe_is_linear_skb(mdev, params);
return is_linear_skb ? linear_rq_headroom : 0; return is_linear_skb ? mlx5e_get_linear_rq_headroom(params, NULL) : 0;
} }
...@@ -6,7 +6,13 @@ ...@@ -6,7 +6,13 @@
#include "en.h" #include "en.h"
u32 mlx5e_rx_get_linear_frag_sz(struct mlx5e_params *params); struct mlx5e_xsk_param {
u16 headroom;
u16 chunk_size;
};
u32 mlx5e_rx_get_linear_frag_sz(struct mlx5e_params *params,
struct mlx5e_xsk_param *xsk);
u8 mlx5e_mpwqe_log_pkts_per_wqe(struct mlx5e_params *params); u8 mlx5e_mpwqe_log_pkts_per_wqe(struct mlx5e_params *params);
bool mlx5e_rx_is_linear_skb(struct mlx5e_params *params); bool mlx5e_rx_is_linear_skb(struct mlx5e_params *params);
bool mlx5e_rx_mpwqe_is_linear_skb(struct mlx5_core_dev *mdev, bool mlx5e_rx_mpwqe_is_linear_skb(struct mlx5_core_dev *mdev,
......
...@@ -1954,7 +1954,7 @@ static void mlx5e_build_rq_frags_info(struct mlx5_core_dev *mdev, ...@@ -1954,7 +1954,7 @@ static void mlx5e_build_rq_frags_info(struct mlx5_core_dev *mdev,
if (mlx5e_rx_is_linear_skb(params)) { if (mlx5e_rx_is_linear_skb(params)) {
int frag_stride; int frag_stride;
frag_stride = mlx5e_rx_get_linear_frag_sz(params); frag_stride = mlx5e_rx_get_linear_frag_sz(params, NULL);
frag_stride = roundup_pow_of_two(frag_stride); frag_stride = roundup_pow_of_two(frag_stride);
info->arr[0].frag_size = byte_count; info->arr[0].frag_size = byte_count;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment