summaryrefslogtreecommitdiff
path: root/include/net
diff options
context:
space:
mode:
authorOz Shlomo <ozsh@nvidia.com>2023-02-12 15:25:16 +0200
committerPaolo Abeni <pabeni@redhat.com>2023-02-14 11:00:01 +0100
commit5246c896b805b043a87fa78af32a33cbce00de05 (patch)
treed1379fb49b03d0742df7459fad1e02502e6d236c /include/net
parentd307b2c6f962ad5d83d7a7df71c2e9c9e4106d82 (diff)
net/sched: support per action hw stats
There are currently two mechanisms for populating hardware stats: 1. Using flow_offload api to query the flow's statistics. The api assumes that the same stats values apply to all the flow's actions. This assumption breaks when action drops or jumps over following actions. 2. Using hw_action api to query specific action stats via a driver callback method. This api assures the correct action stats for the offloaded action, however, it does not apply to the rest of the actions in the flow's actions array. Extend the flow_offload stats callback to indicate that a per action stats update is required. Use the existing flow_offload_action api to query the action's hw stats. In addition, currently the tc action stats utility only updates hw actions. Reuse the existing action stats cb infrastructure to query any action stats. Signed-off-by: Oz Shlomo <ozsh@nvidia.com> Reviewed-by: Simon Horman <simon.horman@corigine.com> Reviewed-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'include/net')
-rw-r--r--include/net/flow_offload.h1
-rw-r--r--include/net/pkt_cls.h29
2 files changed, 20 insertions, 10 deletions
diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h
index d177bf5f0e1a..8c05455b1e34 100644
--- a/include/net/flow_offload.h
+++ b/include/net/flow_offload.h
@@ -594,6 +594,7 @@ struct flow_cls_common_offload {
struct flow_cls_offload {
struct flow_cls_common_offload common;
enum flow_cls_command command;
+ bool use_act_stats;
unsigned long cookie;
struct flow_rule *rule;
struct flow_stats stats;
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index bf50829d9255..ace437c6754b 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -292,9 +292,15 @@ static inline void tcf_exts_put_net(struct tcf_exts *exts)
#define tcf_act_for_each_action(i, a, actions) \
for (i = 0; i < TCA_ACT_MAX_PRIO && ((a) = actions[i]); i++)
+static inline bool tc_act_in_hw(struct tc_action *act)
+{
+ return !!act->in_hw_count;
+}
+
static inline void
tcf_exts_hw_stats_update(const struct tcf_exts *exts,
- struct flow_stats *stats)
+ struct flow_stats *stats,
+ bool use_act_stats)
{
#ifdef CONFIG_NET_CLS_ACT
int i;
@@ -302,16 +308,18 @@ tcf_exts_hw_stats_update(const struct tcf_exts *exts,
for (i = 0; i < exts->nr_actions; i++) {
struct tc_action *a = exts->actions[i];
- /* if stats from hw, just skip */
- if (tcf_action_update_hw_stats(a)) {
- preempt_disable();
- tcf_action_stats_update(a, stats->bytes, stats->pkts, stats->drops,
- stats->lastused, true);
- preempt_enable();
-
- a->used_hw_stats = stats->used_hw_stats;
- a->used_hw_stats_valid = stats->used_hw_stats_valid;
+ if (use_act_stats || tc_act_in_hw(a)) {
+ if (!tcf_action_update_hw_stats(a))
+ continue;
}
+
+ preempt_disable();
+ tcf_action_stats_update(a, stats->bytes, stats->pkts, stats->drops,
+ stats->lastused, true);
+ preempt_enable();
+
+ a->used_hw_stats = stats->used_hw_stats;
+ a->used_hw_stats_valid = stats->used_hw_stats_valid;
}
#endif
}
@@ -769,6 +777,7 @@ struct tc_cls_matchall_offload {
enum tc_matchall_command command;
struct flow_rule *rule;
struct flow_stats stats;
+ bool use_act_stats;
unsigned long cookie;
};