| From 89eb26b97f6900e73d8c796889b4050f785c8778 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 29 Sep 2025 00:02:08 +0300 |
| Subject: net/mlx5: pagealloc: Fix reclaim race during command interface |
| teardown |
| |
| From: Shay Drory <shayd@nvidia.com> |
| |
| [ Upstream commit 79a0e32b32ac4e4f9e4bb22be97f371c8c116c88 ] |
| |
| The reclaim_pages_cmd() function sends a command to the firmware to |
| reclaim pages if the command interface is active. |
| |
| A race condition can occur if the command interface goes down (e.g., due |
| to a PCI error) while the mlx5_cmd_do() call is in flight. In this |
| case, mlx5_cmd_do() will return an error. The original code would |
| propagate this error immediately, bypassing the software-based page |
| reclamation logic that is supposed to run when the command interface is |
| down. |
| |
| Fix this by checking whether mlx5_cmd_do() returns -ENXIO, which mark |
| that command interface is down. If this is the case, fall through to |
| the software reclamation path. If the command failed for any another |
| reason, or finished successfully, return as before. |
| |
| Fixes: b898ce7bccf1 ("net/mlx5: cmdif, Avoid skipping reclaim pages if FW is not accessible") |
| Signed-off-by: Shay Drory <shayd@nvidia.com> |
| Reviewed-by: Moshe Shemesh <moshe@nvidia.com> |
| Signed-off-by: Tariq Toukan <tariqt@nvidia.com> |
| Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c | 7 +++++-- |
| 1 file changed, 5 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c |
| index 9bc9bd83c2324..cd68c4b2c0bf9 100644 |
| --- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c |
| +++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c |
| @@ -489,9 +489,12 @@ static int reclaim_pages_cmd(struct mlx5_core_dev *dev, |
| u32 func_id; |
| u32 npages; |
| u32 i = 0; |
| + int err; |
| |
| - if (!mlx5_cmd_is_down(dev)) |
| - return mlx5_cmd_do(dev, in, in_size, out, out_size); |
| + err = mlx5_cmd_do(dev, in, in_size, out, out_size); |
| + /* If FW is gone (-ENXIO), proceed to forceful reclaim */ |
| + if (err != -ENXIO) |
| + return err; |
| |
| /* No hard feelings, we want our pages back! */ |
| npages = MLX5_GET(manage_pages_in, in, input_num_entries); |
| -- |
| 2.51.0 |
| |