Skip to content

Commit

Permalink
netdevsim: Add devlink-trap policer support
Browse files Browse the repository at this point in the history
Register three dummy packet trap policers with devlink and implement
callbacks to change their parameters and read their counters.

This will be used later on in the series to test the devlink-trap
policer infrastructure.

v2:
* Remove check about burst size being a power of 2 and instead add a
  debugfs knob to fail the operation
* Provide max/min rate/burst size when registering policers and remove
  the validity checks from nsim_dev_devlink_trap_policer_set()

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Ido Schimmel authored and David S. Miller committed Mar 31, 2020
1 parent ef7d5c7 commit ad18845
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 1 deletion.
85 changes: 84 additions & 1 deletion drivers/net/netdevsim/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
&nsim_dev->fail_reload);
debugfs_create_file("trap_flow_action_cookie", 0600, nsim_dev->ddir,
nsim_dev, &nsim_dev_trap_fa_cookie_fops);
debugfs_create_bool("fail_trap_policer_set", 0600,
nsim_dev->ddir,
&nsim_dev->fail_trap_policer_set);
debugfs_create_bool("fail_trap_policer_counter_get", 0600,
nsim_dev->ddir,
&nsim_dev->fail_trap_policer_counter_get);
return 0;
}

Expand Down Expand Up @@ -392,6 +398,7 @@ struct nsim_trap_item {
struct nsim_trap_data {
struct delayed_work trap_report_dw;
struct nsim_trap_item *trap_items_arr;
u64 *trap_policers_cnt_arr;
struct nsim_dev *nsim_dev;
spinlock_t trap_lock; /* Protects trap_items_arr */
};
Expand Down Expand Up @@ -426,6 +433,24 @@ enum {
DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
NSIM_TRAP_METADATA)

#define NSIM_DEV_TRAP_POLICER_MIN_RATE 1
#define NSIM_DEV_TRAP_POLICER_MAX_RATE 8000
#define NSIM_DEV_TRAP_POLICER_MIN_BURST 8
#define NSIM_DEV_TRAP_POLICER_MAX_BURST 65536

#define NSIM_TRAP_POLICER(_id, _rate, _burst) \
DEVLINK_TRAP_POLICER(_id, _rate, _burst, \
NSIM_DEV_TRAP_POLICER_MAX_RATE, \
NSIM_DEV_TRAP_POLICER_MIN_RATE, \
NSIM_DEV_TRAP_POLICER_MAX_BURST, \
NSIM_DEV_TRAP_POLICER_MIN_BURST)

static const struct devlink_trap_policer nsim_trap_policers_arr[] = {
NSIM_TRAP_POLICER(1, 1000, 128),
NSIM_TRAP_POLICER(2, 2000, 256),
NSIM_TRAP_POLICER(3, 3000, 512),
};

static const struct devlink_trap_group nsim_trap_groups_arr[] = {
DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS),
DEVLINK_TRAP_GROUP_GENERIC(L3_DROPS),
Expand Down Expand Up @@ -568,6 +593,7 @@ static void nsim_dev_trap_report_work(struct work_struct *work)

static int nsim_dev_traps_init(struct devlink *devlink)
{
size_t policers_count = ARRAY_SIZE(nsim_trap_policers_arr);
struct nsim_dev *nsim_dev = devlink_priv(devlink);
struct nsim_trap_data *nsim_trap_data;
int err;
Expand All @@ -584,6 +610,14 @@ static int nsim_dev_traps_init(struct devlink *devlink)
goto err_trap_data_free;
}

nsim_trap_data->trap_policers_cnt_arr = kcalloc(policers_count,
sizeof(u64),
GFP_KERNEL);
if (!nsim_trap_data->trap_policers_cnt_arr) {
err = -ENOMEM;
goto err_trap_items_free;
}

/* The lock is used to protect the action state of the registered
* traps. The value is written by user and read in delayed work when
* iterating over all the traps.
Expand All @@ -592,10 +626,15 @@ static int nsim_dev_traps_init(struct devlink *devlink)
nsim_trap_data->nsim_dev = nsim_dev;
nsim_dev->trap_data = nsim_trap_data;

err = devlink_trap_policers_register(devlink, nsim_trap_policers_arr,
policers_count);
if (err)
goto err_trap_policers_cnt_free;

err = devlink_trap_groups_register(devlink, nsim_trap_groups_arr,
ARRAY_SIZE(nsim_trap_groups_arr));
if (err)
goto err_trap_items_free;
goto err_trap_policers_unregister;

err = devlink_traps_register(devlink, nsim_traps_arr,
ARRAY_SIZE(nsim_traps_arr), NULL);
Expand All @@ -612,6 +651,11 @@ static int nsim_dev_traps_init(struct devlink *devlink)
err_trap_groups_unregister:
devlink_trap_groups_unregister(devlink, nsim_trap_groups_arr,
ARRAY_SIZE(nsim_trap_groups_arr));
err_trap_policers_unregister:
devlink_trap_policers_unregister(devlink, nsim_trap_policers_arr,
ARRAY_SIZE(nsim_trap_policers_arr));
err_trap_policers_cnt_free:
kfree(nsim_trap_data->trap_policers_cnt_arr);
err_trap_items_free:
kfree(nsim_trap_data->trap_items_arr);
err_trap_data_free:
Expand All @@ -628,6 +672,9 @@ static void nsim_dev_traps_exit(struct devlink *devlink)
ARRAY_SIZE(nsim_traps_arr));
devlink_trap_groups_unregister(devlink, nsim_trap_groups_arr,
ARRAY_SIZE(nsim_trap_groups_arr));
devlink_trap_policers_unregister(devlink, nsim_trap_policers_arr,
ARRAY_SIZE(nsim_trap_policers_arr));
kfree(nsim_dev->trap_data->trap_policers_cnt_arr);
kfree(nsim_dev->trap_data->trap_items_arr);
kfree(nsim_dev->trap_data);
}
Expand Down Expand Up @@ -766,13 +813,49 @@ nsim_dev_devlink_trap_action_set(struct devlink *devlink,
return 0;
}

static int
nsim_dev_devlink_trap_policer_set(struct devlink *devlink,
const struct devlink_trap_policer *policer,
u64 rate, u64 burst,
struct netlink_ext_ack *extack)
{
struct nsim_dev *nsim_dev = devlink_priv(devlink);

if (nsim_dev->fail_trap_policer_set) {
NL_SET_ERR_MSG_MOD(extack, "User setup the operation to fail for testing purposes");
return -EINVAL;
}

return 0;
}

static int
nsim_dev_devlink_trap_policer_counter_get(struct devlink *devlink,
const struct devlink_trap_policer *policer,
u64 *p_drops)
{
struct nsim_dev *nsim_dev = devlink_priv(devlink);
u64 *cnt;

if (nsim_dev->fail_trap_policer_counter_get)
return -EINVAL;

cnt = &nsim_dev->trap_data->trap_policers_cnt_arr[policer->id - 1];
*p_drops = *cnt;
*cnt += jiffies % 64;

return 0;
}

static const struct devlink_ops nsim_dev_devlink_ops = {
.reload_down = nsim_dev_reload_down,
.reload_up = nsim_dev_reload_up,
.info_get = nsim_dev_info_get,
.flash_update = nsim_dev_flash_update,
.trap_init = nsim_dev_devlink_trap_init,
.trap_action_set = nsim_dev_devlink_trap_action_set,
.trap_policer_set = nsim_dev_devlink_trap_policer_set,
.trap_policer_counter_get = nsim_dev_devlink_trap_policer_counter_get,
};

#define NSIM_DEV_MAX_MACS_DEFAULT 32
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/netdevsim/netdevsim.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ struct nsim_dev {
struct nsim_dev_health health;
struct flow_action_cookie *fa_cookie;
spinlock_t fa_cookie_lock; /* protects fa_cookie */
bool fail_trap_policer_set;
bool fail_trap_policer_counter_get;
};

static inline struct net *nsim_dev_net(struct nsim_dev *nsim_dev)
Expand Down

0 comments on commit ad18845

Please sign in to comment.