Skip to content

Commit 2b68d65

Browse files
ozshlomoPaolo Abeni
authored andcommitted
net/mlx5e: TC, support per action stats
Extend the action stats callback implementation to update stats for actions that are associated with hw counters. Note that the callback may be called from tc action utility or from tc flower. Both apis expect the driver to return the stats difference from the last update. As such, query the raw counter value and maintain the diff from the last api call in the tc layer, instead of the fs_core layer. Signed-off-by: Oz Shlomo <ozsh@nvidia.com> Reviewed-by: Roi Dayan <roid@nvidia.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent d13674b commit 2b68d65

File tree

8 files changed

+91
-13
lines changed

8 files changed

+91
-13
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ mlx5e_rep_indr_stats_act(struct mlx5e_rep_priv *rpriv,
589589

590590
act = mlx5e_tc_act_get(fl_act->id, ns_type);
591591
if (!act || !act->stats_action)
592-
return -EOPNOTSUPP;
592+
return mlx5e_tc_fill_action_stats(priv, fl_act);
593593

594594
return act->stats_action(priv, fl_act);
595595
}

drivers/net/ethernet/mellanox/mlx5/core/en/tc/act_stats.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ mlx5e_tc_act_stats_del_flow(struct mlx5e_tc_act_stats_handle *handle,
102102
struct mlx5e_tc_act_stats *act_stats;
103103
int i;
104104

105+
if (!flow_flag_test(flow, USE_ACT_STATS))
106+
return;
107+
105108
list_for_each_entry(attr, &flow->attrs, list) {
106109
for (i = 0; i < attr->tc_act_cookies_count; i++) {
107110
struct rhashtable *ht = &handle->ht;
@@ -130,6 +133,9 @@ mlx5e_tc_act_stats_add_flow(struct mlx5e_tc_act_stats_handle *handle,
130133
int err;
131134
int i;
132135

136+
if (!flow_flag_test(flow, USE_ACT_STATS))
137+
return 0;
138+
133139
list_for_each_entry(attr, &flow->attrs, list) {
134140
if (attr->counter)
135141
curr_counter = attr->counter;
@@ -151,3 +157,41 @@ mlx5e_tc_act_stats_add_flow(struct mlx5e_tc_act_stats_handle *handle,
151157
mlx5e_tc_act_stats_del_flow(handle, flow);
152158
return err;
153159
}
160+
161+
int
162+
mlx5e_tc_act_stats_fill_stats(struct mlx5e_tc_act_stats_handle *handle,
163+
struct flow_offload_action *fl_act)
164+
{
165+
struct rhashtable *ht = &handle->ht;
166+
struct mlx5e_tc_act_stats *item;
167+
struct mlx5e_tc_act_stats key;
168+
u64 pkts, bytes, lastused;
169+
int err = 0;
170+
171+
key.tc_act_cookie = fl_act->cookie;
172+
173+
rcu_read_lock();
174+
item = rhashtable_lookup(ht, &key, act_counters_ht_params);
175+
if (!item) {
176+
rcu_read_unlock();
177+
err = -ENOENT;
178+
goto err_out;
179+
}
180+
181+
mlx5_fc_query_cached_raw(item->counter,
182+
&bytes, &pkts, &lastused);
183+
184+
flow_stats_update(&fl_act->stats,
185+
bytes - item->lastbytes,
186+
pkts - item->lastpackets,
187+
0, lastused, FLOW_ACTION_HW_STATS_DELAYED);
188+
189+
item->lastpackets = pkts;
190+
item->lastbytes = bytes;
191+
rcu_read_unlock();
192+
193+
return 0;
194+
195+
err_out:
196+
return err;
197+
}

drivers/net/ethernet/mellanox/mlx5/core/en/tc/act_stats.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,8 @@ void
2020
mlx5e_tc_act_stats_del_flow(struct mlx5e_tc_act_stats_handle *handle,
2121
struct mlx5e_tc_flow *flow);
2222

23+
int
24+
mlx5e_tc_act_stats_fill_stats(struct mlx5e_tc_act_stats_handle *handle,
25+
struct flow_offload_action *fl_act);
26+
2327
#endif /* __MLX5_EN_ACT_STATS_H__ */

drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ enum {
3030
MLX5E_TC_FLOW_FLAG_TUN_RX = MLX5E_TC_FLOW_BASE + 9,
3131
MLX5E_TC_FLOW_FLAG_FAILED = MLX5E_TC_FLOW_BASE + 10,
3232
MLX5E_TC_FLOW_FLAG_SAMPLE = MLX5E_TC_FLOW_BASE + 11,
33+
MLX5E_TC_FLOW_FLAG_USE_ACT_STATS = MLX5E_TC_FLOW_BASE + 12,
3334
};
3435

3536
struct mlx5e_tc_flow_parse_attr {

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

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4117,6 +4117,7 @@ parse_branch_ctrl(struct flow_action_entry *act, struct mlx5e_tc_act *tc_act,
41174117

41184118
/* branching action requires its own counter */
41194119
attr->action |= MLX5_FLOW_CONTEXT_ACTION_COUNT;
4120+
flow_flag_set(flow, USE_ACT_STATS);
41204121

41214122
return 0;
41224123

@@ -4967,6 +4968,12 @@ int mlx5e_delete_flower(struct net_device *dev, struct mlx5e_priv *priv,
49674968
return err;
49684969
}
49694970

4971+
int mlx5e_tc_fill_action_stats(struct mlx5e_priv *priv,
4972+
struct flow_offload_action *fl_act)
4973+
{
4974+
return mlx5e_tc_act_stats_fill_stats(get_act_stats_handle(priv), fl_act);
4975+
}
4976+
49704977
int mlx5e_stats_flower(struct net_device *dev, struct mlx5e_priv *priv,
49714978
struct flow_cls_offload *f, unsigned long flags)
49724979
{
@@ -4993,11 +5000,15 @@ int mlx5e_stats_flower(struct net_device *dev, struct mlx5e_priv *priv,
49935000
}
49945001

49955002
if (mlx5e_is_offloaded_flow(flow) || flow_flag_test(flow, CT)) {
4996-
counter = mlx5e_tc_get_counter(flow);
4997-
if (!counter)
4998-
goto errout;
5003+
if (flow_flag_test(flow, USE_ACT_STATS)) {
5004+
f->use_act_stats = true;
5005+
} else {
5006+
counter = mlx5e_tc_get_counter(flow);
5007+
if (!counter)
5008+
goto errout;
49995009

5000-
mlx5_fc_query_cached(counter, &bytes, &packets, &lastuse);
5010+
mlx5_fc_query_cached(counter, &bytes, &packets, &lastuse);
5011+
}
50015012
}
50025013

50035014
/* Under multipath it's possible for one rule to be currently
@@ -5013,14 +5024,18 @@ int mlx5e_stats_flower(struct net_device *dev, struct mlx5e_priv *priv,
50135024
u64 packets2;
50145025
u64 lastuse2;
50155026

5016-
counter = mlx5e_tc_get_counter(flow->peer_flow);
5017-
if (!counter)
5018-
goto no_peer_counter;
5019-
mlx5_fc_query_cached(counter, &bytes2, &packets2, &lastuse2);
5020-
5021-
bytes += bytes2;
5022-
packets += packets2;
5023-
lastuse = max_t(u64, lastuse, lastuse2);
5027+
if (flow_flag_test(flow, USE_ACT_STATS)) {
5028+
f->use_act_stats = true;
5029+
} else {
5030+
counter = mlx5e_tc_get_counter(flow->peer_flow);
5031+
if (!counter)
5032+
goto no_peer_counter;
5033+
mlx5_fc_query_cached(counter, &bytes2, &packets2, &lastuse2);
5034+
5035+
bytes += bytes2;
5036+
packets += packets2;
5037+
lastuse = max_t(u64, lastuse, lastuse2);
5038+
}
50245039
}
50255040

50265041
no_peer_counter:

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ int mlx5e_delete_flower(struct net_device *dev, struct mlx5e_priv *priv,
199199

200200
int mlx5e_stats_flower(struct net_device *dev, struct mlx5e_priv *priv,
201201
struct flow_cls_offload *f, unsigned long flags);
202+
int mlx5e_tc_fill_action_stats(struct mlx5e_priv *priv,
203+
struct flow_offload_action *fl_act);
202204

203205
int mlx5e_tc_configure_matchall(struct mlx5e_priv *priv,
204206
struct tc_cls_matchall_offload *f);

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,16 @@ void mlx5_fc_query_cached(struct mlx5_fc *counter,
504504
counter->lastpackets = c.packets;
505505
}
506506

507+
void mlx5_fc_query_cached_raw(struct mlx5_fc *counter,
508+
u64 *bytes, u64 *packets, u64 *lastuse)
509+
{
510+
struct mlx5_fc_cache c = counter->cache;
511+
512+
*bytes = c.bytes;
513+
*packets = c.packets;
514+
*lastuse = c.lastuse;
515+
}
516+
507517
void mlx5_fc_queue_stats_work(struct mlx5_core_dev *dev,
508518
struct delayed_work *dwork,
509519
unsigned long delay)

include/linux/mlx5/fs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,8 @@ void mlx5_fc_destroy(struct mlx5_core_dev *dev, struct mlx5_fc *counter);
296296
u64 mlx5_fc_query_lastuse(struct mlx5_fc *counter);
297297
void mlx5_fc_query_cached(struct mlx5_fc *counter,
298298
u64 *bytes, u64 *packets, u64 *lastuse);
299+
void mlx5_fc_query_cached_raw(struct mlx5_fc *counter,
300+
u64 *bytes, u64 *packets, u64 *lastuse);
299301
int mlx5_fc_query(struct mlx5_core_dev *dev, struct mlx5_fc *counter,
300302
u64 *packets, u64 *bytes);
301303
u32 mlx5_fc_id(struct mlx5_fc *counter);

0 commit comments

Comments
 (0)