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

devlink: Add packet trap policers support

Devices capable of offloading the kernel's datapath and perform
functions such as bridging and routing must also be able to send (trap)
specific packets to the kernel (i.e., the CPU) for processing.

For example, a device acting as a multicast-aware bridge must be able to
trap IGMP membership reports to the kernel for processing by the bridge
module.

In most cases, the underlying device is capable of handling packet rates
that are several orders of magnitude higher compared to those that can
be handled by the CPU.

Therefore, in order to prevent the underlying device from overwhelming
the CPU, devices usually include packet trap policers that are able to
police the trapped packets to rates that can be handled by the CPU.

This patch allows capable device drivers to register their supported
packet trap policers with devlink. User space can then tune the
parameters of these policer (currently, rate and burst size) and read
from the device the number of packets that were dropped by the policer,
if supported.

Subsequent patches in the series will allow device drivers to create
default binding between these policers and packet trap groups and allow
user space to change the binding.

v2:
* Add 'strict_start_type' in devlink policy
* Have device drivers provide max/min rate/burst size for each policer.
  Use them to check validity of user provided parameters
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 2d39eab4
...@@ -35,6 +35,7 @@ struct devlink { ...@@ -35,6 +35,7 @@ struct devlink {
struct devlink_dpipe_headers *dpipe_headers; struct devlink_dpipe_headers *dpipe_headers;
struct list_head trap_list; struct list_head trap_list;
struct list_head trap_group_list; struct list_head trap_group_list;
struct list_head trap_policer_list;
const struct devlink_ops *ops; const struct devlink_ops *ops;
struct xarray snapshot_ids; struct xarray snapshot_ids;
struct device *dev; struct device *dev;
...@@ -545,6 +546,29 @@ struct devlink_health_reporter_ops { ...@@ -545,6 +546,29 @@ struct devlink_health_reporter_ops {
struct netlink_ext_ack *extack); struct netlink_ext_ack *extack);
}; };
/**
* struct devlink_trap_policer - Immutable packet trap policer attributes.
* @id: Policer identifier.
* @init_rate: Initial rate in packets / sec.
* @init_burst: Initial burst size in packets.
* @max_rate: Maximum rate.
* @min_rate: Minimum rate.
* @max_burst: Maximum burst size.
* @min_burst: Minimum burst size.
*
* Describes immutable attributes of packet trap policers that drivers register
* with devlink.
*/
struct devlink_trap_policer {
u32 id;
u64 init_rate;
u64 init_burst;
u64 max_rate;
u64 min_rate;
u64 max_burst;
u64 min_burst;
};
/** /**
* struct devlink_trap_group - Immutable packet trap group attributes. * struct devlink_trap_group - Immutable packet trap group attributes.
* @name: Trap group name. * @name: Trap group name.
...@@ -742,6 +766,18 @@ enum devlink_trap_group_generic_id { ...@@ -742,6 +766,18 @@ enum devlink_trap_group_generic_id {
.generic = true, \ .generic = true, \
} }
#define DEVLINK_TRAP_POLICER(_id, _rate, _burst, _max_rate, _min_rate, \
_max_burst, _min_burst) \
{ \
.id = _id, \
.init_rate = _rate, \
.init_burst = _burst, \
.max_rate = _max_rate, \
.min_rate = _min_rate, \
.max_burst = _max_burst, \
.min_burst = _min_burst, \
}
struct devlink_ops { struct devlink_ops {
int (*reload_down)(struct devlink *devlink, bool netns_change, int (*reload_down)(struct devlink *devlink, bool netns_change,
struct netlink_ext_ack *extack); struct netlink_ext_ack *extack);
...@@ -838,6 +874,38 @@ struct devlink_ops { ...@@ -838,6 +874,38 @@ struct devlink_ops {
*/ */
int (*trap_group_init)(struct devlink *devlink, int (*trap_group_init)(struct devlink *devlink,
const struct devlink_trap_group *group); const struct devlink_trap_group *group);
/**
* @trap_policer_init: Trap policer initialization function.
*
* Should be used by device drivers to initialize the trap policer in
* the underlying device.
*/
int (*trap_policer_init)(struct devlink *devlink,
const struct devlink_trap_policer *policer);
/**
* @trap_policer_fini: Trap policer de-initialization function.
*
* Should be used by device drivers to de-initialize the trap policer
* in the underlying device.
*/
void (*trap_policer_fini)(struct devlink *devlink,
const struct devlink_trap_policer *policer);
/**
* @trap_policer_set: Trap policer parameters set function.
*/
int (*trap_policer_set)(struct devlink *devlink,
const struct devlink_trap_policer *policer,
u64 rate, u64 burst,
struct netlink_ext_ack *extack);
/**
* @trap_policer_counter_get: Trap policer counter get function.
*
* Should be used by device drivers to report number of packets dropped
* by the policer.
*/
int (*trap_policer_counter_get)(struct devlink *devlink,
const struct devlink_trap_policer *policer,
u64 *p_drops);
}; };
static inline void *devlink_priv(struct devlink *devlink) static inline void *devlink_priv(struct devlink *devlink)
...@@ -1080,6 +1148,14 @@ int devlink_trap_groups_register(struct devlink *devlink, ...@@ -1080,6 +1148,14 @@ int devlink_trap_groups_register(struct devlink *devlink,
void devlink_trap_groups_unregister(struct devlink *devlink, void devlink_trap_groups_unregister(struct devlink *devlink,
const struct devlink_trap_group *groups, const struct devlink_trap_group *groups,
size_t groups_count); size_t groups_count);
int
devlink_trap_policers_register(struct devlink *devlink,
const struct devlink_trap_policer *policers,
size_t policers_count);
void
devlink_trap_policers_unregister(struct devlink *devlink,
const struct devlink_trap_policer *policers,
size_t policers_count);
#if IS_ENABLED(CONFIG_NET_DEVLINK) #if IS_ENABLED(CONFIG_NET_DEVLINK)
......
...@@ -117,6 +117,11 @@ enum devlink_command { ...@@ -117,6 +117,11 @@ enum devlink_command {
DEVLINK_CMD_TRAP_GROUP_NEW, DEVLINK_CMD_TRAP_GROUP_NEW,
DEVLINK_CMD_TRAP_GROUP_DEL, DEVLINK_CMD_TRAP_GROUP_DEL,
DEVLINK_CMD_TRAP_POLICER_GET, /* can dump */
DEVLINK_CMD_TRAP_POLICER_SET,
DEVLINK_CMD_TRAP_POLICER_NEW,
DEVLINK_CMD_TRAP_POLICER_DEL,
/* add new commands above here */ /* add new commands above here */
__DEVLINK_CMD_MAX, __DEVLINK_CMD_MAX,
DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1 DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
...@@ -217,6 +222,7 @@ enum devlink_param_reset_dev_on_drv_probe_value { ...@@ -217,6 +222,7 @@ enum devlink_param_reset_dev_on_drv_probe_value {
enum { enum {
DEVLINK_ATTR_STATS_RX_PACKETS, /* u64 */ DEVLINK_ATTR_STATS_RX_PACKETS, /* u64 */
DEVLINK_ATTR_STATS_RX_BYTES, /* u64 */ DEVLINK_ATTR_STATS_RX_BYTES, /* u64 */
DEVLINK_ATTR_STATS_RX_DROPPED, /* u64 */
__DEVLINK_ATTR_STATS_MAX, __DEVLINK_ATTR_STATS_MAX,
DEVLINK_ATTR_STATS_MAX = __DEVLINK_ATTR_STATS_MAX - 1 DEVLINK_ATTR_STATS_MAX = __DEVLINK_ATTR_STATS_MAX - 1
...@@ -431,6 +437,11 @@ enum devlink_attr { ...@@ -431,6 +437,11 @@ enum devlink_attr {
DEVLINK_ATTR_NETNS_ID, /* u32 */ DEVLINK_ATTR_NETNS_ID, /* u32 */
DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP, /* u8 */ DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP, /* u8 */
DEVLINK_ATTR_TRAP_POLICER_ID, /* u32 */
DEVLINK_ATTR_TRAP_POLICER_RATE, /* u64 */
DEVLINK_ATTR_TRAP_POLICER_BURST, /* u64 */
/* add new attributes above here, update the policy in devlink.c */ /* add new attributes above here, update the policy in devlink.c */
__DEVLINK_ATTR_MAX, __DEVLINK_ATTR_MAX,
......
This diff is collapsed.
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