From: Shay Drory The LAG xarray iterators returned MLX5_MAX_PORTS as their end-of-walk sentinel, and the open-coded callers compared the current index against MLX5_MAX_PORTS to detect the end of iteration. This ties iteration to a compile-time maximum rather than to the actual number of LAG members. Add ldev->max_funcs, and use it as the loop bound. Update the open-coded callers accordingly. When a member is added at an xarray index >= ldev->max_funcs, increase max_funcs. In addition, remove the xa_alloc() limit of MLX5_MAX_PORTS. No functional change; this only removes the dependency on MLX5_MAX_PORTS. Signed-off-by: Shay Drory Reviewed-by: Mark Bloch Reviewed-by: Moshe Shemesh Signed-off-by: Tariq Toukan --- .../net/ethernet/mellanox/mlx5/core/lag/lag.c | 22 +++++++++++-------- .../net/ethernet/mellanox/mlx5/core/lag/lag.h | 3 ++- .../ethernet/mellanox/mlx5/core/lag/mpesw.c | 2 +- .../mellanox/mlx5/core/lag/shared_fdb.c | 2 +- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c index b2ac5c671ae6..73bce918cddb 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c @@ -395,6 +395,7 @@ 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->max_funcs = ldev->ports; return ldev; err_wq: @@ -1284,7 +1285,7 @@ static void mlx5_lag_assert_locked_transition(struct mlx5_lag *ldev, u32 filter) lockdep_assert_held(&ldev->lock); i = mlx5_get_next_lag_func(ldev, 0, filter); - if (i < MLX5_MAX_PORTS) { + if (i < ldev->max_funcs) { pf = mlx5_lag_pf(ldev, i); if (filter == MLX5_LAG_FILTER_PORTS || filter == MLX5_LAG_FILTER_ALL) @@ -1831,7 +1832,7 @@ struct mlx5_devcom_comp_dev *mlx5_lag_get_devcom_comp(struct mlx5_lag *ldev) filter = ldev->virt_lag ? MLX5_LAG_FILTER_ALL : MLX5_LAG_FILTER_PORTS; i = mlx5_get_next_lag_func(ldev, 0, filter); - if (i < MLX5_MAX_PORTS) { + if (i < ldev->max_funcs) { pf = mlx5_lag_pf(ldev, i); devcom = pf->dev->priv.hca_devcom_comp; } @@ -2095,7 +2096,7 @@ static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev, break; } } - if (i < MLX5_MAX_PORTS) { + if (i < ldev->ports) { if (netif_is_bond_master(upper)) { slave = bond_slave_get_rcu(ndev_tmp); if (slave) @@ -2360,13 +2361,16 @@ int mlx5_ldev_add_mdev(struct mlx5_lag *ldev, if (!pf) return -ENOMEM; - err = xa_alloc(&ldev->pfs, &idx, pf, XA_LIMIT(0, MLX5_MAX_PORTS - 1), + err = xa_alloc(&ldev->pfs, &idx, pf, XA_LIMIT(0, U8_MAX - 1), GFP_KERNEL); if (err) { kfree(pf); return err; } + /* max_funcs is the iteration ceiling; grow it, never shrink. */ + if (idx >= ldev->max_funcs) + ldev->max_funcs = idx + 1; pf->idx = idx; pf->dev = dev; pf->group_id = group_id; @@ -2395,7 +2399,7 @@ void mlx5_ldev_remove_mdev(struct mlx5_lag *ldev, if (pf->dev == dev) break; } - if (i >= MLX5_MAX_PORTS) + if (i >= ldev->max_funcs) return; if (pf->port_change_nb.nb.notifier_call) @@ -2608,7 +2612,7 @@ int mlx5_get_next_lag_func(struct mlx5_lag *ldev, int start_idx, u32 filter) MLX5_LAG_XA_MARK_PORT, start_idx) if (pf->dev) return idx; - return MLX5_MAX_PORTS; + return ldev->max_funcs; } xa_for_each_start(&ldev->pfs, idx, pf, start_idx) { @@ -2618,7 +2622,7 @@ int mlx5_get_next_lag_func(struct mlx5_lag *ldev, int start_idx, u32 filter) filter == pf->group_id) return idx; } - return MLX5_MAX_PORTS; + return ldev->max_funcs; } bool mlx5_lag_is_roce(struct mlx5_core_dev *dev) @@ -2868,7 +2872,7 @@ struct mlx5_core_dev *mlx5_lag_get_next_peer_mdev(struct mlx5_core_dev *dev, int if (!ldev) goto unlock; - if (*i == MLX5_MAX_PORTS) + if (*i == ldev->max_funcs) goto unlock; mlx5_lag_for_each(idx, *i, ldev, mlx5_lag_get_filter(ldev, dev)) { pf = mlx5_lag_pf(ldev, idx); @@ -2876,7 +2880,7 @@ struct mlx5_core_dev *mlx5_lag_get_next_peer_mdev(struct mlx5_core_dev *dev, int break; } - if (idx == MLX5_MAX_PORTS) { + if (idx == ldev->max_funcs) { *i = idx; goto unlock; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h index 872cc769297c..479d9f42ff3f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h @@ -83,6 +83,7 @@ struct mlx5_lag { unsigned long mode_flags; unsigned long state_flags; u8 ports; + u8 max_funcs; u8 buckets; bool virt_lag; int mode_changes_in_progress; @@ -298,7 +299,7 @@ static inline bool mlx5_lag_is_supported(struct mlx5_core_dev *dev) #define mlx5_lag_for_each(i, start_index, ldev, filter) \ for (int tmp = start_index; \ tmp = mlx5_get_next_lag_func(ldev, tmp, filter), \ - i = tmp, tmp < MLX5_MAX_PORTS; tmp++) + i = tmp, tmp < (ldev)->max_funcs; tmp++) #define mlx5_lag_for_each_reverse(i, start_index, end_index, ldev, filter) \ for (int tmp = start_index, tmp1 = end_index; \ diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c index b65ad9a26f71..56faa1d498c7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c @@ -223,7 +223,7 @@ void mlx5_mpesw_sd_devcoms_unlock(struct mlx5_lag *ldev) struct mlx5_devcom_comp_dev *sd_devcom; int i; - mlx5_ldev_for_each_reverse(i, MLX5_MAX_PORTS, 0, ldev) { + mlx5_ldev_for_each_reverse(i, ldev->max_funcs, 0, ldev) { sd_devcom = mlx5_sd_get_devcom(mlx5_lag_pf(ldev, i)->dev); if (sd_devcom) mlx5_devcom_comp_unlock(sd_devcom); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/shared_fdb.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/shared_fdb.c index 7c7e6c832a93..29048b0c2797 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lag/shared_fdb.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/shared_fdb.c @@ -71,7 +71,7 @@ static int mlx5_lag_create_single_fdb_filter(struct mlx5_lag *ldev, u32 filter) err = mlx5_eswitch_offloads_single_fdb_add_one(master_esw, slave_esw, - ldev->ports); + ldev->max_funcs); if (err) goto err; } -- 2.44.0