Skip to content

Commit b01ac09

Browse files
jrfastabdavem330
authored andcommitted
net: sched: add support for TCQ_F_NOLOCK subqueues to sch_mq
The sch_mq qdisc creates a sub-qdisc per tx queue which are then called independently for enqueue and dequeue operations. However statistics are aggregated and pushed up to the "master" qdisc. This patch adds support for any of the sub-qdiscs to be per cpu statistic qdiscs. To handle this case add a check when calculating stats and aggregate the per cpu stats if needed. Also exports __gnet_stats_copy_queue() to use as a helper function. Signed-off-by: John Fastabend <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7e66016 commit b01ac09

File tree

3 files changed

+26
-11
lines changed

3 files changed

+26
-11
lines changed

include/net/gen_stats.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ int gnet_stats_copy_rate_est(struct gnet_dump *d,
4949
int gnet_stats_copy_queue(struct gnet_dump *d,
5050
struct gnet_stats_queue __percpu *cpu_q,
5151
struct gnet_stats_queue *q, __u32 qlen);
52+
void __gnet_stats_copy_queue(struct gnet_stats_queue *qstats,
53+
const struct gnet_stats_queue __percpu *cpu_q,
54+
const struct gnet_stats_queue *q, __u32 qlen);
5255
int gnet_stats_copy_app(struct gnet_dump *d, void *st, int len);
5356

5457
int gnet_stats_finish_copy(struct gnet_dump *d);

net/core/gen_stats.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,10 @@ __gnet_stats_copy_queue_cpu(struct gnet_stats_queue *qstats,
252252
}
253253
}
254254

255-
static void __gnet_stats_copy_queue(struct gnet_stats_queue *qstats,
256-
const struct gnet_stats_queue __percpu *cpu,
257-
const struct gnet_stats_queue *q,
258-
__u32 qlen)
255+
void __gnet_stats_copy_queue(struct gnet_stats_queue *qstats,
256+
const struct gnet_stats_queue __percpu *cpu,
257+
const struct gnet_stats_queue *q,
258+
__u32 qlen)
259259
{
260260
if (cpu) {
261261
__gnet_stats_copy_queue_cpu(qstats, cpu);
@@ -269,6 +269,7 @@ static void __gnet_stats_copy_queue(struct gnet_stats_queue *qstats,
269269

270270
qstats->qlen = qlen;
271271
}
272+
EXPORT_SYMBOL(__gnet_stats_copy_queue);
272273

273274
/**
274275
* gnet_stats_copy_queue - copy queue statistics into statistics TLV

net/sched/sch_mq.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/skbuff.h>
1818
#include <net/netlink.h>
1919
#include <net/pkt_sched.h>
20+
#include <net/sch_generic.h>
2021

2122
struct mq_sched {
2223
struct Qdisc **qdiscs;
@@ -103,15 +104,25 @@ static int mq_dump(struct Qdisc *sch, struct sk_buff *skb)
103104
memset(&sch->qstats, 0, sizeof(sch->qstats));
104105

105106
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+
106111
qdisc = netdev_get_tx_queue(dev, ntx)->qdisc_sleeping;
107112
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+
115126
spin_unlock_bh(qdisc_lock(qdisc));
116127
}
117128
return 0;

0 commit comments

Comments
 (0)