mirror of
https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable.git
synced 2025-09-13 11:07:46 +10:00
net/mlx5e: Preserve shared buffer capacity during headroom updates
[ Upstream commit8b0587a885
] When port buffer headroom changes, port_update_shared_buffer() recalculates the shared buffer size and splits it in a 3:1 ratio (lossy:lossless) - Currently, the calculation is: lossless = shared / 4; lossy = (shared / 4) * 3; Meaning, the calculation dropped the remainder of shared % 4 due to integer division, unintentionally reducing the total shared buffer by up to three cells on each update. Over time, this could shrink the buffer below usable size. Fix it by changing the calculation to: lossless = shared / 4; lossy = shared - lossless; This retains all buffer cells while still approximating the intended 3:1 split, preventing capacity loss over time. While at it, perform headroom calculations in units of cells rather than in bytes for more accurate calculations avoiding extra divisions. Fixes:a440030d89
("net/mlx5e: Update shared buffer along with device buffer changes") Signed-off-by: Armen Ratner <armeng@nvidia.com> Signed-off-by: Maher Sanalla <msanalla@nvidia.com> Reviewed-by: Tariq Toukan <tariqt@nvidia.com> Signed-off-by: Alexei Lazar <alazar@nvidia.com> Signed-off-by: Mark Bloch <mbloch@nvidia.com> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> Link: https://patch.msgid.link/20250820133209.389065-9-mbloch@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
3ef5a3a68b
commit
66d25bb8ab
@ -272,8 +272,8 @@ static int port_update_shared_buffer(struct mlx5_core_dev *mdev,
|
||||
/* Total shared buffer size is split in a ratio of 3:1 between
|
||||
* lossy and lossless pools respectively.
|
||||
*/
|
||||
lossy_epool_size = (shared_buffer_size / 4) * 3;
|
||||
lossless_ipool_size = shared_buffer_size / 4;
|
||||
lossy_epool_size = shared_buffer_size - lossless_ipool_size;
|
||||
|
||||
mlx5e_port_set_sbpr(mdev, 0, MLX5_EGRESS_DIR, MLX5_LOSSY_POOL, 0,
|
||||
lossy_epool_size);
|
||||
@ -288,14 +288,12 @@ static int port_set_buffer(struct mlx5e_priv *priv,
|
||||
u16 port_buff_cell_sz = priv->dcbx.port_buff_cell_sz;
|
||||
struct mlx5_core_dev *mdev = priv->mdev;
|
||||
int sz = MLX5_ST_SZ_BYTES(pbmc_reg);
|
||||
u32 new_headroom_size = 0;
|
||||
u32 current_headroom_size;
|
||||
u32 current_headroom_cells = 0;
|
||||
u32 new_headroom_cells = 0;
|
||||
void *in;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
current_headroom_size = port_buffer->headroom_size;
|
||||
|
||||
in = kzalloc(sz, GFP_KERNEL);
|
||||
if (!in)
|
||||
return -ENOMEM;
|
||||
@ -306,12 +304,14 @@ static int port_set_buffer(struct mlx5e_priv *priv,
|
||||
|
||||
for (i = 0; i < MLX5E_MAX_NETWORK_BUFFER; i++) {
|
||||
void *buffer = MLX5_ADDR_OF(pbmc_reg, in, buffer[i]);
|
||||
current_headroom_cells += MLX5_GET(bufferx_reg, buffer, size);
|
||||
|
||||
u64 size = port_buffer->buffer[i].size;
|
||||
u64 xoff = port_buffer->buffer[i].xoff;
|
||||
u64 xon = port_buffer->buffer[i].xon;
|
||||
|
||||
new_headroom_size += size;
|
||||
do_div(size, port_buff_cell_sz);
|
||||
new_headroom_cells += size;
|
||||
do_div(xoff, port_buff_cell_sz);
|
||||
do_div(xon, port_buff_cell_sz);
|
||||
MLX5_SET(bufferx_reg, buffer, size, size);
|
||||
@ -320,10 +320,8 @@ static int port_set_buffer(struct mlx5e_priv *priv,
|
||||
MLX5_SET(bufferx_reg, buffer, xon_threshold, xon);
|
||||
}
|
||||
|
||||
new_headroom_size /= port_buff_cell_sz;
|
||||
current_headroom_size /= port_buff_cell_sz;
|
||||
err = port_update_shared_buffer(priv->mdev, current_headroom_size,
|
||||
new_headroom_size);
|
||||
err = port_update_shared_buffer(priv->mdev, current_headroom_cells,
|
||||
new_headroom_cells);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user