diff options
Diffstat (limited to 'net/sched')
-rw-r--r-- | net/sched/act_api.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/net/sched/act_api.c b/net/sched/act_api.c index d446e89ececc..f9186f283488 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -246,6 +246,37 @@ fl_err: return err; } +int tcf_action_update_hw_stats(struct tc_action *action) +{ + struct flow_offload_action fl_act = {}; + int err; + + if (!tc_act_in_hw(action)) + return -EOPNOTSUPP; + + err = offload_action_init(&fl_act, action, FLOW_ACT_STATS, NULL); + if (err) + return err; + + err = tcf_action_offload_cmd(&fl_act, NULL, NULL); + if (!err) { + preempt_disable(); + tcf_action_stats_update(action, fl_act.stats.bytes, + fl_act.stats.pkts, + fl_act.stats.drops, + fl_act.stats.lastused, + true); + preempt_enable(); + action->used_hw_stats = fl_act.stats.used_hw_stats; + action->used_hw_stats_valid = true; + } else { + return -EOPNOTSUPP; + } + + return 0; +} +EXPORT_SYMBOL(tcf_action_update_hw_stats); + static int tcf_action_offload_del(struct tc_action *action) { struct flow_offload_action fl_act = {}; @@ -1318,6 +1349,9 @@ int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *p, if (p == NULL) goto errout; + /* update hw stats for this action */ + tcf_action_update_hw_stats(p); + /* compat_mode being true specifies a call that is supposed * to add additional backward compatibility statistic TLVs. */ |