Skip to content

Commit

Permalink
net/mlx5: Add devlink flow_steering_mode parameter
Browse files Browse the repository at this point in the history
Add new parameter (flow_steering_mode) to control the flow steering
mode of the driver.
Two modes are supported:
1. DMFS - Device managed flow steering
2. SMFS - Software/Driver managed flow steering.

In the DMFS mode, the HW steering entities are created through the
FW. In the SMFS mode this entities are created though the driver
directly.

The driver will use the devlink steering mode only if the steering
domain supports it, for now SMFS will manages only the switchdev eswitch
steering domain.

User command examples:
- Set SMFS flow steering mode::

    $ devlink dev param set pci/0000:06:00.0 name flow_steering_mode value "smfs" cmode runtime

- Read device flow steering mode::

    $ devlink dev param show pci/0000:06:00.0 name flow_steering_mode
      pci/0000:06:00.0:
      name flow_steering_mode type driver-specific
      values:
         cmode runtime value smfs

Signed-off-by: Maor Gottlieb <[email protected]>
Signed-off-by: Saeed Mahameed <[email protected]>
  • Loading branch information
Maor Gottlieb authored and Saeed Mahameed committed Sep 3, 2019
1 parent 8463daf commit e890acd
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 1 deletion.
33 changes: 33 additions & 0 deletions Documentation/networking/device_drivers/mellanox/mlx5.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Contents

- `Enabling the driver and kconfig options`_
- `Devlink info`_
- `Devlink parameters`_
- `Devlink health reporters`_
- `mlx5 tracepoints`_

Expand Down Expand Up @@ -122,6 +123,38 @@ User command example::
stored:
fw.version 16.26.0100

Devlink parameters
==================

flow_steering_mode: Device flow steering mode
---------------------------------------------
The flow steering mode parameter controls the flow steering mode of the driver.
Two modes are supported:
1. 'dmfs' - Device managed flow steering.
2. 'smfs - Software/Driver managed flow steering.

In DMFS mode, the HW steering entities are created and managed through the
Firmware.
In SMFS mode, the HW steering entities are created and managed though by
the driver directly into Hardware without firmware intervention.

SMFS mode is faster and provides better rule inserstion rate compared to default DMFS mode.

User command examples:

- Set SMFS flow steering mode::

$ devlink dev param set pci/0000:06:00.0 name flow_steering_mode value "smfs" cmode runtime

- Read device flow steering mode::

$ devlink dev param show pci/0000:06:00.0 name flow_steering_mode
pci/0000:06:00.0:
name flow_steering_mode type driver-specific
values:
cmode runtime value smfs


Devlink health reporters
========================

Expand Down
112 changes: 111 additions & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <devlink.h>

#include "mlx5_core.h"
#include "fs_core.h"
#include "eswitch.h"

static int mlx5_devlink_flash_update(struct devlink *devlink,
Expand Down Expand Up @@ -107,12 +108,121 @@ void mlx5_devlink_free(struct devlink *devlink)
devlink_free(devlink);
}

static int mlx5_devlink_fs_mode_validate(struct devlink *devlink, u32 id,
union devlink_param_value val,
struct netlink_ext_ack *extack)
{
struct mlx5_core_dev *dev = devlink_priv(devlink);
char *value = val.vstr;
int err = 0;

if (!strcmp(value, "dmfs")) {
return 0;
} else if (!strcmp(value, "smfs")) {
u8 eswitch_mode;
bool smfs_cap;

eswitch_mode = mlx5_eswitch_mode(dev->priv.eswitch);
smfs_cap = mlx5_fs_dr_is_supported(dev);

if (!smfs_cap) {
err = -EOPNOTSUPP;
NL_SET_ERR_MSG_MOD(extack,
"Software managed steering is not supported by current device");
}

else if (eswitch_mode == MLX5_ESWITCH_OFFLOADS) {
NL_SET_ERR_MSG_MOD(extack,
"Software managed steering is not supported when eswitch offlaods enabled.");
err = -EOPNOTSUPP;
}
} else {
NL_SET_ERR_MSG_MOD(extack,
"Bad parameter: supported values are [\"dmfs\", \"smfs\"]");
err = -EINVAL;
}

return err;
}

static int mlx5_devlink_fs_mode_set(struct devlink *devlink, u32 id,
struct devlink_param_gset_ctx *ctx)
{
struct mlx5_core_dev *dev = devlink_priv(devlink);
enum mlx5_flow_steering_mode mode;

if (!strcmp(ctx->val.vstr, "smfs"))
mode = MLX5_FLOW_STEERING_MODE_SMFS;
else
mode = MLX5_FLOW_STEERING_MODE_DMFS;
dev->priv.steering->mode = mode;

return 0;
}

static int mlx5_devlink_fs_mode_get(struct devlink *devlink, u32 id,
struct devlink_param_gset_ctx *ctx)
{
struct mlx5_core_dev *dev = devlink_priv(devlink);

if (dev->priv.steering->mode == MLX5_FLOW_STEERING_MODE_SMFS)
strcpy(ctx->val.vstr, "smfs");
else
strcpy(ctx->val.vstr, "dmfs");
return 0;
}

enum mlx5_devlink_param_id {
MLX5_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
MLX5_DEVLINK_PARAM_FLOW_STEERING_MODE,
};

static const struct devlink_param mlx5_devlink_params[] = {
DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_FLOW_STEERING_MODE,
"flow_steering_mode", DEVLINK_PARAM_TYPE_STRING,
BIT(DEVLINK_PARAM_CMODE_RUNTIME),
mlx5_devlink_fs_mode_get, mlx5_devlink_fs_mode_set,
mlx5_devlink_fs_mode_validate),
};

static void mlx5_devlink_set_params_init_values(struct devlink *devlink)
{
struct mlx5_core_dev *dev = devlink_priv(devlink);
union devlink_param_value value;

if (dev->priv.steering->mode == MLX5_FLOW_STEERING_MODE_DMFS)
strcpy(value.vstr, "dmfs");
else
strcpy(value.vstr, "smfs");
devlink_param_driverinit_value_set(devlink,
MLX5_DEVLINK_PARAM_FLOW_STEERING_MODE,
value);
}

int mlx5_devlink_register(struct devlink *devlink, struct device *dev)
{
return devlink_register(devlink, dev);
int err;

err = devlink_register(devlink, dev);
if (err)
return err;

err = devlink_params_register(devlink, mlx5_devlink_params,
ARRAY_SIZE(mlx5_devlink_params));
if (err)
goto params_reg_err;
mlx5_devlink_set_params_init_values(devlink);
devlink_params_publish(devlink);
return 0;

params_reg_err:
devlink_unregister(devlink);
return err;
}

void mlx5_devlink_unregister(struct devlink *devlink)
{
devlink_params_unregister(devlink, mlx5_devlink_params,
ARRAY_SIZE(mlx5_devlink_params));
devlink_unregister(devlink);
}

0 comments on commit e890acd

Please sign in to comment.