Commit 579524c6 authored by Vladyslav Tarasiuk's avatar Vladyslav Tarasiuk Committed by Saeed Mahameed
Browse files

net/mlx5e: Validate stop_room size upon user input



Stop room is a space that may be taken by WQEs in the SQ during a packet
transmit. It is used to check if next packet has enough room in the SQ.
Stop room guarantees this packet can be served and if not, the queue is
stopped, so no more packets are passed to the driver until it's ready.

Currently, stop_room size is calculated and validated upon tx queues
allocation. This makes it impossible to know if user provided valid
input for certain parameters when interface is down.

Instead, store stop_room in mlx5e_sq_param and create
mlx5e_validate_params(), to validate its fields upon user input even
when the interface is down.

Signed-off-by: default avatarVladyslav Tarasiuk <vladyslavt@nvidia.com>
Reviewed-by: default avatarTariq Toukan <tariqt@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent 284836d9
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@
/* Copyright (c) 2019 Mellanox Technologies. */

#include "en/params.h"
#include "en/txrx.h"
#include "en_accel/tls_rxtx.h"

static inline bool mlx5e_rx_is_xdp(struct mlx5e_params *params,
				   struct mlx5e_xsk_param *xsk)
@@ -152,3 +154,35 @@ u16 mlx5e_get_rq_headroom(struct mlx5_core_dev *mdev,

	return is_linear_skb ? mlx5e_get_linear_rq_headroom(params, xsk) : 0;
}

u16 mlx5e_calc_sq_stop_room(struct mlx5_core_dev *mdev, struct mlx5e_params *params)
{
	bool is_mpwqe = MLX5E_GET_PFLAG(params, MLX5E_PFLAG_SKB_TX_MPWQE);
	u16 stop_room;

	stop_room  = mlx5e_tls_get_stop_room(mdev, params);
	stop_room += mlx5e_stop_room_for_wqe(MLX5_SEND_WQE_MAX_WQEBBS);
	if (is_mpwqe)
		/* A MPWQE can take up to the maximum-sized WQE + all the normal
		 * stop room can be taken if a new packet breaks the active
		 * MPWQE session and allocates its WQEs right away.
		 */
		stop_room += mlx5e_stop_room_for_wqe(MLX5_SEND_WQE_MAX_WQEBBS);

	return stop_room;
}

int mlx5e_validate_params(struct mlx5e_priv *priv, struct mlx5e_params *params)
{
	size_t sq_size = 1 << params->log_sq_size;
	u16 stop_room;

	stop_room = mlx5e_calc_sq_stop_room(priv->mdev, params);
	if (stop_room >= sq_size) {
		netdev_err(priv->netdev, "Stop room %hu is bigger than the SQ size %zu\n",
			   stop_room, sq_size);
		return -EINVAL;
	}

	return 0;
}
+4 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ struct mlx5e_sq_param {
	u32                        sqc[MLX5_ST_SZ_DW(sqc)];
	struct mlx5_wq_param       wq;
	bool                       is_mpw;
	u16                        stop_room;
};

struct mlx5e_channel_param {
@@ -124,4 +125,7 @@ void mlx5e_build_xdpsq_param(struct mlx5e_priv *priv,
			     struct mlx5e_params *params,
			     struct mlx5e_sq_param *param);

u16 mlx5e_calc_sq_stop_room(struct mlx5_core_dev *mdev, struct mlx5e_params *params);
int mlx5e_validate_params(struct mlx5e_priv *priv, struct mlx5e_params *params);

#endif /* __MLX5_EN_PARAMS_H__ */
+4 −4
Original line number Diff line number Diff line
@@ -13,20 +13,20 @@ struct mlx5e_dump_wqe {
	(DIV_ROUND_UP(sizeof(struct mlx5e_dump_wqe), MLX5_SEND_WQE_BB))

static u8
mlx5e_ktls_dumps_num_wqes(struct mlx5e_txqsq *sq, unsigned int nfrags,
mlx5e_ktls_dumps_num_wqes(struct mlx5e_params *params, unsigned int nfrags,
			  unsigned int sync_len)
{
	/* Given the MTU and sync_len, calculates an upper bound for the
	 * number of DUMP WQEs needed for the TX resync of a record.
	 */
	return nfrags + DIV_ROUND_UP(sync_len, sq->hw_mtu);
	return nfrags + DIV_ROUND_UP(sync_len, MLX5E_SW2HW_MTU(params, params->sw_mtu));
}

u16 mlx5e_ktls_get_stop_room(struct mlx5e_txqsq *sq)
u16 mlx5e_ktls_get_stop_room(struct mlx5e_params *params)
{
	u16 num_dumps, stop_room = 0;

	num_dumps = mlx5e_ktls_dumps_num_wqes(sq, MAX_SKB_FRAGS, TLS_MAX_PAYLOAD_SIZE);
	num_dumps = mlx5e_ktls_dumps_num_wqes(params, MAX_SKB_FRAGS, TLS_MAX_PAYLOAD_SIZE);

	stop_room += mlx5e_stop_room_for_wqe(MLX5E_TLS_SET_STATIC_PARAMS_WQEBBS);
	stop_room += mlx5e_stop_room_for_wqe(MLX5E_TLS_SET_PROGRESS_PARAMS_WQEBBS);
+1 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@ struct mlx5e_accel_tx_tls_state {
	u32 tls_tisn;
};

u16 mlx5e_ktls_get_stop_room(struct mlx5e_txqsq *sq);
u16 mlx5e_ktls_get_stop_room(struct mlx5e_params *params);

bool mlx5e_ktls_handle_tx_skb(struct tls_context *tls_ctx, struct mlx5e_txqsq *sq,
			      struct sk_buff *skb, int datalen,
+2 −4
Original line number Diff line number Diff line
@@ -385,15 +385,13 @@ void mlx5e_tls_handle_rx_skb_metadata(struct mlx5e_rq *rq, struct sk_buff *skb,
	*cqe_bcnt -= MLX5E_METADATA_ETHER_LEN;
}

u16 mlx5e_tls_get_stop_room(struct mlx5e_txqsq *sq)
u16 mlx5e_tls_get_stop_room(struct mlx5_core_dev *mdev, struct mlx5e_params *params)
{
	struct mlx5_core_dev *mdev = sq->channel->mdev;

	if (!mlx5_accel_is_tls_device(mdev))
		return 0;

	if (mlx5_accel_is_ktls_device(mdev))
		return mlx5e_ktls_get_stop_room(sq);
		return mlx5e_ktls_get_stop_room(params);

	/* FPGA */
	/* Resync SKB. */
Loading