[PATCH net-next 03/13] net/mlx5: LAG, allocate v2p_map dynamically

From: Tariq Toukan

Date: Wed Sep 23 2026 - 06:50:54 EST


From: Shay Drory <shayd@xxxxxxxxxx>

v2p_map was a fixed array sized MLX5_MAX_PORTS *
MLX5_LAG_MAX_HASH_BUCKETS embedded in struct mlx5_lag. Turn it into a
pointer allocated in mlx5_lag_dev_alloc() once ldev->ports is known,
sized by the actual port count, and free it in mlx5_ldev_free(). The
ldev->ports / ldev->buckets initialization is moved up so the allocation
can use it.

The matching scratch buffer in mlx5_modify_lag() is converted from a
MLX5_MAX_PORTS-sized stack array to a kcalloc() of the same extent, with
the trailing teardown reworked through a goto so the buffer is freed on
every path. The memcpy() that previously relied on sizeof() of the stack
array now uses the explicit ldev->ports * MLX5_LAG_MAX_HASH_BUCKETS
span.

No functional change; this removes v2p_map's dependency on
MLX5_MAX_PORTS.

Signed-off-by: Shay Drory <shayd@xxxxxxxxxx>
Reviewed-by: Moshe Shemesh <moshe@xxxxxxxxxx>
Reviewed-by: Akiva Goldberger <agoldberger@xxxxxxxxxx>
Signed-off-by: Tariq Toukan <tariqt@xxxxxxxxxx>
---
.../net/ethernet/mellanox/mlx5/core/lag/lag.c | 38 ++++++++++++++-----
.../net/ethernet/mellanox/mlx5/core/lag/lag.h | 2 +-
2 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
index c655f6e32e9b..00b0159cb422 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
@@ -308,6 +308,7 @@ static void mlx5_ldev_free(struct kref *ref)
cancel_work_sync(&ldev->speed_update_work);
destroy_workqueue(ldev->wq);
mutex_destroy(&ldev->lock);
+ kfree(ldev->v2p_map);
kfree(ldev);
}

@@ -330,11 +331,16 @@ static struct mlx5_lag *mlx5_lag_dev_alloc(struct mlx5_core_dev *dev)
if (!ldev)
return NULL;

+ ldev->ports = MLX5_CAP_GEN(dev, num_lag_ports);
+ ldev->buckets = 1;
+ ldev->v2p_map = kcalloc(ldev->ports * MLX5_LAG_MAX_HASH_BUCKETS,
+ sizeof(*ldev->v2p_map), GFP_KERNEL);
+ if (!ldev->v2p_map)
+ goto err_v2p_map;
+
ldev->wq = create_singlethread_workqueue("mlx5_lag");
- if (!ldev->wq) {
- kfree(ldev);
- return NULL;
- }
+ if (!ldev->wq)
+ goto err_wq;

kref_init(&ldev->ref);
mutex_init(&ldev->lock);
@@ -358,10 +364,13 @@ static struct mlx5_lag *mlx5_lag_dev_alloc(struct mlx5_core_dev *dev)
mlx5_core_err(dev, "Failed to init multipath lag err=%d\n",
err);

- ldev->ports = MLX5_CAP_GEN(dev, num_lag_ports);
- ldev->buckets = 1;
-
return ldev;
+
+err_wq:
+ kfree(ldev->v2p_map);
+err_v2p_map:
+ kfree(ldev);
+ return NULL;
}

int mlx5_lag_dev_get_netdev_idx(struct mlx5_lag *ldev,
@@ -853,8 +862,8 @@ void mlx5_modify_lag(struct mlx5_lag *ldev,
struct lag_tracker *tracker)
{
int first_idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
- u8 ports[MLX5_MAX_PORTS * MLX5_LAG_MAX_HASH_BUCKETS] = {};
struct mlx5_core_dev *dev0;
+ u8 *ports;
int idx;
int err;
int i;
@@ -864,6 +873,12 @@ void mlx5_modify_lag(struct mlx5_lag *ldev,
return;

dev0 = mlx5_lag_pf(ldev, first_idx)->dev;
+
+ ports = kcalloc(ldev->ports * MLX5_LAG_MAX_HASH_BUCKETS,
+ sizeof(*ports), GFP_KERNEL);
+ if (!ports)
+ return;
+
mlx5_infer_tx_affinity_mapping(tracker, ldev, ldev->buckets, ports);

mlx5_ldev_for_each(i, 0, ldev) {
@@ -876,9 +891,10 @@ void mlx5_modify_lag(struct mlx5_lag *ldev,
mlx5_core_err(dev0,
"Failed to modify LAG (%d)\n",
err);
- return;
+ goto out;
}
- memcpy(ldev->v2p_map, ports, sizeof(ports));
+ memcpy(ldev->v2p_map, ports,
+ ldev->ports * MLX5_LAG_MAX_HASH_BUCKETS);

mlx5_lag_print_mapping(dev0, ldev, tracker,
ldev->mode_flags);
@@ -899,6 +915,8 @@ void mlx5_modify_lag(struct mlx5_lag *ldev,
ndev);
dev_put(ndev);
}
+out:
+ kfree(ports);
}

static int mlx5_lag_set_port_sel_mode(struct mlx5_lag *ldev,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
index e9f0ef83ce1d..8552792b9035 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
@@ -85,7 +85,7 @@ struct mlx5_lag {
u8 ports;
u8 buckets;
int mode_changes_in_progress;
- u8 v2p_map[MLX5_MAX_PORTS * MLX5_LAG_MAX_HASH_BUCKETS];
+ u8 *v2p_map;
struct kref ref;
struct xarray pfs;
struct lag_tracker tracker;
--
2.44.0