Skip to content

Commit

Permalink
net/mlx5: SF, Implement peer devlink set for SF representor devlink port
Browse files Browse the repository at this point in the history
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: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jiri Pirko authored and David S. Miller committed Sep 17, 2023
1 parent 0b7a272 commit ac5f395
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 0 deletions.
6 changes: 6 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ struct mlx5_sf_dev {
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_destroy(struct mlx5_core_dev *dev);

Expand Down
26 changes: 26 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,20 @@
#include "dev.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)
{
struct mlx5_sf_dev *sf_dev = container_of(adev, struct mlx5_sf_dev, adev);
Expand Down Expand Up @@ -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);
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);
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:
iounmap(mdev->iseg);
remap_err:
Expand Down
34 changes: 34 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ struct mlx5_sf_table {
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 *
Expand Down Expand Up @@ -511,6 +512,35 @@ static int mlx5_sf_esw_event(struct notifier_block *nb, unsigned long event, voi
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)
{
return dev->priv.eswitch && MLX5_ESWITCH_MANAGER(dev) &&
Expand Down Expand Up @@ -544,6 +574,9 @@ int mlx5_sf_table_init(struct mlx5_core_dev *dev)
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:
Expand All @@ -562,6 +595,7 @@ 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->priv.eswitch, &table->esw_nb);
WARN_ON(refcount_read(&table->refcount));
Expand Down
1 change: 1 addition & 0 deletions include/linux/mlx5/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ enum mlx5_driver_event {
MLX5_DRIVER_EVENT_UPLINK_NETDEV,
MLX5_DRIVER_EVENT_MACSEC_SA_ADDED,
MLX5_DRIVER_EVENT_MACSEC_SA_DELETED,
MLX5_DRIVER_EVENT_SF_PEER_DEVLINK,
};

enum {
Expand Down

0 comments on commit ac5f395

Please sign in to comment.