mirror of
https://github.com/torvalds/linux.git
synced 2026-07-30 19:21:28 +02:00
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:
parent
de46472048
commit
68c2dd59a6
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user