From: Mark Bloch mlx5_eswitch_register_vport_reps() merely sets the callbacks. The actual representor load/unload requires devlink locking and shouldn’t run from the registration context. Queue a work that acquires the devlink lock, loads all relevant reps. This lets load happen where the needed locks can be taken. Signed-off-by: Mark Bloch Signed-off-by: Tariq Toukan --- .../mellanox/mlx5/core/eswitch_offloads.c | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index 4b626ffcfa8e..279490c0074c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -4535,6 +4535,38 @@ mlx5_eswitch_register_vport_reps_blocked(struct mlx5_eswitch *esw, } } +static void mlx5_eswitch_reload_reps_blocked(struct mlx5_eswitch *esw) +{ + struct mlx5_vport *vport; + unsigned long i; + + if (esw->mode != MLX5_ESWITCH_OFFLOADS) + return; + + if (mlx5_esw_offloads_rep_load(esw, MLX5_VPORT_UPLINK)) + return; + + mlx5_esw_for_each_vport(esw, i, vport) { + if (!vport) + continue; + if (!vport->enabled) + continue; + if (vport->vport == MLX5_VPORT_UPLINK) + continue; + if (!mlx5_eswitch_vport_has_rep(esw, vport->vport)) + continue; + + mlx5_esw_offloads_rep_load(esw, vport->vport); + } +} + +static void mlx5_eswitch_reload_reps(struct mlx5_eswitch *esw) +{ + mlx5_esw_reps_block(esw); + mlx5_eswitch_reload_reps_blocked(esw); + mlx5_esw_reps_unblock(esw); +} + void mlx5_eswitch_register_vport_reps(struct mlx5_eswitch *esw, const struct mlx5_eswitch_rep_ops *ops, u8 rep_type) @@ -4542,6 +4574,8 @@ void mlx5_eswitch_register_vport_reps(struct mlx5_eswitch *esw, mlx5_esw_reps_block(esw); mlx5_eswitch_register_vport_reps_blocked(esw, ops, rep_type); mlx5_esw_reps_unblock(esw); + + mlx5_esw_add_work(esw, mlx5_eswitch_reload_reps); } EXPORT_SYMBOL(mlx5_eswitch_register_vport_reps); -- 2.44.0