net/mlx5: E-Switch, Tie rep load/unload to SD LAG state

On an SD device, vport representors are not functional until the SD
group is combined and shared FDB is active. Skip the initial load and
the reload paths in that window; reps are loaded as part of the SD LAG
activation flow once it becomes active.

In addition, explicitly unload representors when SD LAG is destroyed.

Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260612113904.537595-14-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Shay Drory 2026-06-12 14:39:02 +03:00 committed by Jakub Kicinski
parent de46472048
commit 68c2dd59a6
5 changed files with 58 additions and 0 deletions

View File

@ -959,6 +959,7 @@ int mlx5_eswitch_offloads_single_fdb_add_one(struct mlx5_eswitch *master_esw,
void mlx5_eswitch_offloads_single_fdb_del_one(struct mlx5_eswitch *master_esw,
struct mlx5_eswitch *slave_esw);
int mlx5_eswitch_reload_ib_reps(struct mlx5_eswitch *esw);
void mlx5_eswitch_unload_reps(struct mlx5_eswitch *esw);
bool mlx5_eswitch_is_peer(struct mlx5_eswitch *esw,
struct mlx5_eswitch *peer_esw);
@ -1063,6 +1064,9 @@ mlx5_eswitch_reload_ib_reps(struct mlx5_eswitch *esw)
return 0;
}
static inline void
mlx5_eswitch_unload_reps(struct mlx5_eswitch *esw) {}
static inline bool
mlx5_eswitch_block_encap(struct mlx5_core_dev *dev, bool from_fdb)
{

View File

@ -2863,6 +2863,10 @@ static int mlx5_esw_offloads_rep_load(struct mlx5_eswitch *esw, u16 vport_num)
int rep_type;
int err;
if (vport_num != MLX5_VPORT_UPLINK &&
mlx5_get_sd(esw->dev) && !mlx5_lag_is_active(esw->dev))
return 0;
rep = mlx5_eswitch_get_rep(esw, vport_num);
for (rep_type = 0; rep_type < NUM_REP_TYPES; rep_type++) {
err = __esw_offloads_load_rep(esw, rep, rep_type,
@ -3779,6 +3783,21 @@ static void esw_destroy_offloads_acl_tables(struct mlx5_eswitch *esw)
esw_vport_destroy_offloads_acl_tables(esw, vport);
}
void mlx5_eswitch_unload_reps(struct mlx5_eswitch *esw)
{
struct mlx5_eswitch_rep *rep;
unsigned long i;
if (!esw || esw->mode != MLX5_ESWITCH_OFFLOADS)
return;
mlx5_esw_for_each_rep(esw, i, rep) {
if (rep->vport == MLX5_VPORT_UPLINK)
continue;
mlx5_esw_offloads_rep_unload(esw, rep->vport);
}
}
int mlx5_eswitch_reload_ib_reps(struct mlx5_eswitch *esw)
{
struct mlx5_eswitch_rep *rep;
@ -3805,6 +3824,10 @@ int mlx5_eswitch_reload_ib_reps(struct mlx5_eswitch *esw)
if (!mlx5_sd_is_primary(esw->dev) &&
rep->vport == MLX5_VPORT_UPLINK)
continue;
if (rep->vport != MLX5_VPORT_UPLINK &&
mlx5_get_sd(esw->dev) && !mlx5_lag_is_active(esw->dev))
continue;
if (atomic_read(&rep->rep_data[REP_ETH].state) == REP_LOADED)
__esw_offloads_load_rep(esw, rep, REP_IB, NULL);
}
@ -4764,6 +4787,9 @@ static void mlx5_eswitch_reload_reps_blocked(struct mlx5_eswitch *esw)
return;
}
if (mlx5_get_sd(esw->dev) && !mlx5_lag_is_active(esw->dev))
return;
mlx5_esw_for_each_vport(esw, i, vport) {
if (!vport)
continue;

View File

@ -1312,6 +1312,32 @@ int mlx5_lag_reload_ib_reps_from_locked(struct mlx5_lag *ldev, u32 flags,
return mlx5_lag_reload_ib_reps(ldev, flags, filter, cont_on_fail);
}
static void mlx5_lag_unload_reps_unlocked(struct mlx5_lag *ldev, u32 filter)
{
struct lag_func *pf;
int i;
mlx5_lag_for_each(i, 0, ldev, filter) {
struct mlx5_eswitch *esw;
pf = mlx5_lag_pf(ldev, i);
esw = pf->dev->priv.eswitch;
mlx5_esw_reps_block(esw);
mlx5_eswitch_unload_reps(esw);
mlx5_esw_reps_unblock(esw);
}
}
void mlx5_lag_unload_reps_from_locked(struct mlx5_lag *ldev, u32 filter)
{
/* Same lock dance as mlx5_lag_reload_ib_reps: drop ldev->lock around
* the per-eswitch reps_lock to keep the reps_lock -> ldev->lock order.
*/
mlx5_lag_drop_lock_for_reps(ldev, filter);
mlx5_lag_unload_reps_unlocked(ldev, filter);
mlx5_lag_retake_lock_after_reps(ldev);
}
void mlx5_disable_lag(struct mlx5_lag *ldev)
{
bool shared_fdb = test_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, &ldev->mode_flags);

View File

@ -310,6 +310,7 @@ int mlx5_lag_num_devs(struct mlx5_lag *ldev);
int mlx5_lag_num_netdevs(struct mlx5_lag *ldev);
int mlx5_lag_reload_ib_reps_from_locked(struct mlx5_lag *ldev, u32 flags,
u32 filter, bool cont_on_fail);
void mlx5_lag_unload_reps_from_locked(struct mlx5_lag *ldev, u32 filter);
int mlx5_ldev_add_mdev(struct mlx5_lag *ldev, struct mlx5_core_dev *dev,
u32 group_id);
void mlx5_ldev_remove_mdev(struct mlx5_lag *ldev, struct mlx5_core_dev *dev);

View File

@ -296,6 +296,7 @@ void mlx5_lag_shared_fdb_destroy(struct mlx5_lag *ldev, u32 group_id)
pf->sd_fdb_active = false;
}
mlx5_lag_destroy_single_fdb_filter(ldev, group_id);
mlx5_lag_unload_reps_from_locked(ldev, filter);
}
mlx5_lag_add_devices_filter(ldev, filter);