Commit f9f54392 authored by Ido Schimmel's avatar Ido Schimmel Committed by David S. Miller

devlink: Add packet trap group parameters support

Packet trap groups are used to aggregate logically related packet traps.
Currently, these groups allow user space to batch operations such as
setting the trap action of all member traps.

In order to prevent the CPU from being overwhelmed by too many trapped
packets, it is desirable to bind a packet trap policer to these groups.
For example, to limit all the packets that encountered an exception
during routing to 10Kpps.

Allow device drivers to bind default packet trap policers to packet trap
groups when the latter are registered with devlink.

The next patch will enable user space to change this default binding.
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Reviewed-by: default avatarJiri Pirko <jiri@mellanox.com>
Reviewed-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ad188458
...@@ -166,10 +166,10 @@ static void mlxsw_sp_rx_exception_listener(struct sk_buff *skb, u8 local_port, ...@@ -166,10 +166,10 @@ static void mlxsw_sp_rx_exception_listener(struct sk_buff *skb, u8 local_port,
_action, false, SP_##_group_id, SET_FW_DEFAULT) _action, false, SP_##_group_id, SET_FW_DEFAULT)
static const struct devlink_trap_group mlxsw_sp_trap_groups_arr[] = { static const struct devlink_trap_group mlxsw_sp_trap_groups_arr[] = {
DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS), DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS, 0),
DEVLINK_TRAP_GROUP_GENERIC(L3_DROPS), DEVLINK_TRAP_GROUP_GENERIC(L3_DROPS, 0),
DEVLINK_TRAP_GROUP_GENERIC(TUNNEL_DROPS), DEVLINK_TRAP_GROUP_GENERIC(TUNNEL_DROPS, 0),
DEVLINK_TRAP_GROUP_GENERIC(ACL_DROPS), DEVLINK_TRAP_GROUP_GENERIC(ACL_DROPS, 0),
}; };
static const struct devlink_trap mlxsw_sp_traps_arr[] = { static const struct devlink_trap mlxsw_sp_traps_arr[] = {
......
...@@ -452,10 +452,10 @@ static const struct devlink_trap_policer nsim_trap_policers_arr[] = { ...@@ -452,10 +452,10 @@ static const struct devlink_trap_policer nsim_trap_policers_arr[] = {
}; };
static const struct devlink_trap_group nsim_trap_groups_arr[] = { static const struct devlink_trap_group nsim_trap_groups_arr[] = {
DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS), DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS, 0),
DEVLINK_TRAP_GROUP_GENERIC(L3_DROPS), DEVLINK_TRAP_GROUP_GENERIC(L3_DROPS, 1),
DEVLINK_TRAP_GROUP_GENERIC(BUFFER_DROPS), DEVLINK_TRAP_GROUP_GENERIC(BUFFER_DROPS, 2),
DEVLINK_TRAP_GROUP_GENERIC(ACL_DROPS), DEVLINK_TRAP_GROUP_GENERIC(ACL_DROPS, 3),
}; };
static const struct devlink_trap nsim_traps_arr[] = { static const struct devlink_trap nsim_traps_arr[] = {
......
...@@ -574,6 +574,7 @@ struct devlink_trap_policer { ...@@ -574,6 +574,7 @@ struct devlink_trap_policer {
* @name: Trap group name. * @name: Trap group name.
* @id: Trap group identifier. * @id: Trap group identifier.
* @generic: Whether the trap group is generic or not. * @generic: Whether the trap group is generic or not.
* @init_policer_id: Initial policer identifier.
* *
* Describes immutable attributes of packet trap groups that drivers register * Describes immutable attributes of packet trap groups that drivers register
* with devlink. * with devlink.
...@@ -582,6 +583,7 @@ struct devlink_trap_group { ...@@ -582,6 +583,7 @@ struct devlink_trap_group {
const char *name; const char *name;
u16 id; u16 id;
bool generic; bool generic;
u32 init_policer_id;
}; };
#define DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT BIT(0) #define DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT BIT(0)
...@@ -759,11 +761,12 @@ enum devlink_trap_group_generic_id { ...@@ -759,11 +761,12 @@ enum devlink_trap_group_generic_id {
.metadata_cap = _metadata_cap, \ .metadata_cap = _metadata_cap, \
} }
#define DEVLINK_TRAP_GROUP_GENERIC(_id) \ #define DEVLINK_TRAP_GROUP_GENERIC(_id, _policer_id) \
{ \ { \
.name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \ .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \
.id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \ .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \
.generic = true, \ .generic = true, \
.init_policer_id = _policer_id, \
} }
#define DEVLINK_TRAP_POLICER(_id, _rate, _burst, _max_rate, _min_rate, \ #define DEVLINK_TRAP_POLICER(_id, _rate, _burst, _max_rate, _min_rate, \
......
...@@ -5739,6 +5739,7 @@ struct devlink_trap_policer_item { ...@@ -5739,6 +5739,7 @@ struct devlink_trap_policer_item {
/** /**
* struct devlink_trap_group_item - Packet trap group attributes. * struct devlink_trap_group_item - Packet trap group attributes.
* @group: Immutable packet trap group attributes. * @group: Immutable packet trap group attributes.
* @policer_item: Associated policer item. Can be NULL.
* @list: trap_group_list member. * @list: trap_group_list member.
* @stats: Trap group statistics. * @stats: Trap group statistics.
* *
...@@ -5747,6 +5748,7 @@ struct devlink_trap_policer_item { ...@@ -5747,6 +5748,7 @@ struct devlink_trap_policer_item {
*/ */
struct devlink_trap_group_item { struct devlink_trap_group_item {
const struct devlink_trap_group *group; const struct devlink_trap_group *group;
struct devlink_trap_policer_item *policer_item;
struct list_head list; struct list_head list;
struct devlink_stats __percpu *stats; struct devlink_stats __percpu *stats;
}; };
...@@ -6161,6 +6163,11 @@ devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink, ...@@ -6161,6 +6163,11 @@ devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink,
nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC)) nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
goto nla_put_failure; goto nla_put_failure;
if (group_item->policer_item &&
nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
group_item->policer_item->policer->id))
goto nla_put_failure;
err = devlink_trap_stats_put(msg, group_item->stats); err = devlink_trap_stats_put(msg, group_item->stats);
if (err) if (err)
goto nla_put_failure; goto nla_put_failure;
...@@ -8759,6 +8766,25 @@ void *devlink_trap_ctx_priv(void *trap_ctx) ...@@ -8759,6 +8766,25 @@ void *devlink_trap_ctx_priv(void *trap_ctx)
} }
EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv); EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv);
static int
devlink_trap_group_item_policer_link(struct devlink *devlink,
struct devlink_trap_group_item *group_item)
{
u32 policer_id = group_item->group->init_policer_id;
struct devlink_trap_policer_item *policer_item;
if (policer_id == 0)
return 0;
policer_item = devlink_trap_policer_item_lookup(devlink, policer_id);
if (WARN_ON_ONCE(!policer_item))
return -EINVAL;
group_item->policer_item = policer_item;
return 0;
}
static int static int
devlink_trap_group_register(struct devlink *devlink, devlink_trap_group_register(struct devlink *devlink,
const struct devlink_trap_group *group) const struct devlink_trap_group *group)
...@@ -8781,6 +8807,10 @@ devlink_trap_group_register(struct devlink *devlink, ...@@ -8781,6 +8807,10 @@ devlink_trap_group_register(struct devlink *devlink,
group_item->group = group; group_item->group = group;
err = devlink_trap_group_item_policer_link(devlink, group_item);
if (err)
goto err_policer_link;
if (devlink->ops->trap_group_init) { if (devlink->ops->trap_group_init) {
err = devlink->ops->trap_group_init(devlink, group); err = devlink->ops->trap_group_init(devlink, group);
if (err) if (err)
...@@ -8794,6 +8824,7 @@ devlink_trap_group_register(struct devlink *devlink, ...@@ -8794,6 +8824,7 @@ devlink_trap_group_register(struct devlink *devlink,
return 0; return 0;
err_group_init: err_group_init:
err_policer_link:
free_percpu(group_item->stats); free_percpu(group_item->stats);
err_stats_alloc: err_stats_alloc:
kfree(group_item); kfree(group_item);
......
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