Skip to content

Commit 1413269

Browse files
Sebastian Andrzej Siewiorkuba-moo
authored andcommitted
mqprio: Correct stats in mqprio_dump_class_stats().
Introduction of lockless subqueues broke the class statistics. Before the change stats were accumulated in `bstats' and `qstats' on the stack which was then copied to struct gnet_dump. After the change the `bstats' and `qstats' are initialized to 0 and never updated, yet still fed to gnet_dump. The code updates the global qdisc->cpu_bstats and qdisc->cpu_qstats instead, clobbering them. Most likely a copy-paste error from the code in mqprio_dump(). __gnet_stats_copy_basic() and __gnet_stats_copy_queue() accumulate the values for per-CPU case but for global stats they overwrite the value, so only stats from the last loop iteration / tc end up in sch->[bq]stats. Use the on-stack [bq]stats variables again and add the stats manually in the global case. Fixes: ce679e8 ("net: sched: add support for TCQ_F_NOLOCK subqueues to sch_mqprio") Cc: John Fastabend <[email protected]> Signed-off-by: Sebastian Andrzej Siewior <[email protected]> https://lore.kernel.org/all/[email protected]/ Signed-off-by: Jakub Kicinski <[email protected]>
1 parent bccf56c commit 1413269

File tree

1 file changed

+18
-12
lines changed

1 file changed

+18
-12
lines changed

net/sched/sch_mqprio.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -529,22 +529,28 @@ static int mqprio_dump_class_stats(struct Qdisc *sch, unsigned long cl,
529529
for (i = tc.offset; i < tc.offset + tc.count; i++) {
530530
struct netdev_queue *q = netdev_get_tx_queue(dev, i);
531531
struct Qdisc *qdisc = rtnl_dereference(q->qdisc);
532-
struct gnet_stats_basic_cpu __percpu *cpu_bstats = NULL;
533-
struct gnet_stats_queue __percpu *cpu_qstats = NULL;
534532

535533
spin_lock_bh(qdisc_lock(qdisc));
534+
536535
if (qdisc_is_percpu_stats(qdisc)) {
537-
cpu_bstats = qdisc->cpu_bstats;
538-
cpu_qstats = qdisc->cpu_qstats;
536+
qlen = qdisc_qlen_sum(qdisc);
537+
538+
__gnet_stats_copy_basic(NULL, &bstats,
539+
qdisc->cpu_bstats,
540+
&qdisc->bstats);
541+
__gnet_stats_copy_queue(&qstats,
542+
qdisc->cpu_qstats,
543+
&qdisc->qstats,
544+
qlen);
545+
} else {
546+
qlen += qdisc->q.qlen;
547+
bstats.bytes += qdisc->bstats.bytes;
548+
bstats.packets += qdisc->bstats.packets;
549+
qstats.backlog += qdisc->qstats.backlog;
550+
qstats.drops += qdisc->qstats.drops;
551+
qstats.requeues += qdisc->qstats.requeues;
552+
qstats.overlimits += qdisc->qstats.overlimits;
539553
}
540-
541-
qlen = qdisc_qlen_sum(qdisc);
542-
__gnet_stats_copy_basic(NULL, &sch->bstats,
543-
cpu_bstats, &qdisc->bstats);
544-
__gnet_stats_copy_queue(&sch->qstats,
545-
cpu_qstats,
546-
&qdisc->qstats,
547-
qlen);
548554
spin_unlock_bh(qdisc_lock(qdisc));
549555
}
550556

0 commit comments

Comments
 (0)