[PATCH net-next 03/13] net/mlx5: LAG, allocate v2p_map dynamically
flat view
COOLING13d
IN NET-NEXT: 2 (0M)
From: Tariq Toukan <tariqt@nvidia.com>
Date: 2026-09-23 10:40:39
Also in:
linux-rdma, lkml
Subsystem:
mellanox mlx5 core vpi driver, networking drivers, the rest · Maintainers:
Saeed Mahameed, Leon Romanovsky, Tariq Toukan, Mark Bloch, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
2 review trailers; queued in net-next as d9f3227f673b on 2026-09-29.
From: Shay Drory <redacted> 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 <redacted> Reviewed-by: Moshe Shemesh <redacted> Reviewed-by: Akiva Goldberger <redacted> Signed-off-by: Tariq Toukan <tariqt@nvidia.com> --- .../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