From: Cosmin Ratiu Move the SF table notifiers registration/unregistration outside of mlx5_init_one() / mlx5_uninit_one() and into the mlx5_mdev_init() / mlx5_mdev_uninit() functions. This is only done for non-SFs, since SFs do not have a SF table themselves and thus don't need notifiers. Signed-off-by: Cosmin Ratiu Reviewed-by: Carolina Jubran Signed-off-by: Tariq Toukan --- .../net/ethernet/mellanox/mlx5/core/main.c | 7 ++ .../ethernet/mellanox/mlx5/core/sf/devlink.c | 90 ++++++++++++------- .../net/ethernet/mellanox/mlx5/core/sf/sf.h | 11 +++ include/linux/mlx5/driver.h | 3 + 4 files changed, 78 insertions(+), 33 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 843ee452239f..0c3613ef39b1 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -1833,8 +1833,14 @@ static int mlx5_notifiers_init(struct mlx5_core_dev *dev) if (err) goto err_sf_hw_notifier; + err = mlx5_sf_notifiers_init(dev); + if (err) + goto err_sf_notifiers; + return 0; +err_sf_notifiers: + mlx5_sf_hw_notifier_cleanup(dev); err_sf_hw_notifier: mlx5_events_cleanup(dev); return err; @@ -1842,6 +1848,7 @@ static int mlx5_notifiers_init(struct mlx5_core_dev *dev) static void mlx5_notifiers_cleanup(struct mlx5_core_dev *dev) { + mlx5_sf_notifiers_cleanup(dev); mlx5_sf_hw_notifier_cleanup(dev); mlx5_events_cleanup(dev); } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c index 2ece4983d33f..b82323b8449e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c @@ -31,9 +31,6 @@ struct mlx5_sf_table { struct mlx5_core_dev *dev; /* To refer from notifier context. */ struct xarray function_ids; /* function id based lookup. */ struct mutex sf_state_lock; /* Serializes sf state among user cmds & vhca event handler. */ - struct notifier_block esw_nb; - struct notifier_block vhca_nb; - struct notifier_block mdev_nb; }; static struct mlx5_sf * @@ -391,11 +388,16 @@ static bool mlx5_sf_state_update_check(const struct mlx5_sf *sf, u8 new_state) static int mlx5_sf_vhca_event(struct notifier_block *nb, unsigned long opcode, void *data) { - struct mlx5_sf_table *table = container_of(nb, struct mlx5_sf_table, vhca_nb); + struct mlx5_core_dev *dev = container_of(nb, struct mlx5_core_dev, + priv.sf_table_vhca_nb); + struct mlx5_sf_table *table = dev->priv.sf_table; const struct mlx5_vhca_state_event *event = data; bool update = false; struct mlx5_sf *sf; + if (!table) + return 0; + mutex_lock(&table->sf_state_lock); sf = mlx5_sf_lookup_by_function_id(table, event->function_id); if (!sf) @@ -407,7 +409,7 @@ static int mlx5_sf_vhca_event(struct notifier_block *nb, unsigned long opcode, v update = mlx5_sf_state_update_check(sf, event->new_vhca_state); if (update) sf->hw_state = event->new_vhca_state; - trace_mlx5_sf_update_state(table->dev, sf->port_index, sf->controller, + trace_mlx5_sf_update_state(dev, sf->port_index, sf->controller, sf->hw_fn_id, sf->hw_state); unlock: mutex_unlock(&table->sf_state_lock); @@ -425,12 +427,16 @@ static void mlx5_sf_del_all(struct mlx5_sf_table *table) static int mlx5_sf_esw_event(struct notifier_block *nb, unsigned long event, void *data) { - struct mlx5_sf_table *table = container_of(nb, struct mlx5_sf_table, esw_nb); + struct mlx5_core_dev *dev = container_of(nb, struct mlx5_core_dev, + priv.sf_table_esw_nb); const struct mlx5_esw_event_info *mode = data; + if (!dev->priv.sf_table) + return 0; + switch (mode->new_mode) { case MLX5_ESWITCH_LEGACY: - mlx5_sf_del_all(table); + mlx5_sf_del_all(dev->priv.sf_table); break; default: break; @@ -441,15 +447,16 @@ static int mlx5_sf_esw_event(struct notifier_block *nb, unsigned long event, voi static int mlx5_sf_mdev_event(struct notifier_block *nb, unsigned long event, void *data) { - struct mlx5_sf_table *table = container_of(nb, struct mlx5_sf_table, mdev_nb); + struct mlx5_core_dev *dev = container_of(nb, struct mlx5_core_dev, + priv.sf_table_mdev_nb); struct mlx5_sf_peer_devlink_event_ctx *event_ctx = data; + struct mlx5_sf_table *table = dev->priv.sf_table; int ret = NOTIFY_DONE; struct mlx5_sf *sf; - if (event != MLX5_DRIVER_EVENT_SF_PEER_DEVLINK) + if (!table || event != MLX5_DRIVER_EVENT_SF_PEER_DEVLINK) return NOTIFY_DONE; - mutex_lock(&table->sf_state_lock); sf = mlx5_sf_lookup_by_function_id(table, event_ctx->fn_id); if (!sf) @@ -464,10 +471,40 @@ static int mlx5_sf_mdev_event(struct notifier_block *nb, unsigned long event, vo return ret; } +int mlx5_sf_notifiers_init(struct mlx5_core_dev *dev) +{ + int err; + + if (mlx5_core_is_sf(dev)) + return 0; + + dev->priv.sf_table_esw_nb.notifier_call = mlx5_sf_esw_event; + err = mlx5_esw_event_notifier_register(dev, &dev->priv.sf_table_esw_nb); + if (err) + return err; + + dev->priv.sf_table_vhca_nb.notifier_call = mlx5_sf_vhca_event; + err = mlx5_vhca_event_notifier_register(dev, + &dev->priv.sf_table_vhca_nb); + if (err) + goto vhca_err; + + dev->priv.sf_table_mdev_nb.notifier_call = mlx5_sf_mdev_event; + err = mlx5_blocking_notifier_register(dev, &dev->priv.sf_table_mdev_nb); + if (err) + goto mdev_err; + + return 0; +mdev_err: + mlx5_vhca_event_notifier_unregister(dev, &dev->priv.sf_table_vhca_nb); +vhca_err: + mlx5_esw_event_notifier_unregister(dev, &dev->priv.sf_table_esw_nb); + return err; +} + int mlx5_sf_table_init(struct mlx5_core_dev *dev) { struct mlx5_sf_table *table; - int err; if (!mlx5_sf_table_supported(dev) || !mlx5_vhca_event_supported(dev)) return 0; @@ -480,28 +517,18 @@ int mlx5_sf_table_init(struct mlx5_core_dev *dev) table->dev = dev; xa_init(&table->function_ids); dev->priv.sf_table = table; - table->esw_nb.notifier_call = mlx5_sf_esw_event; - err = mlx5_esw_event_notifier_register(dev, &table->esw_nb); - if (err) - goto reg_err; - - table->vhca_nb.notifier_call = mlx5_sf_vhca_event; - err = mlx5_vhca_event_notifier_register(table->dev, &table->vhca_nb); - if (err) - goto vhca_err; - - table->mdev_nb.notifier_call = mlx5_sf_mdev_event; - mlx5_blocking_notifier_register(dev, &table->mdev_nb); return 0; +} -vhca_err: - mlx5_esw_event_notifier_unregister(dev, &table->esw_nb); -reg_err: - mutex_destroy(&table->sf_state_lock); - kfree(table); - dev->priv.sf_table = NULL; - return err; +void mlx5_sf_notifiers_cleanup(struct mlx5_core_dev *dev) +{ + if (mlx5_core_is_sf(dev)) + return; + + mlx5_blocking_notifier_unregister(dev, &dev->priv.sf_table_mdev_nb); + mlx5_vhca_event_notifier_unregister(dev, &dev->priv.sf_table_vhca_nb); + mlx5_esw_event_notifier_unregister(dev, &dev->priv.sf_table_esw_nb); } void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev) @@ -511,9 +538,6 @@ void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev) if (!table) return; - mlx5_blocking_notifier_unregister(dev, &table->mdev_nb); - mlx5_vhca_event_notifier_unregister(table->dev, &table->vhca_nb); - mlx5_esw_event_notifier_unregister(dev, &table->esw_nb); mutex_destroy(&table->sf_state_lock); WARN_ON(!xa_empty(&table->function_ids)); kfree(table); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h b/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h index 3922dacffae8..d8a934a0e968 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h @@ -16,7 +16,9 @@ int mlx5_sf_hw_notifier_init(struct mlx5_core_dev *dev); void mlx5_sf_hw_notifier_cleanup(struct mlx5_core_dev *dev); void mlx5_sf_hw_table_destroy(struct mlx5_core_dev *dev); +int mlx5_sf_notifiers_init(struct mlx5_core_dev *dev); int mlx5_sf_table_init(struct mlx5_core_dev *dev); +void mlx5_sf_notifiers_cleanup(struct mlx5_core_dev *dev); void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev); bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev); @@ -58,11 +60,20 @@ static inline void mlx5_sf_hw_table_destroy(struct mlx5_core_dev *dev) { } +static inline int mlx5_sf_notifiers_init(struct mlx5_core_dev *dev) +{ + return 0; +} + static inline int mlx5_sf_table_init(struct mlx5_core_dev *dev) { return 0; } +static inline void mlx5_sf_notifiers_cleanup(struct mlx5_core_dev *dev) +{ +} + static inline void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev) { } diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index a51bea44d57c..7dbef112deaf 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -622,6 +622,9 @@ struct mlx5_priv { #ifdef CONFIG_MLX5_SF_MANAGER struct notifier_block sf_hw_table_vhca_nb; struct mlx5_sf_hw_table *sf_hw_table; + struct notifier_block sf_table_esw_nb; + struct notifier_block sf_table_vhca_nb; + struct notifier_block sf_table_mdev_nb; struct mlx5_sf_table *sf_table; #endif struct blocking_notifier_head lag_nh; -- 2.31.1