mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-27 23:25:13 -04:00
net/mlx5: implement max_sfs parameter
Implement max_sfs generic parameter to allow users to control the total light-weight NIC subfunctions that can be created using devlink instead of external vendor tools. A value of 0 will effectively disable creation of new subfunction devices. A warning is sent to user-space via extack (returning extack without error code is interpreted as a warning by user-space tools). The maximum value is capped at U16_MAX. Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com> Reviewed-by: David Ahern <dsahern@kernel.org> Reviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com> Signed-off-by: Tariq Toukan <tariqt@nvidia.com> Link: https://patch.msgid.link/20260806073037.3001886-3-tariqt@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
26ba30221c
commit
38c35fdd80
@@ -45,8 +45,13 @@ Parameters
|
||||
- The range is between 1 and a device-specific max.
|
||||
- Applies to each physical function (PF) independently, if the device
|
||||
supports it. Otherwise, it applies symmetrically to all PFs.
|
||||
* - ``max_sfs``
|
||||
- permanent
|
||||
- The range is between 0 and a device-specific max.
|
||||
- Applies to each physical function (PF) independently.
|
||||
|
||||
Note: permanent parameters such as ``enable_sriov`` and ``total_vfs`` require FW reset to take effect
|
||||
Note: permanent parameters such as ``enable_sriov``, ``total_vfs`` and ``max_sfs``
|
||||
require FW reset to take effect
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
|
||||
@@ -68,7 +68,9 @@ struct mlx5_ifc_mnvda_reg_bits {
|
||||
|
||||
struct mlx5_ifc_nv_global_pci_conf_bits {
|
||||
u8 sriov_valid[0x1];
|
||||
u8 reserved_at_1[0x10];
|
||||
u8 reserved_at_1[0xa];
|
||||
u8 per_pf_num_sf[0x1];
|
||||
u8 reserved_at_c[0x5];
|
||||
u8 per_pf_total_vf[0x1];
|
||||
u8 reserved_at_12[0xe];
|
||||
|
||||
@@ -93,9 +95,11 @@ struct mlx5_ifc_nv_global_pci_cap_bits {
|
||||
};
|
||||
|
||||
struct mlx5_ifc_nv_pf_pci_conf_bits {
|
||||
u8 reserved_at_0[0x9];
|
||||
u8 log_sf_bar_size[0x8];
|
||||
u8 pf_total_sf_en[0x1];
|
||||
u8 pf_total_vf_en[0x1];
|
||||
u8 reserved_at_a[0x16];
|
||||
u8 reserved_at_a[0x6];
|
||||
u8 total_sf[0x10];
|
||||
|
||||
u8 reserved_at_20[0x20];
|
||||
|
||||
@@ -158,6 +162,8 @@ struct mlx5_ifc_nv_sw_accelerate_conf_bits {
|
||||
#define MLX5_GET_CFG_HDR_LEN(_mnvda_ptr) \
|
||||
MLX5_GET(mnvda_reg, _mnvda_ptr, configuration_item_header.length)
|
||||
|
||||
#define MLX5_DEFAULT_LOG_SF_BAR_SIZE 12
|
||||
|
||||
static int mlx5_nv_param_read(struct mlx5_core_dev *dev, void *mnvda,
|
||||
size_t len)
|
||||
{
|
||||
@@ -755,6 +761,115 @@ static int mlx5_devlink_total_vfs_validate(struct devlink *devlink, u32 id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mlx5_devlink_max_sfs_get(struct devlink *devlink, u32 id,
|
||||
struct devlink_param_gset_ctx *ctx,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct mlx5_core_dev *dev = devlink_priv(devlink);
|
||||
u32 mnvda[MLX5_ST_SZ_DW(mnvda_reg)] = {};
|
||||
void *data;
|
||||
int err;
|
||||
|
||||
err = mlx5_nv_param_read_global_pci_conf(dev, mnvda, sizeof(mnvda));
|
||||
if (err) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Failed to read global PCI configuration");
|
||||
return err;
|
||||
}
|
||||
|
||||
data = MLX5_ADDR_OF(mnvda_reg, mnvda, configuration_item_data);
|
||||
if (!MLX5_GET(nv_global_pci_conf, data, per_pf_num_sf)) {
|
||||
ctx->val.vu32 = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(mnvda, 0, sizeof(mnvda));
|
||||
err = mlx5_nv_param_read_per_host_pf_conf(dev, mnvda, sizeof(mnvda));
|
||||
if (err) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Failed to read PF configuration");
|
||||
return err;
|
||||
}
|
||||
|
||||
data = MLX5_ADDR_OF(mnvda_reg, mnvda, configuration_item_data);
|
||||
if (MLX5_GET(nv_pf_pci_conf, data, pf_total_sf_en))
|
||||
ctx->val.vu32 = MLX5_GET(nv_pf_pci_conf, data, total_sf);
|
||||
else
|
||||
ctx->val.vu32 = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mlx5_devlink_max_sfs_validate(struct devlink *devlink, u32 id,
|
||||
union devlink_param_value *val,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
if (val->vu32 > U16_MAX) {
|
||||
NL_SET_ERR_MSG_FMT_MOD(extack,
|
||||
"Max SFs allowed value is %u", U16_MAX);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mlx5_devlink_max_sfs_set(struct devlink *devlink, u32 id,
|
||||
struct devlink_param_gset_ctx *ctx,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct mlx5_core_dev *dev = devlink_priv(devlink);
|
||||
u32 mnvda[MLX5_ST_SZ_DW(mnvda_reg)] = {};
|
||||
void *data;
|
||||
int err;
|
||||
|
||||
/* we don't explicitly disable per_pf_num_sf when max_sfs is 0 because
|
||||
* another PF may be using SFs
|
||||
*/
|
||||
if (ctx->val.vu32) {
|
||||
err = mlx5_nv_param_read_global_pci_conf(dev, mnvda,
|
||||
sizeof(mnvda));
|
||||
if (err) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Failed to read global PCI configuration");
|
||||
return err;
|
||||
}
|
||||
|
||||
data = MLX5_ADDR_OF(mnvda_reg, mnvda, configuration_item_data);
|
||||
/* always enable per_pf_num_sf because another PF may use SFs */
|
||||
MLX5_SET(nv_global_pci_conf, data, per_pf_num_sf, 1);
|
||||
|
||||
err = mlx5_nv_param_write(dev, mnvda, sizeof(mnvda));
|
||||
if (err) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Failed to change per_pf_num_sf global PCI configuration");
|
||||
return err;
|
||||
}
|
||||
memset(mnvda, 0, sizeof(mnvda));
|
||||
}
|
||||
|
||||
err = mlx5_nv_param_read_per_host_pf_conf(dev, mnvda, sizeof(mnvda));
|
||||
if (err) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Failed to read PF configuration");
|
||||
return err;
|
||||
}
|
||||
|
||||
data = MLX5_ADDR_OF(mnvda_reg, mnvda, configuration_item_data);
|
||||
MLX5_SET(nv_pf_pci_conf, data, log_sf_bar_size,
|
||||
ctx->val.vu32 ? MLX5_DEFAULT_LOG_SF_BAR_SIZE : 0);
|
||||
MLX5_SET(nv_pf_pci_conf, data, pf_total_sf_en, !!ctx->val.vu32);
|
||||
MLX5_SET(nv_pf_pci_conf, data, total_sf, ctx->val.vu32);
|
||||
|
||||
err = mlx5_nv_param_write(dev, mnvda, sizeof(mnvda));
|
||||
if (err) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Failed to change PF PCI configuration");
|
||||
return err;
|
||||
}
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Modifying max_sfs requires a FW reset and PCI bus rescan");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct devlink_param mlx5_nv_param_devlink_params[] = {
|
||||
DEVLINK_PARAM_GENERIC(ENABLE_SRIOV, BIT(DEVLINK_PARAM_CMODE_PERMANENT),
|
||||
mlx5_devlink_enable_sriov_get,
|
||||
@@ -763,6 +878,10 @@ static const struct devlink_param mlx5_nv_param_devlink_params[] = {
|
||||
mlx5_devlink_total_vfs_get,
|
||||
mlx5_devlink_total_vfs_set,
|
||||
mlx5_devlink_total_vfs_validate),
|
||||
DEVLINK_PARAM_GENERIC(MAX_SFS, BIT(DEVLINK_PARAM_CMODE_PERMANENT),
|
||||
mlx5_devlink_max_sfs_get,
|
||||
mlx5_devlink_max_sfs_set,
|
||||
mlx5_devlink_max_sfs_validate),
|
||||
DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_CQE_COMPRESSION_TYPE,
|
||||
"cqe_compress_type", DEVLINK_PARAM_TYPE_STRING,
|
||||
BIT(DEVLINK_PARAM_CMODE_PERMANENT),
|
||||
|
||||
Reference in New Issue
Block a user