Skip to content

Commit 44f8658

Browse files
jpirkodavem330
authored andcommitted
sched: act: allow user to specify type of HW stats for a filter
Currently, user who is adding an action expects HW to report stats, however it does not have exact expectations about the stats types. That is aligned with TCA_ACT_HW_STATS_TYPE_ANY. Allow user to specify the type of HW stats for an action and require it. Pass the information down to flow_offload layer. Signed-off-by: Jiri Pirko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d7cb1e3 commit 44f8658

File tree

4 files changed

+69
-0
lines changed

4 files changed

+69
-0
lines changed

include/net/act_api.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ struct tc_action {
4141
struct tc_cookie __rcu *act_cookie;
4242
struct tcf_chain __rcu *goto_chain;
4343
u32 tcfa_flags;
44+
u8 hw_stats_type;
4445
};
4546
#define tcf_index common.tcfa_index
4647
#define tcf_refcnt common.tcfa_refcnt
@@ -52,6 +53,9 @@ struct tc_action {
5253
#define tcf_rate_est common.tcfa_rate_est
5354
#define tcf_lock common.tcfa_lock
5455

56+
#define TCA_ACT_HW_STATS_TYPE_ANY (TCA_ACT_HW_STATS_TYPE_IMMEDIATE | \
57+
TCA_ACT_HW_STATS_TYPE_DELAYED)
58+
5559
/* Update lastuse only if needed, to avoid dirtying a cache line.
5660
* We use a temp variable to avoid fetching jiffies twice.
5761
*/

include/uapi/linux/pkt_cls.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,35 @@ enum {
1717
TCA_ACT_PAD,
1818
TCA_ACT_COOKIE,
1919
TCA_ACT_FLAGS,
20+
TCA_ACT_HW_STATS_TYPE,
2021
__TCA_ACT_MAX
2122
};
2223

2324
#define TCA_ACT_FLAGS_NO_PERCPU_STATS 1 /* Don't use percpu allocator for
2425
* actions stats.
2526
*/
2627

28+
/* tca HW stats type
29+
* When user does not pass the attribute, he does not care.
30+
* It is the same as if he would pass the attribute with
31+
* all supported bits set.
32+
* In case no bits are set, user is not interested in getting any HW statistics.
33+
*/
34+
#define TCA_ACT_HW_STATS_TYPE_IMMEDIATE (1 << 0) /* Means that in dump, user
35+
* gets the current HW stats
36+
* state from the device
37+
* queried at the dump time.
38+
*/
39+
#define TCA_ACT_HW_STATS_TYPE_DELAYED (1 << 1) /* Means that in dump, user gets
40+
* HW stats that might be out
41+
* of date for some time, maybe
42+
* couple of seconds. This is
43+
* the case when driver polls
44+
* stats updates periodically
45+
* or when it gets async stats update
46+
* from the device.
47+
*/
48+
2749
#define TCA_ACT_MAX __TCA_ACT_MAX
2850
#define TCA_OLD_COMPAT (TCA_ACT_MAX+1)
2951
#define TCA_ACT_MAX_PRIO 32

net/sched/act_api.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ static size_t tcf_action_shared_attrs_size(const struct tc_action *act)
185185
return nla_total_size(0) /* action number nested */
186186
+ nla_total_size(IFNAMSIZ) /* TCA_ACT_KIND */
187187
+ cookie_len /* TCA_ACT_COOKIE */
188+
+ nla_total_size(sizeof(struct nla_bitfield32)) /* TCA_ACT_HW_STATS_TYPE */
188189
+ nla_total_size(0) /* TCA_ACT_STATS nested */
189190
+ nla_total_size(sizeof(struct nla_bitfield32)) /* TCA_ACT_FLAGS */
190191
/* TCA_STATS_BASIC */
@@ -788,6 +789,17 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
788789
}
789790
rcu_read_unlock();
790791

792+
if (a->hw_stats_type != TCA_ACT_HW_STATS_TYPE_ANY) {
793+
struct nla_bitfield32 hw_stats_type = {
794+
a->hw_stats_type,
795+
TCA_ACT_HW_STATS_TYPE_ANY,
796+
};
797+
798+
if (nla_put(skb, TCA_ACT_HW_STATS_TYPE, sizeof(hw_stats_type),
799+
&hw_stats_type))
800+
goto nla_put_failure;
801+
}
802+
791803
if (a->tcfa_flags) {
792804
struct nla_bitfield32 flags = { a->tcfa_flags,
793805
a->tcfa_flags, };
@@ -854,7 +866,23 @@ static struct tc_cookie *nla_memdup_cookie(struct nlattr **tb)
854866
return c;
855867
}
856868

869+
static u8 tcf_action_hw_stats_type_get(struct nlattr *hw_stats_type_attr)
870+
{
871+
struct nla_bitfield32 hw_stats_type_bf;
872+
873+
/* If the user did not pass the attr, that means he does
874+
* not care about the type. Return "any" in that case
875+
* which is setting on all supported types.
876+
*/
877+
if (!hw_stats_type_attr)
878+
return TCA_ACT_HW_STATS_TYPE_ANY;
879+
hw_stats_type_bf = nla_get_bitfield32(hw_stats_type_attr);
880+
return hw_stats_type_bf.value;
881+
}
882+
857883
static const u32 tca_act_flags_allowed = TCA_ACT_FLAGS_NO_PERCPU_STATS;
884+
static const u32 tca_act_hw_stats_type_allowed = TCA_ACT_HW_STATS_TYPE_ANY;
885+
858886
static const struct nla_policy tcf_action_policy[TCA_ACT_MAX + 1] = {
859887
[TCA_ACT_KIND] = { .type = NLA_STRING },
860888
[TCA_ACT_INDEX] = { .type = NLA_U32 },
@@ -863,6 +891,8 @@ static const struct nla_policy tcf_action_policy[TCA_ACT_MAX + 1] = {
863891
[TCA_ACT_OPTIONS] = { .type = NLA_NESTED },
864892
[TCA_ACT_FLAGS] = { .type = NLA_BITFIELD32,
865893
.validation_data = &tca_act_flags_allowed },
894+
[TCA_ACT_HW_STATS_TYPE] = { .type = NLA_BITFIELD32,
895+
.validation_data = &tca_act_hw_stats_type_allowed },
866896
};
867897

868898
struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
@@ -871,6 +901,7 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
871901
bool rtnl_held,
872902
struct netlink_ext_ack *extack)
873903
{
904+
u8 hw_stats_type = TCA_ACT_HW_STATS_TYPE_ANY;
874905
struct nla_bitfield32 flags = { 0, 0 };
875906
struct tc_action *a;
876907
struct tc_action_ops *a_o;
@@ -903,6 +934,8 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
903934
goto err_out;
904935
}
905936
}
937+
hw_stats_type =
938+
tcf_action_hw_stats_type_get(tb[TCA_ACT_HW_STATS_TYPE]);
906939
if (tb[TCA_ACT_FLAGS])
907940
flags = nla_get_bitfield32(tb[TCA_ACT_FLAGS]);
908941
} else {
@@ -953,6 +986,9 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
953986
if (!name && tb[TCA_ACT_COOKIE])
954987
tcf_set_action_cookie(&a->act_cookie, cookie);
955988

989+
if (!name)
990+
a->hw_stats_type = hw_stats_type;
991+
956992
/* module count goes up only when brand new policy is created
957993
* if it exists and is only bound to in a_o->init() then
958994
* ACT_P_CREATED is not returned (a zero is).

net/sched/cls_api.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3464,6 +3464,10 @@ int tc_setup_flow_action(struct flow_action *flow_action,
34643464
struct tc_action *act;
34653465
int i, j, k, err = 0;
34663466

3467+
BUILD_BUG_ON(TCA_ACT_HW_STATS_TYPE_ANY != FLOW_ACTION_HW_STATS_TYPE_ANY);
3468+
BUILD_BUG_ON(TCA_ACT_HW_STATS_TYPE_IMMEDIATE != FLOW_ACTION_HW_STATS_TYPE_IMMEDIATE);
3469+
BUILD_BUG_ON(TCA_ACT_HW_STATS_TYPE_DELAYED != FLOW_ACTION_HW_STATS_TYPE_DELAYED);
3470+
34673471
if (!exts)
34683472
return 0;
34693473

@@ -3476,6 +3480,9 @@ int tc_setup_flow_action(struct flow_action *flow_action,
34763480
err = tcf_act_get_cookie(entry, act);
34773481
if (err)
34783482
goto err_out_locked;
3483+
3484+
entry->hw_stats_type = act->hw_stats_type;
3485+
34793486
if (is_tcf_gact_ok(act)) {
34803487
entry->id = FLOW_ACTION_ACCEPT;
34813488
} else if (is_tcf_gact_shot(act)) {

0 commit comments

Comments
 (0)