mirror of
https://github.com/torvalds/linux.git
synced 2024-12-12 14:12:51 +00:00
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:
parent
869c7be940
commit
6687e953f4
@ -89,13 +89,15 @@ struct mlxsw_listener {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define __MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _en_trap_group, \
|
#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, \
|
.trap_id = MLXSW_TRAP_ID_##_trap_id, \
|
||||||
.rx_listener = \
|
.rx_listener = \
|
||||||
{ \
|
{ \
|
||||||
.func = _func, \
|
.func = _func, \
|
||||||
.local_port = MLXSW_PORT_DONT_CARE, \
|
.local_port = MLXSW_PORT_DONT_CARE, \
|
||||||
|
.mirror_reason = _mirror_reason, \
|
||||||
.trap_id = MLXSW_TRAP_ID_##_trap_id, \
|
.trap_id = MLXSW_TRAP_ID_##_trap_id, \
|
||||||
}, \
|
}, \
|
||||||
.en_action = MLXSW_REG_HPKT_ACTION_##_en_action, \
|
.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, \
|
#define MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _trap_group, \
|
||||||
_dis_action) \
|
_dis_action) \
|
||||||
__MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _trap_group, \
|
__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, \
|
#define MLXSW_RXL_DIS(_func, _trap_id, _en_action, _is_ctrl, _en_trap_group, \
|
||||||
_dis_action, _dis_trap_group) \
|
_dis_action, _dis_trap_group) \
|
||||||
__MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _en_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) \
|
#define MLXSW_EVENTL(_func, _trap_id, _trap_group) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -5614,6 +5614,7 @@ enum mlxsw_reg_htgt_trap_group {
|
|||||||
MLXSW_REG_HTGT_TRAP_GROUP_SP_L3_EXCEPTIONS,
|
MLXSW_REG_HTGT_TRAP_GROUP_SP_L3_EXCEPTIONS,
|
||||||
MLXSW_REG_HTGT_TRAP_GROUP_SP_TUNNEL_DISCARDS,
|
MLXSW_REG_HTGT_TRAP_GROUP_SP_TUNNEL_DISCARDS,
|
||||||
MLXSW_REG_HTGT_TRAP_GROUP_SP_ACL_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 = __MLXSW_REG_HTGT_TRAP_GROUP_MAX - 1
|
MLXSW_REG_HTGT_TRAP_GROUP_MAX = __MLXSW_REG_HTGT_TRAP_GROUP_MAX - 1
|
||||||
|
@ -21,6 +21,7 @@ struct mlxsw_sp_trap_group_item {
|
|||||||
struct devlink_trap_group group;
|
struct devlink_trap_group group;
|
||||||
u16 hw_group_id;
|
u16 hw_group_id;
|
||||||
u8 priority;
|
u8 priority;
|
||||||
|
u8 fixed_policer:1; /* Whether policer binding can change */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MLXSW_SP_TRAP_LISTENERS_MAX 3
|
#define MLXSW_SP_TRAP_LISTENERS_MAX 3
|
||||||
@ -28,6 +29,7 @@ struct mlxsw_sp_trap_group_item {
|
|||||||
struct mlxsw_sp_trap_item {
|
struct mlxsw_sp_trap_item {
|
||||||
struct devlink_trap trap;
|
struct devlink_trap trap;
|
||||||
struct mlxsw_listener listeners_arr[MLXSW_SP_TRAP_LISTENERS_MAX];
|
struct mlxsw_listener listeners_arr[MLXSW_SP_TRAP_LISTENERS_MAX];
|
||||||
|
u8 is_source:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* All driver-specific traps must be documented in
|
/* 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
|
#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,
|
static int mlxsw_sp_rx_listener(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
|
||||||
u8 local_port,
|
u8 local_port,
|
||||||
struct mlxsw_sp_port *mlxsw_sp_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, \
|
DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
|
||||||
MLXSW_SP_TRAP_METADATA | (_metadata))
|
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) \
|
#define MLXSW_SP_TRAP_DRIVER_DROP(_id, _group_id) \
|
||||||
DEVLINK_TRAP_DRIVER(DROP, DROP, DEVLINK_MLXSW_TRAP_ID_##_id, \
|
DEVLINK_TRAP_DRIVER(DROP, DROP, DEVLINK_MLXSW_TRAP_ID_##_id, \
|
||||||
DEVLINK_MLXSW_TRAP_NAME_##_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, \
|
TRAP_EXCEPTION_TO_CPU, false, SP_##_en_group_id, \
|
||||||
SET_FW_DEFAULT, SP_##_dis_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) \
|
#define MLXSW_SP_RXL_EXCEPTION(_id, _group_id, _action) \
|
||||||
MLXSW_RXL(mlxsw_sp_rx_mark_listener, _id, \
|
MLXSW_RXL(mlxsw_sp_rx_mark_listener, _id, \
|
||||||
_action, false, SP_##_group_id, SET_FW_DEFAULT)
|
_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(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[] = {
|
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))
|
if (WARN_ON(!trap_item))
|
||||||
return -EINVAL;
|
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++) {
|
for (i = 0; i < MLXSW_SP_TRAP_LISTENERS_MAX; i++) {
|
||||||
const struct mlxsw_listener *listener;
|
const struct mlxsw_listener *listener;
|
||||||
bool enabled;
|
bool enabled;
|
||||||
@ -1470,6 +1494,11 @@ __mlxsw_sp_trap_group_init(struct mlxsw_core *mlxsw_core,
|
|||||||
if (WARN_ON(!group_item))
|
if (WARN_ON(!group_item))
|
||||||
return -EINVAL;
|
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) {
|
if (policer_id) {
|
||||||
struct mlxsw_sp_trap_policer_item *policer_item;
|
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
|
static const struct mlxsw_sp_trap_group_item
|
||||||
mlxsw_sp2_trap_group_items_arr[] = {
|
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
|
static const struct mlxsw_sp_trap_item
|
||||||
mlxsw_sp2_trap_items_arr[] = {
|
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
|
static int
|
||||||
|
Loading…
Reference in New Issue
Block a user