|
17 | 17 | #include <linux/skbuff.h> |
18 | 18 | #include <net/netlink.h> |
19 | 19 | #include <net/pkt_sched.h> |
| 20 | +#include <net/sch_generic.h> |
20 | 21 |
|
21 | 22 | struct mq_sched { |
22 | 23 | struct Qdisc **qdiscs; |
@@ -103,15 +104,25 @@ static int mq_dump(struct Qdisc *sch, struct sk_buff *skb) |
103 | 104 | memset(&sch->qstats, 0, sizeof(sch->qstats)); |
104 | 105 |
|
105 | 106 | for (ntx = 0; ntx < dev->num_tx_queues; ntx++) { |
| 107 | + struct gnet_stats_basic_cpu __percpu *cpu_bstats = NULL; |
| 108 | + struct gnet_stats_queue __percpu *cpu_qstats = NULL; |
| 109 | + __u32 qlen = 0; |
| 110 | + |
106 | 111 | qdisc = netdev_get_tx_queue(dev, ntx)->qdisc_sleeping; |
107 | 112 | spin_lock_bh(qdisc_lock(qdisc)); |
108 | | - sch->q.qlen += qdisc->q.qlen; |
109 | | - sch->bstats.bytes += qdisc->bstats.bytes; |
110 | | - sch->bstats.packets += qdisc->bstats.packets; |
111 | | - sch->qstats.backlog += qdisc->qstats.backlog; |
112 | | - sch->qstats.drops += qdisc->qstats.drops; |
113 | | - sch->qstats.requeues += qdisc->qstats.requeues; |
114 | | - sch->qstats.overlimits += qdisc->qstats.overlimits; |
| 113 | + |
| 114 | + if (qdisc_is_percpu_stats(qdisc)) { |
| 115 | + cpu_bstats = qdisc->cpu_bstats; |
| 116 | + cpu_qstats = qdisc->cpu_qstats; |
| 117 | + } |
| 118 | + |
| 119 | + qlen = qdisc_qlen_sum(qdisc); |
| 120 | + |
| 121 | + __gnet_stats_copy_basic(NULL, &sch->bstats, |
| 122 | + cpu_bstats, &qdisc->bstats); |
| 123 | + __gnet_stats_copy_queue(&sch->qstats, |
| 124 | + cpu_qstats, &qdisc->qstats, qlen); |
| 125 | + |
115 | 126 | spin_unlock_bh(qdisc_lock(qdisc)); |
116 | 127 | } |
117 | 128 | return 0; |
|
0 commit comments