]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/5.0.11/net-mlx5e-fix-the-max-mtu-check-in-case-of-xdp.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 5.0.11 / net-mlx5e-fix-the-max-mtu-check-in-case-of-xdp.patch
1 From foo@baz Tue 30 Apr 2019 09:51:57 AM CEST
2 From: Maxim Mikityanskiy <maximmi@mellanox.com>
3 Date: Mon, 8 Apr 2019 15:12:45 +0300
4 Subject: net/mlx5e: Fix the max MTU check in case of XDP
5
6 From: Maxim Mikityanskiy <maximmi@mellanox.com>
7
8 [ Upstream commit d460c2718906252a2a69bc6f89b537071f792e6e ]
9
10 MLX5E_XDP_MAX_MTU was calculated incorrectly. It didn't account for
11 NET_IP_ALIGN and MLX5E_HW2SW_MTU, and it also misused MLX5_SKB_FRAG_SZ.
12 This commit fixes the calculations and adds a brief explanation for the
13 formula used.
14
15 Fixes: a26a5bdf3ee2d ("net/mlx5e: Restrict the combination of large MTU and XDP")
16 Signed-off-by: Maxim Mikityanskiy <maximmi@mellanox.com>
17 Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
18 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
19 ---
20 drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c | 20 ++++++++++++++++++++
21 drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h | 3 +--
22 drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 5 +++--
23 3 files changed, 24 insertions(+), 4 deletions(-)
24
25 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
26 +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
27 @@ -33,6 +33,26 @@
28 #include <linux/bpf_trace.h>
29 #include "en/xdp.h"
30
31 +int mlx5e_xdp_max_mtu(struct mlx5e_params *params)
32 +{
33 + int hr = NET_IP_ALIGN + XDP_PACKET_HEADROOM;
34 +
35 + /* Let S := SKB_DATA_ALIGN(sizeof(struct skb_shared_info)).
36 + * The condition checked in mlx5e_rx_is_linear_skb is:
37 + * SKB_DATA_ALIGN(sw_mtu + hard_mtu + hr) + S <= PAGE_SIZE (1)
38 + * (Note that hw_mtu == sw_mtu + hard_mtu.)
39 + * What is returned from this function is:
40 + * max_mtu = PAGE_SIZE - S - hr - hard_mtu (2)
41 + * After assigning sw_mtu := max_mtu, the left side of (1) turns to
42 + * SKB_DATA_ALIGN(PAGE_SIZE - S) + S, which is equal to PAGE_SIZE,
43 + * because both PAGE_SIZE and S are already aligned. Any number greater
44 + * than max_mtu would make the left side of (1) greater than PAGE_SIZE,
45 + * so max_mtu is the maximum MTU allowed.
46 + */
47 +
48 + return MLX5E_HW2SW_MTU(params, SKB_MAX_HEAD(hr));
49 +}
50 +
51 static inline bool
52 mlx5e_xmit_xdp_buff(struct mlx5e_xdpsq *sq, struct mlx5e_dma_info *di,
53 struct xdp_buff *xdp)
54 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h
55 +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h
56 @@ -34,13 +34,12 @@
57
58 #include "en.h"
59
60 -#define MLX5E_XDP_MAX_MTU ((int)(PAGE_SIZE - \
61 - MLX5_SKB_FRAG_SZ(XDP_PACKET_HEADROOM)))
62 #define MLX5E_XDP_MIN_INLINE (ETH_HLEN + VLAN_HLEN)
63 #define MLX5E_XDP_TX_EMPTY_DS_COUNT \
64 (sizeof(struct mlx5e_tx_wqe) / MLX5_SEND_WQE_DS)
65 #define MLX5E_XDP_TX_DS_COUNT (MLX5E_XDP_TX_EMPTY_DS_COUNT + 1 /* SG DS */)
66
67 +int mlx5e_xdp_max_mtu(struct mlx5e_params *params);
68 bool mlx5e_xdp_handle(struct mlx5e_rq *rq, struct mlx5e_dma_info *di,
69 void *va, u16 *rx_headroom, u32 *len);
70 bool mlx5e_poll_xdpsq_cq(struct mlx5e_cq *cq, struct mlx5e_rq *rq);
71 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
72 +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
73 @@ -3816,7 +3816,7 @@ int mlx5e_change_mtu(struct net_device *
74 if (params->xdp_prog &&
75 !mlx5e_rx_is_linear_skb(priv->mdev, &new_channels.params)) {
76 netdev_err(netdev, "MTU(%d) > %d is not allowed while XDP enabled\n",
77 - new_mtu, MLX5E_XDP_MAX_MTU);
78 + new_mtu, mlx5e_xdp_max_mtu(params));
79 err = -EINVAL;
80 goto out;
81 }
82 @@ -4280,7 +4280,8 @@ static int mlx5e_xdp_allowed(struct mlx5
83
84 if (!mlx5e_rx_is_linear_skb(priv->mdev, &new_channels.params)) {
85 netdev_warn(netdev, "XDP is not allowed with MTU(%d) > %d\n",
86 - new_channels.params.sw_mtu, MLX5E_XDP_MAX_MTU);
87 + new_channels.params.sw_mtu,
88 + mlx5e_xdp_max_mtu(&new_channels.params));
89 return -EINVAL;
90 }
91