* [RFC PATCH v4 net-next 0/4] flow_offload: Re-add per-action statistics
@ 2019-06-04 17:32 Edward Cree
2019-06-04 17:34 ` [RFC PATCH v4 net-next 1/4] flow_offload: add a cookie to flow_action_entry Edward Cree
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Edward Cree @ 2019-06-04 17:32 UTC (permalink / raw)
To: Jamal Hadi Salim, Jiri Pirko, Pablo Neira Ayuso, David Miller
Cc: netdev, Cong Wang, Andy Gospodarek, Jakub Kicinski, Michael Chan,
Vishal Kulkarni, Or Gerlitz
When the flow_offload infrastructure was added, per-action statistics,
which were previously possible for drivers to support in TC offload,
were not plumbed through, perhaps because the drivers in the tree did
not implement them.
In TC (and in the previous offload API) statistics are per-action,
though generally only on 'delivery' actions like mirred, ok and shot.
Actions also have an index, which may be supplied by the user, which
allows the sharing of entities such as counters between multiple rules.
The existing driver implementations did not support this, however,
instead allocating a single counter per rule. The flow_offload API did
not support this either, as (a) the information that two actions were
actually the same action never reached the driver, and (b) the
TC_CLSFLOWER_STATS callback is only able to return a single set of
stats, which are added to all counters for actions on the rule.
Patch #1 of this series fixes (a) by adding a cookie member to struct
flow_action_entry, while the remaining patches fix (b) by adding a per-
action offload callback (TC_SETUP_ACTION/TC_ACTION_STATS) for
RTM_GETACTION, and also (patch #4) calling it for each action when
dumping a rule.
For drivers supporting per-action stats (of which none yet exist
upstream, hence RFC), this also means that RTM_GETACTION will return
up-to-date stats, rather than stale values from the last time the rule
was dumped.
Changed in v4:
* Incorporated RTM_GETACTION offload series
* Replaced TC_CLSFLOWER_STATS stats-array with multiple TC_SETUP_ACTION
callbacks
* dropped header inclusion fix (submitted separately)
* re-added RFC tags
Changed in v3:
* replaced action_index with cookie, so drivers don't have to look at
flow_action_id to distinguish shared actions
* removed RFC tags
Changed in v2:
* use array instead of new callback for getting stats
* remove CVLAN patch (posted separately for net)
* add header inclusion fix
Edward Cree (4):
flow_offload: add a cookie to flow_action_entry
net/sched: add callback to get stats on an action from clsflower
offload
net/sched: add action block binding to other classifiers
net/sched: call action stats offload in flower or mall dump
include/linux/netdevice.h | 1 +
include/net/act_api.h | 7 +++++-
include/net/flow_offload.h | 2 ++
include/net/pkt_cls.h | 18 ++++++++++++++
net/sched/act_api.c | 51 ++++++++++++++++++++++++++++++++++++++
net/sched/cls_api.c | 2 ++
net/sched/cls_bpf.c | 10 +++++++-
net/sched/cls_flower.c | 13 ++++++++++
net/sched/cls_matchall.c | 12 +++++++++
net/sched/cls_u32.c | 7 ++++++
10 files changed, 121 insertions(+), 2 deletions(-)
^ permalink raw reply [flat|nested] 5+ messages in thread
* [RFC PATCH v4 net-next 1/4] flow_offload: add a cookie to flow_action_entry
2019-06-04 17:32 [RFC PATCH v4 net-next 0/4] flow_offload: Re-add per-action statistics Edward Cree
@ 2019-06-04 17:34 ` Edward Cree
2019-06-04 17:34 ` [RFC PATCH v4 net-next 2/4] net/sched: add callback to get stats on an action from clsflower offload Edward Cree
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Edward Cree @ 2019-06-04 17:34 UTC (permalink / raw)
To: Jamal Hadi Salim, Jiri Pirko, Pablo Neira Ayuso, David Miller
Cc: netdev, Cong Wang, Andy Gospodarek, Jakub Kicinski, Michael Chan,
Vishal Kulkarni, Or Gerlitz
Populated with the address of the struct tc_action from which it was made.
Required for support of shared counters (and possibly other shared per-
action entities in future).
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
include/net/flow_offload.h | 1 +
net/sched/cls_api.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h
index 36fdb85c974d..d526696958f6 100644
--- a/include/net/flow_offload.h
+++ b/include/net/flow_offload.h
@@ -140,6 +140,7 @@ enum flow_action_mangle_base {
struct flow_action_entry {
enum flow_action_id id;
+ unsigned long cookie;
union {
u32 chain_index; /* FLOW_ACTION_GOTO */
struct net_device *dev; /* FLOW_ACTION_REDIRECT */
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index d4699156974a..5411cec17af5 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -3195,6 +3195,7 @@ int tc_setup_flow_action(struct flow_action *flow_action,
struct flow_action_entry *entry;
entry = &flow_action->entries[j];
+ entry->cookie = (unsigned long)act;
if (is_tcf_gact_ok(act)) {
entry->id = FLOW_ACTION_ACCEPT;
} else if (is_tcf_gact_shot(act)) {
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [RFC PATCH v4 net-next 2/4] net/sched: add callback to get stats on an action from clsflower offload
2019-06-04 17:32 [RFC PATCH v4 net-next 0/4] flow_offload: Re-add per-action statistics Edward Cree
2019-06-04 17:34 ` [RFC PATCH v4 net-next 1/4] flow_offload: add a cookie to flow_action_entry Edward Cree
@ 2019-06-04 17:34 ` Edward Cree
2019-06-04 17:34 ` [RFC PATCH v4 net-next 3/4] net/sched: add action block binding to other classifiers Edward Cree
2019-06-04 17:34 ` [RFC PATCH v4 net-next 4/4] net/sched: call action stats offload in flower or mall dump Edward Cree
3 siblings, 0 replies; 5+ messages in thread
From: Edward Cree @ 2019-06-04 17:34 UTC (permalink / raw)
To: Jamal Hadi Salim, Jiri Pirko, Pablo Neira Ayuso, David Miller
Cc: netdev, Cong Wang, Andy Gospodarek, Jakub Kicinski, Michael Chan,
Vishal Kulkarni, Or Gerlitz
When handling RTM_GETACTION (e.g. tc actions get/list), make a callback to
blocks with hardware offload of the action to update stats from hardware.
In order to support this, track each action/block binding by allocating a
struct tc_action_block_binding and adding it to a list on the action.
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
include/linux/netdevice.h | 1 +
include/net/act_api.h | 2 +-
include/net/pkt_cls.h | 18 ++++++++++++++
net/sched/act_api.c | 50 +++++++++++++++++++++++++++++++++++++++
net/sched/cls_flower.c | 7 ++++++
5 files changed, 77 insertions(+), 1 deletion(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 44b47e9df94a..dee84954a1c7 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -849,6 +849,7 @@ enum tc_setup_type {
TC_SETUP_QDISC_ETF,
TC_SETUP_ROOT_QDISC,
TC_SETUP_QDISC_GRED,
+ TC_SETUP_ACTION,
};
/* These structures hold the attributes of bpf state that are being passed
diff --git a/include/net/act_api.h b/include/net/act_api.h
index c61a1bf4e3de..38d1769f279b 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -40,6 +40,7 @@ struct tc_action {
struct gnet_stats_queue __percpu *cpu_qstats;
struct tc_cookie __rcu *act_cookie;
struct tcf_chain __rcu *goto_chain;
+ struct list_head hw_blocks;
};
#define tcf_index common.tcfa_index
#define tcf_refcnt common.tcfa_refcnt
@@ -199,5 +200,4 @@ static inline void tcf_action_stats_update(struct tc_action *a, u64 bytes,
#endif
}
-
#endif
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 514e3c80ecc1..880048879904 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -342,6 +342,14 @@ static inline void tcf_exts_put_net(struct tcf_exts *exts)
for (; 0; (void)(i), (void)(a), (void)(exts))
#endif
+struct tc_action_block_binding {
+ struct list_head list;
+ struct tcf_block *block;
+};
+
+void tc_bind_action_blocks(struct tcf_exts *exts, struct tcf_block *block);
+void tc_unbind_action_blocks(struct tcf_exts *exts, struct tcf_block *block);
+
static inline void
tcf_exts_stats_update(const struct tcf_exts *exts,
u64 bytes, u64 packets, u64 lastuse)
@@ -953,4 +961,14 @@ struct tc_root_qopt_offload {
bool ingress;
};
+enum tc_action_command {
+ TC_ACTION_STATS,
+};
+
+struct tc_action_offload {
+ enum tc_action_command command;
+ unsigned long cookie;
+ struct flow_stats stats;
+};
+
#endif
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index c42ecf4b3c10..239fc28456d9 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -427,6 +427,7 @@ int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
goto err3;
}
spin_lock_init(&p->tcfa_lock);
+ INIT_LIST_HEAD(&p->hw_blocks);
p->tcfa_index = index;
p->tcfa_tm.install = jiffies;
p->tcfa_tm.lastuse = jiffies;
@@ -753,6 +754,20 @@ tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
return a->ops->dump(skb, a, bind, ref);
}
+static void tcf_action_update_stats(struct tc_action *a)
+{
+ struct tc_action_block_binding *bind;
+ struct tc_action_offload offl = {};
+
+ offl.command = TC_ACTION_STATS;
+ offl.cookie = (unsigned long)a;
+ ASSERT_RTNL();
+ list_for_each_entry(bind, &a->hw_blocks, list)
+ tc_setup_cb_call(bind->block, TC_SETUP_ACTION, &offl, false);
+ tcf_action_stats_update(a, offl.stats.bytes, offl.stats.pkts,
+ offl.stats.lastused, true);
+}
+
int
tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
{
@@ -763,6 +778,7 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
if (nla_put_string(skb, TCA_KIND, a->ops->kind))
goto nla_put_failure;
+ tcf_action_update_stats(a);
if (tcf_action_copy_stats(skb, a, 0))
goto nla_put_failure;
@@ -1538,6 +1554,40 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
return skb->len;
}
+/** Add a binding for %block to hw_blocks list of each action in %exts */
+void tc_bind_action_blocks(struct tcf_exts *exts, struct tcf_block *block)
+{
+ struct tc_action_block_binding *bind;
+ struct tc_action *act;
+ int i;
+
+ tcf_exts_for_each_action(i, act, exts) {
+ bind = kzalloc(sizeof(*bind), GFP_KERNEL);
+ if (WARN_ON_ONCE(!bind))
+ continue; /* just skip it, stats won't update timely */
+ bind->block = block;
+ list_add_tail(&bind->list, &act->hw_blocks);
+ }
+}
+EXPORT_SYMBOL(tc_bind_action_blocks);
+
+/** Remove one instance of %block from binding list of each action in %exts */
+void tc_unbind_action_blocks(struct tcf_exts *exts, struct tcf_block *block)
+{
+ struct tc_action_block_binding *bind;
+ struct tc_action *act;
+ int i;
+
+ tcf_exts_for_each_action(i, act, exts)
+ list_for_each_entry(bind, &act->hw_blocks, list)
+ if (bind->block == block) {
+ list_del(&bind->list);
+ kfree(bind);
+ break;
+ }
+}
+EXPORT_SYMBOL(tc_unbind_action_blocks);
+
static int __init tc_action_init(void)
{
rtnl_register(PF_UNSPEC, RTM_NEWACTION, tc_ctl_action, NULL, 0);
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index f6685fc53119..252d102702bb 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -394,6 +394,8 @@ static void fl_hw_destroy_filter(struct tcf_proto *tp, struct cls_fl_filter *f,
cls_flower.cookie = (unsigned long) f;
tc_setup_cb_call(block, TC_SETUP_CLSFLOWER, &cls_flower, false);
+ if (f->in_hw_count)
+ tc_unbind_action_blocks(&f->exts, block);
spin_lock(&tp->lock);
list_del_init(&f->hw_list);
tcf_block_offload_dec(block, &f->flags);
@@ -448,6 +450,7 @@ static int fl_hw_replace_filter(struct tcf_proto *tp,
goto errout;
} else if (err > 0) {
f->in_hw_count = err;
+ tc_bind_action_blocks(&f->exts, block);
err = 0;
spin_lock(&tp->lock);
tcf_block_offload_inc(block, &f->flags);
@@ -1789,10 +1792,14 @@ static int fl_reoffload(struct tcf_proto *tp, bool add, tc_setup_cb_t *cb,
goto next_flow;
}
+ if (add && !f->in_hw_count)
+ tc_bind_action_blocks(&f->exts, block);
spin_lock(&tp->lock);
tc_cls_offload_cnt_update(block, &f->in_hw_count, &f->flags,
add);
spin_unlock(&tp->lock);
+ if (!add && !f->in_hw_count)
+ tc_unbind_action_blocks(&f->exts, block);
next_flow:
__fl_put(f);
}
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [RFC PATCH v4 net-next 3/4] net/sched: add action block binding to other classifiers
2019-06-04 17:32 [RFC PATCH v4 net-next 0/4] flow_offload: Re-add per-action statistics Edward Cree
2019-06-04 17:34 ` [RFC PATCH v4 net-next 1/4] flow_offload: add a cookie to flow_action_entry Edward Cree
2019-06-04 17:34 ` [RFC PATCH v4 net-next 2/4] net/sched: add callback to get stats on an action from clsflower offload Edward Cree
@ 2019-06-04 17:34 ` Edward Cree
2019-06-04 17:34 ` [RFC PATCH v4 net-next 4/4] net/sched: call action stats offload in flower or mall dump Edward Cree
3 siblings, 0 replies; 5+ messages in thread
From: Edward Cree @ 2019-06-04 17:34 UTC (permalink / raw)
To: Jamal Hadi Salim, Jiri Pirko, Pablo Neira Ayuso, David Miller
Cc: netdev, Cong Wang, Andy Gospodarek, Jakub Kicinski, Michael Chan,
Vishal Kulkarni, Or Gerlitz
cls_matchall, cls_u32, and cls_bpf all have offloads as well, so they also
need to bind actions to blocks for RTM_GETACTION stats collection.
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
net/sched/cls_bpf.c | 10 +++++++++-
net/sched/cls_matchall.c | 7 +++++++
net/sched/cls_u32.c | 7 +++++++
3 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c
index 27365ed3fe0b..c99e53cbf83d 100644
--- a/net/sched/cls_bpf.c
+++ b/net/sched/cls_bpf.c
@@ -165,8 +165,11 @@ static int cls_bpf_offload_cmd(struct tcf_proto *tp, struct cls_bpf_prog *prog,
cls_bpf.name = obj->bpf_name;
cls_bpf.exts_integrated = obj->exts_integrated;
- if (oldprog)
+ if (oldprog) {
+ if (oldprog->in_hw_count)
+ tc_unbind_action_blocks(&oldprog->exts, block);
tcf_block_offload_dec(block, &oldprog->gen_flags);
+ }
err = tc_setup_cb_call(block, TC_SETUP_CLSBPF, &cls_bpf, skip_sw);
if (prog) {
@@ -175,6 +178,7 @@ static int cls_bpf_offload_cmd(struct tcf_proto *tp, struct cls_bpf_prog *prog,
return err;
} else if (err > 0) {
prog->in_hw_count = err;
+ tc_bind_action_blocks(&prog->exts, block);
tcf_block_offload_inc(block, &prog->gen_flags);
}
}
@@ -683,8 +687,12 @@ static int cls_bpf_reoffload(struct tcf_proto *tp, bool add, tc_setup_cb_t *cb,
continue;
}
+ if (add && !prog->in_hw_count)
+ tc_bind_action_blocks(&prog->exts, block);
tc_cls_offload_cnt_update(block, &prog->in_hw_count,
&prog->gen_flags, add);
+ if (!add && !prog->in_hw_count)
+ tc_unbind_action_blocks(&prog->exts, block);
}
return 0;
diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c
index db42d97a2006..5cb4832d1b3b 100644
--- a/net/sched/cls_matchall.c
+++ b/net/sched/cls_matchall.c
@@ -79,6 +79,8 @@ static void mall_destroy_hw_filter(struct tcf_proto *tp,
cls_mall.cookie = cookie;
tc_setup_cb_call(block, TC_SETUP_CLSMATCHALL, &cls_mall, false);
+ if (head->in_hw_count)
+ tc_unbind_action_blocks(&head->exts, block);
tcf_block_offload_dec(block, &head->flags);
}
@@ -120,6 +122,7 @@ static int mall_replace_hw_filter(struct tcf_proto *tp,
return err;
} else if (err > 0) {
head->in_hw_count = err;
+ tc_bind_action_blocks(&head->exts, block);
tcf_block_offload_inc(block, &head->flags);
}
@@ -320,7 +323,11 @@ static int mall_reoffload(struct tcf_proto *tp, bool add, tc_setup_cb_t *cb,
return 0;
}
+ if (add && !head->in_hw_count)
+ tc_bind_action_blocks(&head->exts, block);
tc_cls_offload_cnt_update(block, &head->in_hw_count, &head->flags, add);
+ if (!add && !head->in_hw_count)
+ tc_unbind_action_blocks(&head->exts, block);
return 0;
}
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 4b8710a266cc..84f067d9b4a4 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -534,6 +534,8 @@ static void u32_remove_hw_knode(struct tcf_proto *tp, struct tc_u_knode *n,
cls_u32.knode.handle = n->handle;
tc_setup_cb_call(block, TC_SETUP_CLSU32, &cls_u32, false);
+ if (n->in_hw_count)
+ tc_unbind_action_blocks(&n->exts, block);
tcf_block_offload_dec(block, &n->flags);
}
@@ -569,6 +571,7 @@ static int u32_replace_hw_knode(struct tcf_proto *tp, struct tc_u_knode *n,
return err;
} else if (err > 0) {
n->in_hw_count = err;
+ tc_bind_action_blocks(&n->exts, block);
tcf_block_offload_inc(block, &n->flags);
}
@@ -1223,7 +1226,11 @@ static int u32_reoffload_knode(struct tcf_proto *tp, struct tc_u_knode *n,
return 0;
}
+ if (add && !n->in_hw_count)
+ tc_bind_action_blocks(&n->exts, block);
tc_cls_offload_cnt_update(block, &n->in_hw_count, &n->flags, add);
+ if (!add && !n->in_hw_count)
+ tc_unbind_action_blocks(&n->exts, block);
return 0;
}
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [RFC PATCH v4 net-next 4/4] net/sched: call action stats offload in flower or mall dump
2019-06-04 17:32 [RFC PATCH v4 net-next 0/4] flow_offload: Re-add per-action statistics Edward Cree
` (2 preceding siblings ...)
2019-06-04 17:34 ` [RFC PATCH v4 net-next 3/4] net/sched: add action block binding to other classifiers Edward Cree
@ 2019-06-04 17:34 ` Edward Cree
3 siblings, 0 replies; 5+ messages in thread
From: Edward Cree @ 2019-06-04 17:34 UTC (permalink / raw)
To: Jamal Hadi Salim, Jiri Pirko, Pablo Neira Ayuso, David Miller
Cc: netdev, Cong Wang, Andy Gospodarek, Jakub Kicinski, Michael Chan,
Vishal Kulkarni, Or Gerlitz
Drivers that support per-action stats should implement TC_ACTION_STATS
rather than TC_CLSFLOWER_STATS/TC_CLSMATCHALL_STATS.
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
include/net/act_api.h | 5 +++++
include/net/flow_offload.h | 1 +
net/sched/act_api.c | 3 ++-
net/sched/cls_api.c | 1 +
net/sched/cls_flower.c | 6 ++++++
net/sched/cls_matchall.c | 5 +++++
6 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/include/net/act_api.h b/include/net/act_api.h
index 38d1769f279b..76054524a2de 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -187,6 +187,11 @@ int tcf_action_check_ctrlact(int action, struct tcf_proto *tp,
struct netlink_ext_ack *newchain);
struct tcf_chain *tcf_action_set_ctrlact(struct tc_action *a, int action,
struct tcf_chain *newchain);
+void tcf_action_update_stats(struct tc_action *a);
+#else /* CONFIG_NET_CLS_ACT */
+static inline void tcf_action_update_stats(struct tc_action *a)
+{
+}
#endif /* CONFIG_NET_CLS_ACT */
static inline void tcf_action_stats_update(struct tc_action *a, u64 bytes,
diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h
index d526696958f6..813a91ae9d9a 100644
--- a/include/net/flow_offload.h
+++ b/include/net/flow_offload.h
@@ -140,6 +140,7 @@ enum flow_action_mangle_base {
struct flow_action_entry {
enum flow_action_id id;
+ bool want_stats;
unsigned long cookie;
union {
u32 chain_index; /* FLOW_ACTION_GOTO */
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 239fc28456d9..82f9c1f1acd6 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -754,7 +754,7 @@ tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
return a->ops->dump(skb, a, bind, ref);
}
-static void tcf_action_update_stats(struct tc_action *a)
+void tcf_action_update_stats(struct tc_action *a)
{
struct tc_action_block_binding *bind;
struct tc_action_offload offl = {};
@@ -767,6 +767,7 @@ static void tcf_action_update_stats(struct tc_action *a)
tcf_action_stats_update(a, offl.stats.bytes, offl.stats.pkts,
offl.stats.lastused, true);
}
+EXPORT_SYMBOL(tcf_action_update_stats);
int
tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 5411cec17af5..bb9b0d7ec1c0 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -3195,6 +3195,7 @@ int tc_setup_flow_action(struct flow_action *flow_action,
struct flow_action_entry *entry;
entry = &flow_action->entries[j];
+ entry->want_stats = act->ops && act->ops->stats_update;
entry->cookie = (unsigned long)act;
if (is_tcf_gact_ok(act)) {
entry->id = FLOW_ACTION_ACCEPT;
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 252d102702bb..fcd5615ca2bc 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -477,6 +477,8 @@ static void fl_hw_update_stats(struct tcf_proto *tp, struct cls_fl_filter *f,
{
struct tc_cls_flower_offload cls_flower = {};
struct tcf_block *block = tp->chain->block;
+ struct tc_action *act;
+ int i;
if (!rtnl_held)
rtnl_lock();
@@ -492,6 +494,10 @@ static void fl_hw_update_stats(struct tcf_proto *tp, struct cls_fl_filter *f,
cls_flower.stats.pkts,
cls_flower.stats.lastused);
+ tcf_exts_for_each_action(i, act, &f->exts)
+ if (act->ops && act->ops->stats_update)
+ tcf_action_update_stats(act);
+
if (!rtnl_held)
rtnl_unlock();
}
diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c
index 5cb4832d1b3b..c51beed83b1e 100644
--- a/net/sched/cls_matchall.c
+++ b/net/sched/cls_matchall.c
@@ -338,6 +338,8 @@ static void mall_stats_hw_filter(struct tcf_proto *tp,
{
struct tc_cls_matchall_offload cls_mall = {};
struct tcf_block *block = tp->chain->block;
+ struct tc_action *act;
+ int i;
tc_cls_common_offload_init(&cls_mall.common, tp, head->flags, NULL);
cls_mall.command = TC_CLSMATCHALL_STATS;
@@ -347,6 +349,9 @@ static void mall_stats_hw_filter(struct tcf_proto *tp,
tcf_exts_stats_update(&head->exts, cls_mall.stats.bytes,
cls_mall.stats.pkts, cls_mall.stats.lastused);
+ tcf_exts_for_each_action(i, act, &head->exts)
+ if (act->ops && act->ops->stats_update)
+ tcf_action_update_stats(act);
}
static int mall_dump(struct net *net, struct tcf_proto *tp, void *fh,
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2019-06-04 17:34 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-04 17:32 [RFC PATCH v4 net-next 0/4] flow_offload: Re-add per-action statistics Edward Cree
2019-06-04 17:34 ` [RFC PATCH v4 net-next 1/4] flow_offload: add a cookie to flow_action_entry Edward Cree
2019-06-04 17:34 ` [RFC PATCH v4 net-next 2/4] net/sched: add callback to get stats on an action from clsflower offload Edward Cree
2019-06-04 17:34 ` [RFC PATCH v4 net-next 3/4] net/sched: add action block binding to other classifiers Edward Cree
2019-06-04 17:34 ` [RFC PATCH v4 net-next 4/4] net/sched: call action stats offload in flower or mall dump Edward Cree
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).