Skip to content

Commit

Permalink
net/mlx5e: Add red and green counters for metering
Browse files Browse the repository at this point in the history
Add red and green counters per meter instance.
TC police action is implemented as a meter instance.
The meter counters represent the police action
notexceed/exceed counters.
TC rules using the same meter instance will use
the same counters.

Signed-off-by: Roi Dayan <roid@nvidia.com>
Reviewed-by: Jianbo Liu <jianbol@nvidia.com>
Reviewed-by: Oz Shlomo <ozsh@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
  • Loading branch information
Roi Dayan authored and Saeed Mahameed committed Jul 28, 2022
1 parent e5b1db2 commit b50ce43
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 13 deletions.
22 changes: 22 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,13 +240,28 @@ __mlx5e_flow_meter_alloc(struct mlx5e_flow_meters *flow_meters)
struct mlx5_core_dev *mdev = flow_meters->mdev;
struct mlx5e_flow_meter_aso_obj *meters_obj;
struct mlx5e_flow_meter_handle *meter;
struct mlx5_fc *counter;
int err, pos, total;
u32 id;

meter = kzalloc(sizeof(*meter), GFP_KERNEL);
if (!meter)
return ERR_PTR(-ENOMEM);

counter = mlx5_fc_create(mdev, true);
if (IS_ERR(counter)) {
err = PTR_ERR(counter);
goto err_red_counter;
}
meter->red_counter = counter;

counter = mlx5_fc_create(mdev, true);
if (IS_ERR(counter)) {
err = PTR_ERR(counter);
goto err_green_counter;
}
meter->green_counter = counter;

meters_obj = list_first_entry_or_null(&flow_meters->partial_list,
struct mlx5e_flow_meter_aso_obj,
entry);
Expand Down Expand Up @@ -292,6 +307,10 @@ __mlx5e_flow_meter_alloc(struct mlx5e_flow_meters *flow_meters)
err_mem:
mlx5e_flow_meter_destroy_aso_obj(mdev, id);
err_create:
mlx5_fc_destroy(mdev, meter->green_counter);
err_green_counter:
mlx5_fc_destroy(mdev, meter->red_counter);
err_red_counter:
kfree(meter);
return ERR_PTR(err);
}
Expand All @@ -304,6 +323,9 @@ __mlx5e_flow_meter_free(struct mlx5e_flow_meter_handle *meter)
struct mlx5e_flow_meter_aso_obj *meters_obj;
int n, pos;

mlx5_fc_destroy(mdev, meter->green_counter);
mlx5_fc_destroy(mdev, meter->red_counter);

meters_obj = meter->meters_obj;
pos = (meter->obj_id - meters_obj->base_id) * 2 + meter->idx;
bitmap_clear(meters_obj->meters_map, pos, 1);
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ struct mlx5e_flow_meter_handle {
int refcnt;
struct hlist_node hlist;
struct mlx5e_flow_meter_params params;

struct mlx5_fc *green_counter;
struct mlx5_fc *red_counter;
};

struct mlx5e_meter_attr {
Expand Down
33 changes: 22 additions & 11 deletions drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_meter.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,11 @@ mlx5e_post_meter_fg_create(struct mlx5e_priv *priv,
static int
mlx5e_post_meter_rules_create(struct mlx5e_priv *priv,
struct mlx5e_post_meter_priv *post_meter,
struct mlx5e_post_act *post_act)
struct mlx5e_post_act *post_act,
struct mlx5_fc *green_counter,
struct mlx5_fc *red_counter)
{
struct mlx5_flow_destination dest = {};
struct mlx5_flow_destination dest[2] = {};
struct mlx5_flow_act flow_act = {};
struct mlx5_flow_handle *rule;
struct mlx5_flow_spec *spec;
Expand All @@ -98,10 +100,13 @@ mlx5e_post_meter_rules_create(struct mlx5e_priv *priv,

mlx5e_tc_match_to_reg_match(spec, PACKET_COLOR_TO_REG,
MLX5_FLOW_METER_COLOR_RED, MLX5_PACKET_COLOR_MASK);
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP |
MLX5_FLOW_CONTEXT_ACTION_COUNT;
flow_act.flags |= FLOW_ACT_IGNORE_FLOW_LEVEL;
dest[0].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
dest[0].counter_id = mlx5_fc_id(red_counter);

rule = mlx5_add_flow_rules(post_meter->ft, spec, &flow_act, NULL, 0);
rule = mlx5_add_flow_rules(post_meter->ft, spec, &flow_act, dest, 1);
if (IS_ERR(rule)) {
mlx5_core_warn(priv->mdev, "Failed to create post_meter flow drop rule\n");
err = PTR_ERR(rule);
Expand All @@ -111,11 +116,14 @@ mlx5e_post_meter_rules_create(struct mlx5e_priv *priv,

mlx5e_tc_match_to_reg_match(spec, PACKET_COLOR_TO_REG,
MLX5_FLOW_METER_COLOR_GREEN, MLX5_PACKET_COLOR_MASK);
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
dest.ft = mlx5e_tc_post_act_get_ft(post_act);

rule = mlx5_add_flow_rules(post_meter->ft, spec, &flow_act, &dest, 1);
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
MLX5_FLOW_CONTEXT_ACTION_COUNT;
dest[0].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
dest[0].ft = mlx5e_tc_post_act_get_ft(post_act);
dest[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
dest[1].counter_id = mlx5_fc_id(green_counter);

rule = mlx5_add_flow_rules(post_meter->ft, spec, &flow_act, dest, 2);
if (IS_ERR(rule)) {
mlx5_core_warn(priv->mdev, "Failed to create post_meter flow fwd rule\n");
err = PTR_ERR(rule);
Expand Down Expand Up @@ -155,7 +163,9 @@ mlx5e_post_meter_table_destroy(struct mlx5e_post_meter_priv *post_meter)
struct mlx5e_post_meter_priv *
mlx5e_post_meter_init(struct mlx5e_priv *priv,
enum mlx5_flow_namespace_type ns_type,
struct mlx5e_post_act *post_act)
struct mlx5e_post_act *post_act,
struct mlx5_fc *green_counter,
struct mlx5_fc *red_counter)
{
struct mlx5e_post_meter_priv *post_meter;
int err;
Expand All @@ -172,7 +182,8 @@ mlx5e_post_meter_init(struct mlx5e_priv *priv,
if (err)
goto err_fg;

err = mlx5e_post_meter_rules_create(priv, post_meter, post_act);
err = mlx5e_post_meter_rules_create(priv, post_meter, post_act, green_counter,
red_counter);
if (err)
goto err_rules;

Expand Down
4 changes: 3 additions & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_meter.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ mlx5e_post_meter_get_ft(struct mlx5e_post_meter_priv *post_meter);
struct mlx5e_post_meter_priv *
mlx5e_post_meter_init(struct mlx5e_priv *priv,
enum mlx5_flow_namespace_type ns_type,
struct mlx5e_post_act *post_act);
struct mlx5e_post_act *post_act,
struct mlx5_fc *green_counter,
struct mlx5_fc *red_counter);
void
mlx5e_post_meter_cleanup(struct mlx5e_post_meter_priv *post_meter);

Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,8 @@ mlx5e_tc_add_flow_meter(struct mlx5e_priv *priv,
}

ns_type = mlx5e_tc_meter_get_namespace(meter->flow_meters);
post_meter = mlx5e_post_meter_init(priv, ns_type, post_act);
post_meter = mlx5e_post_meter_init(priv, ns_type, post_act, meter->green_counter,
meter->red_counter);
if (IS_ERR(post_meter)) {
mlx5_core_err(priv->mdev, "Failed to init post meter\n");
goto err_meter_init;
Expand Down

0 comments on commit b50ce43

Please sign in to comment.