mlxsw: spectrum_trap: Add early_drop trap

As previously explained, packets that are dropped due to buffer related
reasons (e.g., tail drop, early drop) can be mirrored to the CPU port.
These packets are then trapped with one of the "mirror session" traps
and their CQE includes the reason for which the packet was mirrored.

Register with devlink a new trap, early_drop, and initialize the
corresponding Rx listener with the appropriate mirror reason. Return an
error in case user tries to change the traps' action, as this is not
supported.

Since Spectrum-1 does not support these traps, the above is only done
for Spectrum-2 onwards.

Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Ido Schimmel 2020-08-03 19:11:39 +03:00 committed by David S. Miller
parent 869c7be940
commit 6687e953f4
3 changed files with 53 additions and 3 deletions

View file

@ -89,13 +89,15 @@ struct mlxsw_listener {
};
#define __MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _en_trap_group, \
_dis_action, _enabled_on_register, _dis_trap_group) \
_dis_action, _enabled_on_register, _dis_trap_group, \
_mirror_reason) \
{ \
.trap_id = MLXSW_TRAP_ID_##_trap_id, \
.rx_listener = \
{ \
.func = _func, \
.local_port = MLXSW_PORT_DONT_CARE, \
.mirror_reason = _mirror_reason, \
.trap_id = MLXSW_TRAP_ID_##_trap_id, \
}, \
.en_action = MLXSW_REG_HPKT_ACTION_##_en_action, \
@ -109,12 +111,17 @@ struct mlxsw_listener {
#define MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _trap_group, \
_dis_action) \
__MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _trap_group, \
_dis_action, true, _trap_group)
_dis_action, true, _trap_group, 0)
#define MLXSW_RXL_DIS(_func, _trap_id, _en_action, _is_ctrl, _en_trap_group, \
_dis_action, _dis_trap_group) \
__MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _en_trap_group, \
_dis_action, false, _dis_trap_group)
_dis_action, false, _dis_trap_group, 0)
#define MLXSW_RXL_MIRROR(_func, _session_id, _trap_group, _mirror_reason) \
__MLXSW_RXL(_func, MIRROR_SESSION##_session_id, TRAP_TO_CPU, false, \
_trap_group, TRAP_TO_CPU, true, _trap_group, \
_mirror_reason)
#define MLXSW_EVENTL(_func, _trap_id, _trap_group) \
{ \

View file

@ -5614,6 +5614,7 @@ enum mlxsw_reg_htgt_trap_group {
MLXSW_REG_HTGT_TRAP_GROUP_SP_L3_EXCEPTIONS,
MLXSW_REG_HTGT_TRAP_GROUP_SP_TUNNEL_DISCARDS,
MLXSW_REG_HTGT_TRAP_GROUP_SP_ACL_DISCARDS,
MLXSW_REG_HTGT_TRAP_GROUP_SP_BUFFER_DISCARDS,
__MLXSW_REG_HTGT_TRAP_GROUP_MAX,
MLXSW_REG_HTGT_TRAP_GROUP_MAX = __MLXSW_REG_HTGT_TRAP_GROUP_MAX - 1

View file

@ -21,6 +21,7 @@ struct mlxsw_sp_trap_group_item {
struct devlink_trap_group group;
u16 hw_group_id;
u8 priority;
u8 fixed_policer:1; /* Whether policer binding can change */
};
#define MLXSW_SP_TRAP_LISTENERS_MAX 3
@ -28,6 +29,7 @@ struct mlxsw_sp_trap_group_item {
struct mlxsw_sp_trap_item {
struct devlink_trap trap;
struct mlxsw_listener listeners_arr[MLXSW_SP_TRAP_LISTENERS_MAX];
u8 is_source:1;
};
/* All driver-specific traps must be documented in
@ -46,6 +48,11 @@ enum {
#define MLXSW_SP_TRAP_METADATA DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT
enum {
/* Packet was early dropped. */
MLXSW_SP_MIRROR_REASON_INGRESS_WRED = 9,
};
static int mlxsw_sp_rx_listener(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
u8 local_port,
struct mlxsw_sp_port *mlxsw_sp_port)
@ -222,6 +229,11 @@ static void mlxsw_sp_rx_sample_listener(struct sk_buff *skb, u8 local_port,
DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
MLXSW_SP_TRAP_METADATA | (_metadata))
#define MLXSW_SP_TRAP_BUFFER_DROP(_id) \
DEVLINK_TRAP_GENERIC(DROP, TRAP, _id, \
DEVLINK_TRAP_GROUP_GENERIC_ID_BUFFER_DROPS, \
MLXSW_SP_TRAP_METADATA)
#define MLXSW_SP_TRAP_DRIVER_DROP(_id, _group_id) \
DEVLINK_TRAP_DRIVER(DROP, DROP, DEVLINK_MLXSW_TRAP_ID_##_id, \
DEVLINK_MLXSW_TRAP_NAME_##_id, \
@ -248,6 +260,10 @@ static void mlxsw_sp_rx_sample_listener(struct sk_buff *skb, u8 local_port,
TRAP_EXCEPTION_TO_CPU, false, SP_##_en_group_id, \
SET_FW_DEFAULT, SP_##_dis_group_id)
#define MLXSW_SP_RXL_BUFFER_DISCARD(_mirror_reason) \
MLXSW_RXL_MIRROR(mlxsw_sp_rx_drop_listener, 0, SP_BUFFER_DISCARDS, \
MLXSW_SP_MIRROR_REASON_##_mirror_reason)
#define MLXSW_SP_RXL_EXCEPTION(_id, _group_id, _action) \
MLXSW_RXL(mlxsw_sp_rx_mark_listener, _id, \
_action, false, SP_##_group_id, SET_FW_DEFAULT)
@ -331,6 +347,9 @@ mlxsw_sp_trap_policer_items_arr[] = {
{
.policer = MLXSW_SP_TRAP_POLICER(19, 1024, 512),
},
{
.policer = MLXSW_SP_TRAP_POLICER(20, 10240, 4096),
},
};
static const struct mlxsw_sp_trap_group_item mlxsw_sp_trap_group_items_arr[] = {
@ -1429,6 +1448,11 @@ int mlxsw_sp_trap_action_set(struct mlxsw_core *mlxsw_core,
if (WARN_ON(!trap_item))
return -EINVAL;
if (trap_item->is_source) {
NL_SET_ERR_MSG_MOD(extack, "Changing the action of source traps is not supported");
return -EOPNOTSUPP;
}
for (i = 0; i < MLXSW_SP_TRAP_LISTENERS_MAX; i++) {
const struct mlxsw_listener *listener;
bool enabled;
@ -1470,6 +1494,11 @@ __mlxsw_sp_trap_group_init(struct mlxsw_core *mlxsw_core,
if (WARN_ON(!group_item))
return -EINVAL;
if (group_item->fixed_policer && policer_id != group->init_policer_id) {
NL_SET_ERR_MSG_MOD(extack, "Changing the policer binding of this group is not supported");
return -EOPNOTSUPP;
}
if (policer_id) {
struct mlxsw_sp_trap_policer_item *policer_item;
@ -1682,10 +1711,23 @@ const struct mlxsw_sp_trap_ops mlxsw_sp1_trap_ops = {
static const struct mlxsw_sp_trap_group_item
mlxsw_sp2_trap_group_items_arr[] = {
{
.group = DEVLINK_TRAP_GROUP_GENERIC(BUFFER_DROPS, 20),
.hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_BUFFER_DISCARDS,
.priority = 0,
.fixed_policer = true,
},
};
static const struct mlxsw_sp_trap_item
mlxsw_sp2_trap_items_arr[] = {
{
.trap = MLXSW_SP_TRAP_BUFFER_DROP(EARLY_DROP),
.listeners_arr = {
MLXSW_SP_RXL_BUFFER_DISCARD(INGRESS_WRED),
},
.is_source = true,
},
};
static int