net: sched: modify stats helper functions to support regular stats
authorVlad Buslov <vladbu@mellanox.com>
Wed, 30 Oct 2019 14:09:04 +0000 (16:09 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 31 Oct 2019 01:07:50 +0000 (18:07 -0700)
Modify stats update helper functions introduced in previous patches in this
series to fallback to regular tc_action->tcfa_{b|q}stats if cpu stats are
not allocated for the action argument. If regular non-percpu allocated
counters are in use, then obtain action tcfa_lock while modifying them.

Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/act_api.h
net/sched/act_api.c

index 8d6861ce205bc15b8e2b90ae6bf120dbfd94d40e..a56477051dae55d4c37752365dd83d428a148cbb 100644 (file)
@@ -190,23 +190,35 @@ int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int);
 static inline void tcf_action_update_bstats(struct tc_action *a,
                                            struct sk_buff *skb)
 {
-       bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), skb);
-}
-
-static inline struct gnet_stats_queue *
-tcf_action_get_qstats(struct tc_action *a)
-{
-       return this_cpu_ptr(a->cpu_qstats);
+       if (likely(a->cpu_bstats)) {
+               bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), skb);
+               return;
+       }
+       spin_lock(&a->tcfa_lock);
+       bstats_update(&a->tcfa_bstats, skb);
+       spin_unlock(&a->tcfa_lock);
 }
 
 static inline void tcf_action_inc_drop_qstats(struct tc_action *a)
 {
-       qstats_drop_inc(this_cpu_ptr(a->cpu_qstats));
+       if (likely(a->cpu_qstats)) {
+               qstats_drop_inc(this_cpu_ptr(a->cpu_qstats));
+               return;
+       }
+       spin_lock(&a->tcfa_lock);
+       qstats_drop_inc(&a->tcfa_qstats);
+       spin_unlock(&a->tcfa_lock);
 }
 
 static inline void tcf_action_inc_overlimit_qstats(struct tc_action *a)
 {
-       qstats_overlimit_inc(this_cpu_ptr(a->cpu_qstats));
+       if (likely(a->cpu_qstats)) {
+               qstats_overlimit_inc(this_cpu_ptr(a->cpu_qstats));
+               return;
+       }
+       spin_lock(&a->tcfa_lock);
+       qstats_overlimit_inc(&a->tcfa_qstats);
+       spin_unlock(&a->tcfa_lock);
 }
 
 void tcf_action_update_stats(struct tc_action *a, u64 bytes, u32 packets,
index 0638afa2fc3f2e01aedc712bc0d0233a61b4bbd4..f85b88da5216e59138779b6085eb073e5b29d58b 100644 (file)
@@ -992,14 +992,23 @@ err:
 void tcf_action_update_stats(struct tc_action *a, u64 bytes, u32 packets,
                             bool drop, bool hw)
 {
-       _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), bytes, packets);
+       if (a->cpu_bstats) {
+               _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), bytes, packets);
 
-       if (drop)
-               this_cpu_ptr(a->cpu_qstats)->drops += packets;
+               if (drop)
+                       this_cpu_ptr(a->cpu_qstats)->drops += packets;
+
+               if (hw)
+                       _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats_hw),
+                                          bytes, packets);
+               return;
+       }
 
+       _bstats_update(&a->tcfa_bstats, bytes, packets);
+       if (drop)
+               a->tcfa_qstats.drops += packets;
        if (hw)
-               _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats_hw),
-                                  bytes, packets);
+               _bstats_update(&a->tcfa_bstats_hw, bytes, packets);
 }
 EXPORT_SYMBOL(tcf_action_update_stats);