Commit 3d347b1b authored by Aya Levin's avatar Aya Levin Committed by Jakub Kicinski

net/mlx5: Add support for devlink traps in mlx5 core driver

Add devlink traps infra-structure to mlx5 core driver. Add traps list to
mlx5_priv and corresponding API:
 - mlx5_devlink_trap_report() to wrap trap reports to devlink
 - mlx5_devlink_trap_get_num_active() to decide whether to open/close trap
   resources.
Signed-off-by: default avatarAya Levin <ayal@nvidia.com>
Reviewed-by: default avatarTariq Toukan <tariqt@nvidia.com>
Signed-off-by: default avatarTariq Toukan <tariqt@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent e78ab164
...@@ -168,6 +168,56 @@ static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_a ...@@ -168,6 +168,56 @@ static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_a
return 0; return 0;
} }
static struct mlx5_devlink_trap *mlx5_find_trap_by_id(struct mlx5_core_dev *dev, int trap_id)
{
struct mlx5_devlink_trap *dl_trap;
list_for_each_entry(dl_trap, &dev->priv.traps, list)
if (dl_trap->trap.id == trap_id)
return dl_trap;
return NULL;
}
static int mlx5_devlink_trap_init(struct devlink *devlink, const struct devlink_trap *trap,
void *trap_ctx)
{
struct mlx5_core_dev *dev = devlink_priv(devlink);
struct mlx5_devlink_trap *dl_trap;
dl_trap = kzalloc(sizeof(*dl_trap), GFP_KERNEL);
if (!dl_trap)
return -ENOMEM;
dl_trap->trap.id = trap->id;
dl_trap->trap.action = DEVLINK_TRAP_ACTION_DROP;
dl_trap->item = trap_ctx;
if (mlx5_find_trap_by_id(dev, trap->id)) {
kfree(dl_trap);
mlx5_core_err(dev, "Devlink trap: Trap 0x%x already found", trap->id);
return -EEXIST;
}
list_add_tail(&dl_trap->list, &dev->priv.traps);
return 0;
}
static void mlx5_devlink_trap_fini(struct devlink *devlink, const struct devlink_trap *trap,
void *trap_ctx)
{
struct mlx5_core_dev *dev = devlink_priv(devlink);
struct mlx5_devlink_trap *dl_trap;
dl_trap = mlx5_find_trap_by_id(dev, trap->id);
if (!dl_trap) {
mlx5_core_err(dev, "Devlink trap: Missing trap id 0x%x", trap->id);
return;
}
list_del(&dl_trap->list);
kfree(dl_trap);
}
static const struct devlink_ops mlx5_devlink_ops = { static const struct devlink_ops mlx5_devlink_ops = {
#ifdef CONFIG_MLX5_ESWITCH #ifdef CONFIG_MLX5_ESWITCH
.eswitch_mode_set = mlx5_devlink_eswitch_mode_set, .eswitch_mode_set = mlx5_devlink_eswitch_mode_set,
...@@ -186,8 +236,42 @@ static const struct devlink_ops mlx5_devlink_ops = { ...@@ -186,8 +236,42 @@ static const struct devlink_ops mlx5_devlink_ops = {
.reload_limits = BIT(DEVLINK_RELOAD_LIMIT_NO_RESET), .reload_limits = BIT(DEVLINK_RELOAD_LIMIT_NO_RESET),
.reload_down = mlx5_devlink_reload_down, .reload_down = mlx5_devlink_reload_down,
.reload_up = mlx5_devlink_reload_up, .reload_up = mlx5_devlink_reload_up,
.trap_init = mlx5_devlink_trap_init,
.trap_fini = mlx5_devlink_trap_fini,
}; };
void mlx5_devlink_trap_report(struct mlx5_core_dev *dev, int trap_id, struct sk_buff *skb,
struct devlink_port *dl_port)
{
struct devlink *devlink = priv_to_devlink(dev);
struct mlx5_devlink_trap *dl_trap;
dl_trap = mlx5_find_trap_by_id(dev, trap_id);
if (!dl_trap) {
mlx5_core_err(dev, "Devlink trap: Report on invalid trap id 0x%x", trap_id);
return;
}
if (dl_trap->trap.action != DEVLINK_TRAP_ACTION_TRAP) {
mlx5_core_dbg(dev, "Devlink trap: Trap id %d has action %d", trap_id,
dl_trap->trap.action);
return;
}
devlink_trap_report(devlink, skb, dl_trap->item, dl_port, NULL);
}
int mlx5_devlink_trap_get_num_active(struct mlx5_core_dev *dev)
{
struct mlx5_devlink_trap *dl_trap;
int count = 0;
list_for_each_entry(dl_trap, &dev->priv.traps, list)
if (dl_trap->trap.action == DEVLINK_TRAP_ACTION_TRAP)
count++;
return count;
}
struct devlink *mlx5_devlink_alloc(void) struct devlink *mlx5_devlink_alloc(void)
{ {
return devlink_alloc(&mlx5_devlink_ops, sizeof(struct mlx5_core_dev)); return devlink_alloc(&mlx5_devlink_ops, sizeof(struct mlx5_core_dev));
......
...@@ -12,6 +12,22 @@ enum mlx5_devlink_param_id { ...@@ -12,6 +12,22 @@ enum mlx5_devlink_param_id {
MLX5_DEVLINK_PARAM_ID_ESW_LARGE_GROUP_NUM, MLX5_DEVLINK_PARAM_ID_ESW_LARGE_GROUP_NUM,
}; };
struct mlx5_trap_ctx {
int id;
int action;
};
struct mlx5_devlink_trap {
struct mlx5_trap_ctx trap;
void *item;
struct list_head list;
};
struct mlx5_core_dev;
void mlx5_devlink_trap_report(struct mlx5_core_dev *dev, int trap_id, struct sk_buff *skb,
struct devlink_port *dl_port);
int mlx5_devlink_trap_get_num_active(struct mlx5_core_dev *dev);
struct devlink *mlx5_devlink_alloc(void); struct devlink *mlx5_devlink_alloc(void);
void mlx5_devlink_free(struct devlink *devlink); void mlx5_devlink_free(struct devlink *devlink);
int mlx5_devlink_register(struct devlink *devlink, struct device *dev); int mlx5_devlink_register(struct devlink *devlink, struct device *dev);
......
...@@ -1305,6 +1305,8 @@ static int mlx5_mdev_init(struct mlx5_core_dev *dev, int profile_idx) ...@@ -1305,6 +1305,8 @@ static int mlx5_mdev_init(struct mlx5_core_dev *dev, int profile_idx)
priv->dbg_root = debugfs_create_dir(dev_name(dev->device), priv->dbg_root = debugfs_create_dir(dev_name(dev->device),
mlx5_debugfs_root); mlx5_debugfs_root);
INIT_LIST_HEAD(&priv->traps);
err = mlx5_health_init(dev); err = mlx5_health_init(dev);
if (err) if (err)
goto err_health_init; goto err_health_init;
......
...@@ -564,6 +564,7 @@ struct mlx5_priv { ...@@ -564,6 +564,7 @@ struct mlx5_priv {
int host_pf_pages; int host_pf_pages;
struct mlx5_core_health health; struct mlx5_core_health health;
struct list_head traps;
/* start: qp staff */ /* start: qp staff */
struct dentry *qp_debugfs; struct dentry *qp_debugfs;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment