net_sched: add TCA_STATS_PKT64 attribute
authorEric Dumazet <edumazet@google.com>
Tue, 5 Nov 2019 03:13:15 +0000 (19:13 -0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 6 Nov 2019 02:20:55 +0000 (18:20 -0800)
Now the kernel uses 64bit packet counters in scheduler layer,
we want to export these counters to user space.

Instead risking breaking user space by adding fields
to struct gnet_stats_basic, add a new TCA_STATS_PKT64.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/uapi/linux/gen_stats.h
net/core/gen_stats.c
net/sched/act_api.c

index 4eaacdf452e3b34f8f813046b801bfc1e6bdd2d4..852f234f1fd634b5d4d5444fc8e2f2e45c4f0839 100644 (file)
@@ -13,6 +13,7 @@ enum {
        TCA_STATS_RATE_EST64,
        TCA_STATS_PAD,
        TCA_STATS_BASIC_HW,
+       TCA_STATS_PKT64,
        __TCA_STATS_MAX,
 };
 #define TCA_STATS_MAX (__TCA_STATS_MAX - 1)
index fe33e2a9841e698dc1a0ac086086fa9832c0b514..1d653fbfcf52a95f0c8acdeb1ce1b0b418177351 100644 (file)
@@ -175,12 +175,17 @@ ___gnet_stats_copy_basic(const seqcount_t *running,
 
        if (d->tail) {
                struct gnet_stats_basic sb;
+               int res;
 
                memset(&sb, 0, sizeof(sb));
                sb.bytes = bstats.bytes;
                sb.packets = bstats.packets;
-               return gnet_stats_copy(d, type, &sb, sizeof(sb),
-                                      TCA_STATS_PAD);
+               res = gnet_stats_copy(d, type, &sb, sizeof(sb), TCA_STATS_PAD);
+               if (res < 0 || sb.packets == bstats.packets)
+                       return res;
+               /* emit 64bit stats only if needed */
+               return gnet_stats_copy(d, TCA_STATS_PKT64, &bstats.packets,
+                                      sizeof(bstats.packets), TCA_STATS_PAD);
        }
        return 0;
 }
index 6284c552e943d1ffa45d59a28eac2c37152e4875..bda1ba25c59e973709998b7e6279eee30589cbb8 100644 (file)
@@ -188,6 +188,8 @@ static size_t tcf_action_shared_attrs_size(const struct tc_action *act)
                + nla_total_size(0) /* TCA_ACT_STATS nested */
                /* TCA_STATS_BASIC */
                + nla_total_size_64bit(sizeof(struct gnet_stats_basic))
+               /* TCA_STATS_PKT64 */
+               + nla_total_size_64bit(sizeof(u64))
                /* TCA_STATS_QUEUE */
                + nla_total_size_64bit(sizeof(struct gnet_stats_queue))
                + nla_total_size(0) /* TCA_OPTIONS nested */