Skip to content

Commit

Permalink
Merge branch 'devlink-instances-relationships'
Browse files Browse the repository at this point in the history
Jiri Pirko says:

====================
expose devlink instances relationships

From: Jiri Pirko <jiri@nvidia.com>

Currently, the user can instantiate new SF using "devlink port add"
command. That creates an E-switch representor devlink port.

When user activates this SF, there is an auxiliary device created and
probed for it which leads to SF devlink instance creation.

There is 1:1 relationship between E-switch representor devlink port and
the SF auxiliary device devlink instance.

Also, for example in mlx5, one devlink instance is created for
PCI device and one is created for an auxiliary device that represents
the uplink port. The relation between these is invisible to the user.

Patches #1-#3 and #5 are small preparations.

Patch #4 adds netnsid attribute for nested devlink if that in a
different namespace.

Patch #5 is the main one in this set, introduces the relationship
tracking infrastructure later on used to track SFs, linecards and
devlink instance relationships with nested devlink instances.

Expose the relation to the user by introducing new netlink attribute
DEVLINK_PORT_FN_ATTR_DEVLINK which contains the devlink instance related
to devlink port function. This is done by patch #8.
Patch #9 implements this in mlx5 driver.

Patch #10 converts the linecard nested devlink handling to the newly
introduced rel infrastructure.

Patch #11 benefits from the rel infra and introduces possiblitily to
have relation between devlink instances.
Patch #12 implements this in mlx5 driver.

Examples:
$ devlink dev
pci/0000:08:00.0: nested_devlink auxiliary/mlx5_core.eth.0
pci/0000:08:00.1: nested_devlink auxiliary/mlx5_core.eth.1
auxiliary/mlx5_core.eth.1
auxiliary/mlx5_core.eth.0

$ devlink port add pci/0000:08:00.0 flavour pcisf pfnum 0 sfnum 106
pci/0000:08:00.0/32768: type eth netdev eth4 flavour pcisf controller 0 pfnum 0 sfnum 106 splittable false
  function:
    hw_addr 00:00:00:00:00:00 state inactive opstate detached roce enable
$ devlink port function set pci/0000:08:00.0/32768 state active
$ devlink port show pci/0000:08:00.0/32768
pci/0000:08:00.0/32768: type eth netdev eth4 flavour pcisf controller 0 pfnum 0 sfnum 106 splittable false
  function:
    hw_addr 00:00:00:00:00:00 state active opstate attached roce enable nested_devlink auxiliary/mlx5_core.sf.2

$ devlink port show pci/0000:08:00.0/32768
pci/0000:08:00.0/32768: type eth netdev eth4 flavour pcisf controller 0 pfnum 0 sfnum 106 splittable false
  function:
    hw_addr 00:00:00:00:00:00 state active opstate attached roce enable nested_devlink auxiliary/mlx5_core.sf.2 nested_devlink_netns ns1
====================

Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
davem330 committed Sep 17, 2023
2 parents 1e73cfe + 6c75258 commit e03f0df
Show file tree
Hide file tree
Showing 16 changed files with 509 additions and 60 deletions.
11 changes: 0 additions & 11 deletions drivers/net/ethernet/mellanox/mlx5/core/devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
{
struct mlx5_core_dev *dev = devlink_priv(devlink);
struct pci_dev *pdev = dev->pdev;
bool sf_dev_allocated;
int ret = 0;

if (mlx5_dev_is_lightweight(dev)) {
Expand All @@ -148,16 +147,6 @@ static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
return 0;
}

sf_dev_allocated = mlx5_sf_dev_allocated(dev);
if (sf_dev_allocated) {
/* Reload results in deleting SF device which further results in
* unregistering devlink instance while holding devlink_mutext.
* Hence, do not support reload.
*/
NL_SET_ERR_MSG_MOD(extack, "reload is unsupported when SFs are allocated");
return -EOPNOTSUPP;
}

if (mlx5_lag_is_active(dev)) {
NL_SET_ERR_MSG_MOD(extack, "reload is unsupported in Lag mode");
return -EOPNOTSUPP;
Expand Down
8 changes: 8 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,19 @@ struct mlx5e_dev *mlx5e_create_devlink(struct device *dev,
{
struct mlx5e_dev *mlx5e_dev;
struct devlink *devlink;
int err;

devlink = devlink_alloc_ns(&mlx5e_devlink_ops, sizeof(*mlx5e_dev),
devlink_net(priv_to_devlink(mdev)), dev);
if (!devlink)
return ERR_PTR(-ENOMEM);

err = devl_nested_devlink_set(priv_to_devlink(mdev), devlink);
if (err) {
devlink_free(devlink);
return ERR_PTR(err);
}

devlink_register(devlink);
return devlink_priv(devlink);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1405,9 +1405,9 @@ static int mlx5_load(struct mlx5_core_dev *dev)

static void mlx5_unload(struct mlx5_core_dev *dev)
{
mlx5_eswitch_disable(dev->priv.eswitch);
mlx5_devlink_traps_unregister(priv_to_devlink(dev));
mlx5_sf_dev_table_destroy(dev);
mlx5_eswitch_disable(dev->priv.eswitch);
mlx5_sriov_detach(dev);
mlx5_lag_remove_mdev(dev);
mlx5_ec_cleanup(dev);
Expand Down
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
9 changes: 6 additions & 3 deletions drivers/net/ethernet/mellanox/mlxsw/core_linecard_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ static int mlxsw_linecard_bdev_probe(struct auxiliary_device *adev,
struct mlxsw_linecard *linecard = linecard_bdev->linecard;
struct mlxsw_linecard_dev *linecard_dev;
struct devlink *devlink;
int err;

devlink = devlink_alloc(&mlxsw_linecard_dev_devlink_ops,
sizeof(*linecard_dev), &adev->dev);
Expand All @@ -141,8 +142,12 @@ static int mlxsw_linecard_bdev_probe(struct auxiliary_device *adev,
linecard_dev->linecard = linecard_bdev->linecard;
linecard_bdev->linecard_dev = linecard_dev;

err = devlink_linecard_nested_dl_set(linecard->devlink_linecard, devlink);
if (err) {
devlink_free(devlink);
return err;
}
devlink_register(devlink);
devlink_linecard_nested_dl_set(linecard->devlink_linecard, devlink);
return 0;
}

Expand All @@ -151,9 +156,7 @@ static void mlxsw_linecard_bdev_remove(struct auxiliary_device *adev)
struct mlxsw_linecard_bdev *linecard_bdev =
container_of(adev, struct mlxsw_linecard_bdev, adev);
struct devlink *devlink = priv_to_devlink(linecard_bdev->linecard_dev);
struct mlxsw_linecard *linecard = linecard_bdev->linecard;

devlink_linecard_nested_dl_set(linecard->devlink_linecard, NULL);
devlink_unregister(devlink);
devlink_free(devlink);
}
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
9 changes: 7 additions & 2 deletions include/net/devlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ struct devlink_port {

struct devlink_rate *devlink_rate;
struct devlink_linecard *linecard;
u32 rel_index;
};

struct devlink_port_new_attrs {
Expand Down Expand Up @@ -1697,6 +1698,8 @@ void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 contro
void devlink_port_attrs_pci_sf_set(struct devlink_port *devlink_port,
u32 controller, u16 pf, u32 sf,
bool external);
int devl_port_fn_devlink_set(struct devlink_port *devlink_port,
struct devlink *fn_devlink);
struct devlink_rate *
devl_rate_node_create(struct devlink *devlink, void *priv, char *node_name,
struct devlink_rate *parent);
Expand All @@ -1717,8 +1720,8 @@ void devlink_linecard_provision_clear(struct devlink_linecard *linecard);
void devlink_linecard_provision_fail(struct devlink_linecard *linecard);
void devlink_linecard_activate(struct devlink_linecard *linecard);
void devlink_linecard_deactivate(struct devlink_linecard *linecard);
void devlink_linecard_nested_dl_set(struct devlink_linecard *linecard,
struct devlink *nested_devlink);
int devlink_linecard_nested_dl_set(struct devlink_linecard *linecard,
struct devlink *nested_devlink);
int devl_sb_register(struct devlink *devlink, unsigned int sb_index,
u32 size, u16 ingress_pools_count,
u16 egress_pools_count, u16 ingress_tc_count,
Expand Down Expand Up @@ -1918,6 +1921,8 @@ devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
void
devlink_health_reporter_recovery_done(struct devlink_health_reporter *reporter);

int devl_nested_devlink_set(struct devlink *devlink,
struct devlink *nested_devlink);
bool devlink_is_reload_failed(const struct devlink *devlink);
void devlink_remote_reload_actions_performed(struct devlink *devlink,
enum devlink_reload_limit limit,
Expand Down
1 change: 1 addition & 0 deletions include/uapi/linux/devlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,7 @@ enum devlink_port_function_attr {
DEVLINK_PORT_FN_ATTR_STATE, /* u8 */
DEVLINK_PORT_FN_ATTR_OPSTATE, /* u8 */
DEVLINK_PORT_FN_ATTR_CAPS, /* bitfield32 */
DEVLINK_PORT_FN_ATTR_DEVLINK, /* nested */

__DEVLINK_PORT_FUNCTION_ATTR_MAX,
DEVLINK_PORT_FUNCTION_ATTR_MAX = __DEVLINK_PORT_FUNCTION_ATTR_MAX - 1
Expand Down
Loading

0 comments on commit e03f0df

Please sign in to comment.