diff mbox series

[net-next,2/2] net: sched: fix wrong class stats dumping in sch_mqprio

Message ID 20191217084718.52098-3-dust.li@linux.alibaba.com
State Changes Requested
Delegated to: David Miller
Headers show
Series net: sched: unify __gnet_stats_copy_xxx() for percpu and non-percpu | expand

Commit Message

Dust Li Dec. 17, 2019, 8:47 a.m. UTC
Actually, the stack variables bstats and qstats in
mqprio_dump_class_stats() are not really used. As a result,
'tc -s class show' for the mqprio class always return 0 for
both bstats and qstats.
This patch make them(bstats/qstats) storing the child qdisc's
stats, and add them up to a tbstats/tqstats which will store
the result mqprio class.

Fixes: ce679e8df7ed ("net: sched: add support for TCQ_F_NOLOCK subqueues to sch_mqprio")
Signed-off-by: Dust Li <dust.li@linux.alibaba.com>
Signed-off-by: Tony Lu <tonylu@linux.alibaba.com>
---
 net/sched/sch_mqprio.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c
index ce95e9b4a796..b356517c6ef4 100644
--- a/net/sched/sch_mqprio.c
+++ b/net/sched/sch_mqprio.c
@@ -511,8 +511,8 @@  static int mqprio_dump_class_stats(struct Qdisc *sch, unsigned long cl,
 	if (cl >= TC_H_MIN_PRIORITY) {
 		int i;
 		__u32 qlen = 0;
-		struct gnet_stats_queue qstats = {0};
-		struct gnet_stats_basic_packed bstats = {0};
+		struct gnet_stats_queue tqstats = {0};
+		struct gnet_stats_basic_packed tbstats = {0};
 		struct net_device *dev = qdisc_dev(sch);
 		struct netdev_tc_txq tc = dev->tc_to_txq[cl & TC_BITMASK];
 
@@ -529,6 +529,8 @@  static int mqprio_dump_class_stats(struct Qdisc *sch, unsigned long cl,
 			struct Qdisc *qdisc = rtnl_dereference(q->qdisc);
 			struct gnet_stats_basic_cpu __percpu *cpu_bstats = NULL;
 			struct gnet_stats_queue __percpu *cpu_qstats = NULL;
+			struct gnet_stats_queue qstats = {0};
+			struct gnet_stats_basic_packed bstats = {0};
 
 			spin_lock_bh(qdisc_lock(qdisc));
 			if (qdisc_is_percpu_stats(qdisc)) {
@@ -536,21 +538,28 @@  static int mqprio_dump_class_stats(struct Qdisc *sch, unsigned long cl,
 				cpu_qstats = qdisc->cpu_qstats;
 			}
 
-			qlen = qdisc_qlen_sum(qdisc);
-			__gnet_stats_copy_basic(NULL, &sch->bstats,
+			qlen += qdisc_qlen_sum(qdisc);
+			__gnet_stats_copy_basic(NULL, &bstats,
 						cpu_bstats, &qdisc->bstats);
-			__gnet_stats_copy_queue(&sch->qstats,
+			__gnet_stats_copy_queue(&qstats,
 						cpu_qstats,
 						&qdisc->qstats,
 						qlen);
 			spin_unlock_bh(qdisc_lock(qdisc));
+
+			tbstats.bytes		+= bstats.bytes;
+			tbstats.packets		+= bstats.packets;
+			tqstats.backlog		+= qstats.backlog;
+			tqstats.drops		+= qstats.drops;
+			tqstats.requeues	+= qstats.requeues;
+			tqstats.overlimits	+= qstats.overlimits;
 		}
 
 		/* Reclaim root sleeping lock before completing stats */
 		if (d->lock)
 			spin_lock_bh(d->lock);
-		if (gnet_stats_copy_basic(NULL, d, NULL, &bstats) < 0 ||
-		    gnet_stats_copy_queue(d, NULL, &qstats, qlen) < 0)
+		if (gnet_stats_copy_basic(NULL, d, NULL, &tbstats) < 0 ||
+		    gnet_stats_copy_queue(d, NULL, &tqstats, qlen) < 0)
 			return -1;
 	} else {
 		struct netdev_queue *dev_queue = mqprio_queue_get(sch, cl);