Commit ac5f3956 authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller

net/mlx5: SF, Implement peer devlink set for SF representor devlink port

Benefit from the existence of internal mlx5 notifier and extend it by
event MLX5_DRIVER_EVENT_SF_PEER_DEVLINK. Use this event from SF
auxiliary device probe/remove functions to pass the registered SF
devlink instance to the SF representor.

Process the new event in SF representor code and call
devl_port_fn_devlink_set() to do the assignments. Implement this in work
to avoid possible deadlock when probe/remove function of SF may be
called with devlink instance lock held during devlink reload.
Signed-off-by: default avatarJiri Pirko <jiri@nvidia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0b7a2721
...@@ -19,6 +19,12 @@ struct mlx5_sf_dev { ...@@ -19,6 +19,12 @@ struct mlx5_sf_dev {
u16 fn_id; u16 fn_id;
}; };
struct mlx5_sf_peer_devlink_event_ctx {
u16 fn_id;
struct devlink *devlink;
int err;
};
void mlx5_sf_dev_table_create(struct mlx5_core_dev *dev); void mlx5_sf_dev_table_create(struct mlx5_core_dev *dev);
void mlx5_sf_dev_table_destroy(struct mlx5_core_dev *dev); void mlx5_sf_dev_table_destroy(struct mlx5_core_dev *dev);
......
...@@ -8,6 +8,20 @@ ...@@ -8,6 +8,20 @@
#include "dev.h" #include "dev.h"
#include "devlink.h" #include "devlink.h"
static int mlx5_core_peer_devlink_set(struct mlx5_sf_dev *sf_dev, struct devlink *devlink)
{
struct mlx5_sf_peer_devlink_event_ctx event_ctx = {
.fn_id = sf_dev->fn_id,
.devlink = devlink,
};
int ret;
ret = mlx5_blocking_notifier_call_chain(sf_dev->parent_mdev,
MLX5_DRIVER_EVENT_SF_PEER_DEVLINK,
&event_ctx);
return ret == NOTIFY_OK ? event_ctx.err : 0;
}
static int mlx5_sf_dev_probe(struct auxiliary_device *adev, const struct auxiliary_device_id *id) static int mlx5_sf_dev_probe(struct auxiliary_device *adev, const struct auxiliary_device_id *id)
{ {
struct mlx5_sf_dev *sf_dev = container_of(adev, struct mlx5_sf_dev, adev); struct mlx5_sf_dev *sf_dev = container_of(adev, struct mlx5_sf_dev, adev);
...@@ -54,9 +68,21 @@ static int mlx5_sf_dev_probe(struct auxiliary_device *adev, const struct auxilia ...@@ -54,9 +68,21 @@ static int mlx5_sf_dev_probe(struct auxiliary_device *adev, const struct auxilia
mlx5_core_warn(mdev, "mlx5_init_one err=%d\n", err); mlx5_core_warn(mdev, "mlx5_init_one err=%d\n", err);
goto init_one_err; goto init_one_err;
} }
err = mlx5_core_peer_devlink_set(sf_dev, devlink);
if (err) {
mlx5_core_warn(mdev, "mlx5_core_peer_devlink_set err=%d\n", err);
goto peer_devlink_set_err;
}
devlink_register(devlink); devlink_register(devlink);
return 0; return 0;
peer_devlink_set_err:
if (mlx5_dev_is_lightweight(sf_dev->mdev))
mlx5_uninit_one_light(sf_dev->mdev);
else
mlx5_uninit_one(sf_dev->mdev);
init_one_err: init_one_err:
iounmap(mdev->iseg); iounmap(mdev->iseg);
remap_err: remap_err:
......
...@@ -28,6 +28,7 @@ struct mlx5_sf_table { ...@@ -28,6 +28,7 @@ struct mlx5_sf_table {
struct mutex sf_state_lock; /* Serializes sf state among user cmds & vhca event handler. */ struct mutex sf_state_lock; /* Serializes sf state among user cmds & vhca event handler. */
struct notifier_block esw_nb; struct notifier_block esw_nb;
struct notifier_block vhca_nb; struct notifier_block vhca_nb;
struct notifier_block mdev_nb;
}; };
static struct mlx5_sf * static struct mlx5_sf *
...@@ -511,6 +512,35 @@ static int mlx5_sf_esw_event(struct notifier_block *nb, unsigned long event, voi ...@@ -511,6 +512,35 @@ static int mlx5_sf_esw_event(struct notifier_block *nb, unsigned long event, voi
return 0; return 0;
} }
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_sf_peer_devlink_event_ctx *event_ctx = data;
int ret = NOTIFY_DONE;
struct mlx5_sf *sf;
if (event != MLX5_DRIVER_EVENT_SF_PEER_DEVLINK)
return NOTIFY_DONE;
table = mlx5_sf_table_try_get(table->dev);
if (!table)
return NOTIFY_DONE;
mutex_lock(&table->sf_state_lock);
sf = mlx5_sf_lookup_by_function_id(table, event_ctx->fn_id);
if (!sf)
goto out;
event_ctx->err = devl_port_fn_devlink_set(&sf->dl_port.dl_port,
event_ctx->devlink);
ret = NOTIFY_OK;
out:
mutex_unlock(&table->sf_state_lock);
mlx5_sf_table_put(table);
return ret;
}
static bool mlx5_sf_table_supported(const struct mlx5_core_dev *dev) static bool mlx5_sf_table_supported(const struct mlx5_core_dev *dev)
{ {
return dev->priv.eswitch && MLX5_ESWITCH_MANAGER(dev) && return dev->priv.eswitch && MLX5_ESWITCH_MANAGER(dev) &&
...@@ -544,6 +574,9 @@ int mlx5_sf_table_init(struct mlx5_core_dev *dev) ...@@ -544,6 +574,9 @@ int mlx5_sf_table_init(struct mlx5_core_dev *dev)
if (err) if (err)
goto vhca_err; goto vhca_err;
table->mdev_nb.notifier_call = mlx5_sf_mdev_event;
mlx5_blocking_notifier_register(dev, &table->mdev_nb);
return 0; return 0;
vhca_err: vhca_err:
...@@ -562,6 +595,7 @@ void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev) ...@@ -562,6 +595,7 @@ void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev)
if (!table) if (!table)
return; return;
mlx5_blocking_notifier_unregister(dev, &table->mdev_nb);
mlx5_vhca_event_notifier_unregister(table->dev, &table->vhca_nb); mlx5_vhca_event_notifier_unregister(table->dev, &table->vhca_nb);
mlx5_esw_event_notifier_unregister(dev->priv.eswitch, &table->esw_nb); mlx5_esw_event_notifier_unregister(dev->priv.eswitch, &table->esw_nb);
WARN_ON(refcount_read(&table->refcount)); WARN_ON(refcount_read(&table->refcount));
......
...@@ -366,6 +366,7 @@ enum mlx5_driver_event { ...@@ -366,6 +366,7 @@ enum mlx5_driver_event {
MLX5_DRIVER_EVENT_UPLINK_NETDEV, MLX5_DRIVER_EVENT_UPLINK_NETDEV,
MLX5_DRIVER_EVENT_MACSEC_SA_ADDED, MLX5_DRIVER_EVENT_MACSEC_SA_ADDED,
MLX5_DRIVER_EVENT_MACSEC_SA_DELETED, MLX5_DRIVER_EVENT_MACSEC_SA_DELETED,
MLX5_DRIVER_EVENT_SF_PEER_DEVLINK,
}; };
enum { enum {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment