Skip to content

Commit aad7e08

Browse files
amirvdavem330
authored andcommitted
net/mlx5e: Hardware offloaded flower filter statistics support
Introduce support in updating statistics of offloaded TC flower classifiers. Currently only the DROP action is supported. Signed-off-by: Amir Vadai <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 43a335e commit aad7e08

File tree

3 files changed

+69
-7
lines changed

3 files changed

+69
-7
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en_main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2154,6 +2154,8 @@ static int mlx5e_ndo_setup_tc(struct net_device *dev, u32 handle,
21542154
return mlx5e_configure_flower(priv, proto, tc->cls_flower);
21552155
case TC_CLSFLOWER_DESTROY:
21562156
return mlx5e_delete_flower(priv, tc->cls_flower);
2157+
case TC_CLSFLOWER_STATS:
2158+
return mlx5e_stats_flower(priv, tc->cls_flower);
21572159
}
21582160
default:
21592161
return -EOPNOTSUPP;

drivers/net/ethernet/mellanox/mlx5/core/en_tc.c

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,24 @@ static struct mlx5_flow_rule *mlx5e_tc_add_flow(struct mlx5e_priv *priv,
5353
u32 *match_c, u32 *match_v,
5454
u32 action, u32 flow_tag)
5555
{
56-
struct mlx5_flow_destination dest = {
57-
.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE,
58-
{.ft = priv->fs.vlan.ft.t},
59-
};
56+
struct mlx5_core_dev *dev = priv->mdev;
57+
struct mlx5_flow_destination dest = { 0 };
58+
struct mlx5_fc *counter = NULL;
6059
struct mlx5_flow_rule *rule;
6160
bool table_created = false;
6261

62+
if (action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
63+
dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
64+
dest.ft = priv->fs.vlan.ft.t;
65+
} else {
66+
counter = mlx5_fc_create(dev, true);
67+
if (IS_ERR(counter))
68+
return ERR_CAST(counter);
69+
70+
dest.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
71+
dest.counter = counter;
72+
}
73+
6374
if (IS_ERR_OR_NULL(priv->fs.tc.t)) {
6475
priv->fs.tc.t =
6576
mlx5_create_auto_grouped_flow_table(priv->fs.ns,
@@ -70,7 +81,8 @@ static struct mlx5_flow_rule *mlx5e_tc_add_flow(struct mlx5e_priv *priv,
7081
if (IS_ERR(priv->fs.tc.t)) {
7182
netdev_err(priv->netdev,
7283
"Failed to create tc offload table\n");
73-
return ERR_CAST(priv->fs.tc.t);
84+
rule = ERR_CAST(priv->fs.tc.t);
85+
goto err_create_ft;
7486
}
7587

7688
table_created = true;
@@ -79,21 +91,35 @@ static struct mlx5_flow_rule *mlx5e_tc_add_flow(struct mlx5e_priv *priv,
7991
rule = mlx5_add_flow_rule(priv->fs.tc.t, MLX5_MATCH_OUTER_HEADERS,
8092
match_c, match_v,
8193
action, flow_tag,
82-
action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST ? &dest : NULL);
94+
&dest);
95+
96+
if (IS_ERR(rule))
97+
goto err_add_rule;
98+
99+
return rule;
83100

84-
if (IS_ERR(rule) && table_created) {
101+
err_add_rule:
102+
if (table_created) {
85103
mlx5_destroy_flow_table(priv->fs.tc.t);
86104
priv->fs.tc.t = NULL;
87105
}
106+
err_create_ft:
107+
mlx5_fc_destroy(dev, counter);
88108

89109
return rule;
90110
}
91111

92112
static void mlx5e_tc_del_flow(struct mlx5e_priv *priv,
93113
struct mlx5_flow_rule *rule)
94114
{
115+
struct mlx5_fc *counter = NULL;
116+
117+
counter = mlx5_flow_rule_counter(rule);
118+
95119
mlx5_del_flow_rule(rule);
96120

121+
mlx5_fc_destroy(priv->mdev, counter);
122+
97123
if (!mlx5e_tc_num_filters(priv)) {
98124
mlx5_destroy_flow_table(priv->fs.tc.t);
99125
priv->fs.tc.t = NULL;
@@ -286,6 +312,9 @@ static int parse_tc_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
286312

287313
if (is_tcf_gact_shot(a)) {
288314
*action |= MLX5_FLOW_CONTEXT_ACTION_DROP;
315+
if (MLX5_CAP_FLOWTABLE(priv->mdev,
316+
flow_table_properties_nic_receive.flow_counter))
317+
*action |= MLX5_FLOW_CONTEXT_ACTION_COUNT;
289318
continue;
290319
}
291320

@@ -394,6 +423,34 @@ int mlx5e_delete_flower(struct mlx5e_priv *priv,
394423
return 0;
395424
}
396425

426+
int mlx5e_stats_flower(struct mlx5e_priv *priv,
427+
struct tc_cls_flower_offload *f)
428+
{
429+
struct mlx5e_tc_table *tc = &priv->fs.tc;
430+
struct mlx5e_tc_flow *flow;
431+
struct tc_action *a;
432+
struct mlx5_fc *counter;
433+
u64 bytes;
434+
u64 packets;
435+
u64 lastuse;
436+
437+
flow = rhashtable_lookup_fast(&tc->ht, &f->cookie,
438+
tc->ht_params);
439+
if (!flow)
440+
return -EINVAL;
441+
442+
counter = mlx5_flow_rule_counter(flow->rule);
443+
if (!counter)
444+
return 0;
445+
446+
mlx5_fc_query_cached(counter, &bytes, &packets, &lastuse);
447+
448+
tc_for_each_action(a, f->exts)
449+
tcf_action_stats_update(a, bytes, packets, lastuse);
450+
451+
return 0;
452+
}
453+
397454
static const struct rhashtable_params mlx5e_tc_flow_ht_params = {
398455
.head_offset = offsetof(struct mlx5e_tc_flow, node),
399456
.key_offset = offsetof(struct mlx5e_tc_flow, cookie),

drivers/net/ethernet/mellanox/mlx5/core/en_tc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol,
4343
int mlx5e_delete_flower(struct mlx5e_priv *priv,
4444
struct tc_cls_flower_offload *f);
4545

46+
int mlx5e_stats_flower(struct mlx5e_priv *priv,
47+
struct tc_cls_flower_offload *f);
48+
4649
static inline int mlx5e_tc_num_filters(struct mlx5e_priv *priv)
4750
{
4851
return atomic_read(&priv->fs.tc.ht.nelems);

0 commit comments

Comments
 (0)