mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 21:24:08 +08:00
net/mlx5e: Fix calculations for ICOSQ size
WQEs must not cross page boundaries, they are padded with NOPs if they don't fit the page. mlx5e_mpwrq_total_umr_wqebbs doesn't take into account this padding, risking reserving not enough space. The padding is not straightforward to add to this calculation, because WQEs of different sizes may be mixed together in the queue. If each page ends with a big WQE that doesn't fit and requires at most its size minus 1 WQEBB of padding, the total space can be much bigger than in case when smaller WQEs take advantage of this padding. Replace the wrong exact calculation by the following estimation. Each padding can be at most the size of the maximum WQE used in the queue minus one WQEBB. Let's call the rest of the page "useful space". If we divide the total size of all needed WQEs by this useful space, rounding up, we'll get the number of pages, which is enough to contain all these WQEs. It's correct, because every WQE that appeared on the boundary between two blocks of useful space would start in the useful space of one page and end in the padding of the same page, while our estimation reserved space for its tail in the next space, making the estimation not smaller than the real space occupied in the queue. The code actually uses a looser estimation: instead of taking the maximum size of all used WQE types minus 1 WQEBB, it takes the maximum hardware size of a WQE. It's made for simplicity and extensibility. Signed-off-by: Maxim Mikityanskiy <maximmi@nvidia.com> Reviewed-by: Saeed Mahameed <saeedm@nvidia.com> Reviewed-by: Tariq Toukan <tariqt@nvidia.com> Signed-off-by: Saeed Mahameed <saeedm@nvidia.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
f2f1675836
commit
0b9c86c785
@ -951,7 +951,7 @@ static u8 mlx5e_build_icosq_log_wq_sz(struct mlx5_core_dev *mdev,
|
||||
struct mlx5e_params *params,
|
||||
struct mlx5e_rq_param *rqp)
|
||||
{
|
||||
u32 wqebbs;
|
||||
u32 wqebbs, total_pages, useful_space;
|
||||
|
||||
/* MLX5_WQ_TYPE_CYCLIC */
|
||||
if (params->rq_wq_type != MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ)
|
||||
@ -998,6 +998,18 @@ static u8 mlx5e_build_icosq_log_wq_sz(struct mlx5_core_dev *mdev,
|
||||
if (params->packet_merge.type == MLX5E_PACKET_MERGE_SHAMPO)
|
||||
wqebbs += mlx5e_shampo_icosq_sz(mdev, params, rqp);
|
||||
|
||||
/* UMR WQEs don't cross the page boundary, they are padded with NOPs.
|
||||
* This padding is always smaller than the max WQE size. That gives us
|
||||
* at least (PAGE_SIZE - (max WQE size - MLX5_SEND_WQE_BB)) useful bytes
|
||||
* per page. The number of pages is estimated as the total size of WQEs
|
||||
* divided by the useful space in page, rounding up. If some WQEs don't
|
||||
* fully fit into the useful space, they can occupy part of the padding,
|
||||
* which proves this estimation to be correct (reserve enough space).
|
||||
*/
|
||||
useful_space = PAGE_SIZE - mlx5e_get_max_sq_wqebbs(mdev) + MLX5_SEND_WQE_BB;
|
||||
total_pages = DIV_ROUND_UP(wqebbs * MLX5_SEND_WQE_BB, useful_space);
|
||||
wqebbs = total_pages * (PAGE_SIZE / MLX5_SEND_WQE_BB);
|
||||
|
||||
return max_t(u8, MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE, order_base_2(wqebbs));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user