net/mlx5: E-Switch, Implement devlink port function cmds to control migratable

Implement devlink port function commands to enable / disable migratable.
This is used to control the migratable capability of the device.

Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Acked-by: Saeed Mahameed <saeedm@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Shay Drory 2022-12-06 20:51:19 +02:00 committed by Jakub Kicinski
parent a8ce7b26a5
commit e5b9642a33
5 changed files with 124 additions and 0 deletions

View File

@ -364,6 +364,14 @@ PCI devices/SF.
mlx5 driver support devlink port function attr mechanism to setup RoCE
capability. (refer to Documentation/networking/devlink/devlink-port.rst)
migratable capability setup
---------------------------
User who wants mlx5 PCI VFs to be able to perform live migration need to
explicitly enable the VF migratable capability.
mlx5 driver support devlink port function attr mechanism to setup migratable
capability. (refer to Documentation/networking/devlink/devlink-port.rst)
SF state setup
--------------
To use the SF, the user must activate the SF using the SF function state

View File

@ -316,6 +316,8 @@ static const struct devlink_ops mlx5_devlink_ops = {
.rate_leaf_parent_set = mlx5_esw_devlink_rate_parent_set,
.port_fn_roce_get = mlx5_devlink_port_fn_roce_get,
.port_fn_roce_set = mlx5_devlink_port_fn_roce_set,
.port_fn_migratable_get = mlx5_devlink_port_fn_migratable_get,
.port_fn_migratable_set = mlx5_devlink_port_fn_migratable_set,
#endif
#ifdef CONFIG_MLX5_SF_MANAGER
.port_new = mlx5_devlink_sf_port_new,

View File

@ -794,6 +794,14 @@ static int mlx5_esw_vport_caps_get(struct mlx5_eswitch *esw, struct mlx5_vport *
hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability);
vport->info.roce_enabled = MLX5_GET(cmd_hca_cap, hca_caps, roce);
memset(query_ctx, 0, query_out_sz);
err = mlx5_vport_get_other_func_cap(esw->dev, vport->vport, query_ctx,
MLX5_CAP_GENERAL_2);
if (err)
goto out_free;
hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability);
vport->info.mig_enabled = MLX5_GET(cmd_hca_cap_2, hca_caps, migratable);
out_free:
kfree(query_ctx);
return err;

View File

@ -154,6 +154,7 @@ struct mlx5_vport_info {
u8 spoofchk: 1;
u8 trusted: 1;
u8 roce_enabled: 1;
u8 mig_enabled: 1;
};
/* Vport context events */
@ -513,6 +514,10 @@ int mlx5_devlink_port_fn_roce_get(struct devlink_port *port, bool *is_enabled,
struct netlink_ext_ack *extack);
int mlx5_devlink_port_fn_roce_set(struct devlink_port *port, bool enable,
struct netlink_ext_ack *extack);
int mlx5_devlink_port_fn_migratable_get(struct devlink_port *port, bool *is_enabled,
struct netlink_ext_ack *extack);
int mlx5_devlink_port_fn_migratable_set(struct devlink_port *port, bool enable,
struct netlink_ext_ack *extack);
void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw, u8 rep_type);
int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw,

View File

@ -4038,6 +4038,107 @@ mlx5_devlink_port_fn_get_vport(struct devlink_port *port, struct mlx5_eswitch *e
return mlx5_eswitch_get_vport(esw, vport_num);
}
int mlx5_devlink_port_fn_migratable_get(struct devlink_port *port, bool *is_enabled,
struct netlink_ext_ack *extack)
{
struct mlx5_eswitch *esw;
struct mlx5_vport *vport;
int err = -EOPNOTSUPP;
esw = mlx5_devlink_eswitch_get(port->devlink);
if (IS_ERR(esw))
return PTR_ERR(esw);
if (!MLX5_CAP_GEN(esw->dev, migration)) {
NL_SET_ERR_MSG_MOD(extack, "Device doesn't support migration");
return err;
}
vport = mlx5_devlink_port_fn_get_vport(port, esw);
if (IS_ERR(vport)) {
NL_SET_ERR_MSG_MOD(extack, "Invalid port");
return PTR_ERR(vport);
}
mutex_lock(&esw->state_lock);
if (vport->enabled) {
*is_enabled = vport->info.mig_enabled;
err = 0;
}
mutex_unlock(&esw->state_lock);
return err;
}
int mlx5_devlink_port_fn_migratable_set(struct devlink_port *port, bool enable,
struct netlink_ext_ack *extack)
{
int query_out_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out);
struct mlx5_eswitch *esw;
struct mlx5_vport *vport;
void *query_ctx;
void *hca_caps;
int err = -EOPNOTSUPP;
esw = mlx5_devlink_eswitch_get(port->devlink);
if (IS_ERR(esw))
return PTR_ERR(esw);
if (!MLX5_CAP_GEN(esw->dev, migration)) {
NL_SET_ERR_MSG_MOD(extack, "Device doesn't support migration");
return err;
}
vport = mlx5_devlink_port_fn_get_vport(port, esw);
if (IS_ERR(vport)) {
NL_SET_ERR_MSG_MOD(extack, "Invalid port");
return PTR_ERR(vport);
}
mutex_lock(&esw->state_lock);
if (!vport->enabled) {
NL_SET_ERR_MSG_MOD(extack, "Eswitch vport is disabled");
goto out;
}
if (vport->info.mig_enabled == enable) {
err = 0;
goto out;
}
query_ctx = kzalloc(query_out_sz, GFP_KERNEL);
if (!query_ctx) {
err = -ENOMEM;
goto out;
}
err = mlx5_vport_get_other_func_cap(esw->dev, vport->vport, query_ctx,
MLX5_CAP_GENERAL_2);
if (err) {
NL_SET_ERR_MSG_MOD(extack, "Failed getting HCA caps");
goto out_free;
}
hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability);
memcpy(hca_caps, MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability),
MLX5_UN_SZ_BYTES(hca_cap_union));
MLX5_SET(cmd_hca_cap_2, hca_caps, migratable, 1);
err = mlx5_vport_set_other_func_cap(esw->dev, hca_caps, vport->vport,
MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE2);
if (err) {
NL_SET_ERR_MSG_MOD(extack, "Failed setting HCA migratable cap");
goto out_free;
}
vport->info.mig_enabled = enable;
out_free:
kfree(query_ctx);
out:
mutex_unlock(&esw->state_lock);
return err;
}
int mlx5_devlink_port_fn_roce_get(struct devlink_port *port, bool *is_enabled,
struct netlink_ext_ack *extack)
{