Skip to content

Commit a26a5bd

Browse files
Tariq ToukanSaeed Mahameed
authored andcommitted
net/mlx5e: Restrict the combination of large MTU and XDP
Add checks in control path upon an MTU change or an XDP program set, to prevent reaching cases where large MTU and XDP are set simultaneously. This is to make sure we allow XDP only with the linear RX memory scheme, i.e. a received packet is not scattered to different pages. Change mlx5e_rx_get_linear_frag_sz() accordingly, so that we make sure the XDP configuration can really be set, instead of assuming that it is. Signed-off-by: Tariq Toukan <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent 0ec1387 commit a26a5bd

File tree

2 files changed

+33
-8
lines changed

2 files changed

+33
-8
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ struct page_pool;
7272
#define MLX5_RX_HEADROOM NET_SKB_PAD
7373
#define MLX5_SKB_FRAG_SZ(len) (SKB_DATA_ALIGN(len) + \
7474
SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
75+
#define MLX5E_XDP_MAX_MTU ((int)(PAGE_SIZE - \
76+
MLX5_SKB_FRAG_SZ(XDP_PACKET_HEADROOM)))
7577

7678
#define MLX5_MPWRQ_MIN_LOG_STRIDE_SZ(mdev) \
7779
(6 + MLX5_CAP_GEN(mdev, cache_line_128byte)) /* HW restriction */

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

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,19 @@ bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev)
9696

9797
static u32 mlx5e_rx_get_linear_frag_sz(struct mlx5e_params *params)
9898
{
99-
if (!params->xdp_prog) {
100-
u16 hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu);
101-
u16 rq_headroom = MLX5_RX_HEADROOM + NET_IP_ALIGN;
99+
u16 hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu);
100+
u16 linear_rq_headroom = params->xdp_prog ?
101+
XDP_PACKET_HEADROOM : MLX5_RX_HEADROOM;
102+
u32 frag_sz;
102103

103-
return MLX5_SKB_FRAG_SZ(rq_headroom + hw_mtu);
104-
}
104+
linear_rq_headroom += NET_IP_ALIGN;
105105

106-
return PAGE_SIZE;
106+
frag_sz = MLX5_SKB_FRAG_SZ(linear_rq_headroom + hw_mtu);
107+
108+
if (params->xdp_prog && frag_sz < PAGE_SIZE)
109+
frag_sz = PAGE_SIZE;
110+
111+
return frag_sz;
107112
}
108113

109114
static u8 mlx5e_mpwqe_log_pkts_per_wqe(struct mlx5e_params *params)
@@ -3707,6 +3712,14 @@ int mlx5e_change_mtu(struct net_device *netdev, int new_mtu,
37073712
new_channels.params = *params;
37083713
new_channels.params.sw_mtu = new_mtu;
37093714

3715+
if (params->xdp_prog &&
3716+
!mlx5e_rx_is_linear_skb(priv->mdev, &new_channels.params)) {
3717+
netdev_err(netdev, "MTU(%d) > %d is not allowed while XDP enabled\n",
3718+
new_mtu, MLX5E_XDP_MAX_MTU);
3719+
err = -EINVAL;
3720+
goto out;
3721+
}
3722+
37103723
if (params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) {
37113724
u8 ppw_old = mlx5e_mpwqe_log_pkts_per_wqe(params);
37123725
u8 ppw_new = mlx5e_mpwqe_log_pkts_per_wqe(&new_channels.params);
@@ -4094,9 +4107,10 @@ static void mlx5e_tx_timeout(struct net_device *dev)
40944107
queue_work(priv->wq, &priv->tx_timeout_work);
40954108
}
40964109

4097-
static int mlx5e_xdp_allowed(struct mlx5e_priv *priv)
4110+
static int mlx5e_xdp_allowed(struct mlx5e_priv *priv, struct bpf_prog *prog)
40984111
{
40994112
struct net_device *netdev = priv->netdev;
4113+
struct mlx5e_channels new_channels = {};
41004114

41014115
if (priv->channels.params.lro_en) {
41024116
netdev_warn(netdev, "can't set XDP while LRO is on, disable LRO first\n");
@@ -4108,6 +4122,15 @@ static int mlx5e_xdp_allowed(struct mlx5e_priv *priv)
41084122
return -EINVAL;
41094123
}
41104124

4125+
new_channels.params = priv->channels.params;
4126+
new_channels.params.xdp_prog = prog;
4127+
4128+
if (!mlx5e_rx_is_linear_skb(priv->mdev, &new_channels.params)) {
4129+
netdev_warn(netdev, "XDP is not allowed with MTU(%d) > %d\n",
4130+
new_channels.params.sw_mtu, MLX5E_XDP_MAX_MTU);
4131+
return -EINVAL;
4132+
}
4133+
41114134
return 0;
41124135
}
41134136

@@ -4122,7 +4145,7 @@ static int mlx5e_xdp_set(struct net_device *netdev, struct bpf_prog *prog)
41224145
mutex_lock(&priv->state_lock);
41234146

41244147
if (prog) {
4125-
err = mlx5e_xdp_allowed(priv);
4148+
err = mlx5e_xdp_allowed(priv, prog);
41264149
if (err)
41274150
goto unlock;
41284151
}

0 commit comments

Comments
 (0)