Skip to content

Commit 6401585

Browse files
jrfastabdavem330
authored andcommitted
net: sched: restrict use of qstats qlen
This removes the use of qstats->qlen variable from the classifiers and makes it an explicit argument to gnet_stats_copy_queue(). The qlen represents the qdisc queue length and is packed into the qstats at the last moment before passnig to user space. By handling it explicitely we avoid, in the percpu stats case, having to figure out which per_cpu variable to put it in. It would probably be best to remove it from qstats completely but qstats is a user space ABI and can't be broken. A future patch could make an internal only qstats structure that would avoid having to allocate an additional u32 variable on the Qdisc struct. This would make the qstats struct 128bits instead of 128+32. Signed-off-by: John Fastabend <john.r.fastabend@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 25331d6 commit 6401585

File tree

16 files changed

+32
-34
lines changed

16 files changed

+32
-34
lines changed

include/net/gen_stats.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ void __gnet_stats_copy_basic(struct gnet_stats_basic_packed *bstats,
4040
int gnet_stats_copy_rate_est(struct gnet_dump *d,
4141
const struct gnet_stats_basic_packed *b,
4242
struct gnet_stats_rate_est64 *r);
43-
int gnet_stats_copy_queue(struct gnet_dump *d, struct gnet_stats_queue *q);
43+
int gnet_stats_copy_queue(struct gnet_dump *d,
44+
struct gnet_stats_queue *q, __u32 len);
4445
int gnet_stats_copy_app(struct gnet_dump *d, void *st, int len);
4546

4647
int gnet_stats_finish_copy(struct gnet_dump *d);

net/core/gen_stats.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ EXPORT_SYMBOL(gnet_stats_copy_rate_est);
219219
* gnet_stats_copy_queue - copy queue statistics into statistics TLV
220220
* @d: dumping handle
221221
* @q: queue statistics
222+
* @qlen: queue length statistics
222223
*
223224
* Appends the queue statistics to the top level TLV created by
224225
* gnet_stats_start_copy().
@@ -227,8 +228,11 @@ EXPORT_SYMBOL(gnet_stats_copy_rate_est);
227228
* if the room in the socket buffer was not sufficient.
228229
*/
229230
int
230-
gnet_stats_copy_queue(struct gnet_dump *d, struct gnet_stats_queue *q)
231+
gnet_stats_copy_queue(struct gnet_dump *d,
232+
struct gnet_stats_queue *q, __u32 qlen)
231233
{
234+
q->qlen = qlen;
235+
232236
if (d->compat_tc_stats) {
233237
d->tc_stats.drops = q->drops;
234238
d->tc_stats.qlen = q->qlen;

net/sched/act_api.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,9 @@ int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a,
623623
if (gnet_stats_copy_basic(&d, NULL, &p->tcfc_bstats) < 0 ||
624624
gnet_stats_copy_rate_est(&d, &p->tcfc_bstats,
625625
&p->tcfc_rate_est) < 0 ||
626-
gnet_stats_copy_queue(&d, &p->tcfc_qstats) < 0)
626+
gnet_stats_copy_queue(&d,
627+
&p->tcfc_qstats,
628+
p->tcfc_qstats.qlen) < 0)
627629
goto errout;
628630

629631
if (gnet_stats_finish_copy(&d) < 0)

net/sched/sch_api.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,6 +1318,7 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
13181318
unsigned char *b = skb_tail_pointer(skb);
13191319
struct gnet_dump d;
13201320
struct qdisc_size_table *stab;
1321+
__u32 qlen;
13211322

13221323
cond_resched();
13231324
nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags);
@@ -1335,7 +1336,7 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
13351336
goto nla_put_failure;
13361337
if (q->ops->dump && q->ops->dump(q, skb) < 0)
13371338
goto nla_put_failure;
1338-
q->qstats.qlen = q->q.qlen;
1339+
qlen = q->q.qlen;
13391340

13401341
stab = rtnl_dereference(q->stab);
13411342
if (stab && qdisc_dump_stab(skb, stab) < 0)
@@ -1353,7 +1354,7 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
13531354

13541355
if (gnet_stats_copy_basic(&d, cpu_bstats, &q->bstats) < 0 ||
13551356
gnet_stats_copy_rate_est(&d, &q->bstats, &q->rate_est) < 0 ||
1356-
gnet_stats_copy_queue(&d, &q->qstats) < 0)
1357+
gnet_stats_copy_queue(&d, &q->qstats, qlen) < 0)
13571358
goto nla_put_failure;
13581359

13591360
if (gnet_stats_finish_copy(&d) < 0)

net/sched/sch_atm.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -637,10 +637,8 @@ atm_tc_dump_class_stats(struct Qdisc *sch, unsigned long arg,
637637
{
638638
struct atm_flow_data *flow = (struct atm_flow_data *)arg;
639639

640-
flow->qstats.qlen = flow->q->q.qlen;
641-
642640
if (gnet_stats_copy_basic(d, NULL, &flow->bstats) < 0 ||
643-
gnet_stats_copy_queue(d, &flow->qstats) < 0)
641+
gnet_stats_copy_queue(d, &flow->qstats, flow->q->q.qlen) < 0)
644642
return -1;
645643

646644
return 0;

net/sched/sch_cbq.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,7 +1594,6 @@ cbq_dump_class_stats(struct Qdisc *sch, unsigned long arg,
15941594
struct cbq_sched_data *q = qdisc_priv(sch);
15951595
struct cbq_class *cl = (struct cbq_class *)arg;
15961596

1597-
cl->qstats.qlen = cl->q->q.qlen;
15981597
cl->xstats.avgidle = cl->avgidle;
15991598
cl->xstats.undertime = 0;
16001599

@@ -1603,7 +1602,7 @@ cbq_dump_class_stats(struct Qdisc *sch, unsigned long arg,
16031602

16041603
if (gnet_stats_copy_basic(d, NULL, &cl->bstats) < 0 ||
16051604
gnet_stats_copy_rate_est(d, &cl->bstats, &cl->rate_est) < 0 ||
1606-
gnet_stats_copy_queue(d, &cl->qstats) < 0)
1605+
gnet_stats_copy_queue(d, &cl->qstats, cl->q->q.qlen) < 0)
16071606
return -1;
16081607

16091608
return gnet_stats_copy_app(d, &cl->xstats, sizeof(cl->xstats));

net/sched/sch_drr.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -275,17 +275,16 @@ static int drr_dump_class_stats(struct Qdisc *sch, unsigned long arg,
275275
struct gnet_dump *d)
276276
{
277277
struct drr_class *cl = (struct drr_class *)arg;
278+
__u32 qlen = cl->qdisc->q.qlen;
278279
struct tc_drr_stats xstats;
279280

280281
memset(&xstats, 0, sizeof(xstats));
281-
if (cl->qdisc->q.qlen) {
282+
if (qlen)
282283
xstats.deficit = cl->deficit;
283-
cl->qdisc->qstats.qlen = cl->qdisc->q.qlen;
284-
}
285284

286285
if (gnet_stats_copy_basic(d, NULL, &cl->bstats) < 0 ||
287286
gnet_stats_copy_rate_est(d, &cl->bstats, &cl->rate_est) < 0 ||
288-
gnet_stats_copy_queue(d, &cl->qdisc->qstats) < 0)
287+
gnet_stats_copy_queue(d, &cl->qdisc->qstats, qlen) < 0)
289288
return -1;
290289

291290
return gnet_stats_copy_app(d, &xstats, sizeof(xstats));

net/sched/sch_fq_codel.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ static int fq_codel_dump_class_stats(struct Qdisc *sch, unsigned long cl,
550550
qs.backlog = q->backlogs[idx];
551551
qs.drops = flow->dropped;
552552
}
553-
if (gnet_stats_copy_queue(d, &qs) < 0)
553+
if (gnet_stats_copy_queue(d, &qs, 0) < 0)
554554
return -1;
555555
if (idx < q->flows_cnt)
556556
return gnet_stats_copy_app(d, &xstats, sizeof(xstats));

net/sched/sch_hfsc.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,7 +1370,6 @@ hfsc_dump_class_stats(struct Qdisc *sch, unsigned long arg,
13701370
struct hfsc_class *cl = (struct hfsc_class *)arg;
13711371
struct tc_hfsc_stats xstats;
13721372

1373-
cl->qstats.qlen = cl->qdisc->q.qlen;
13741373
cl->qstats.backlog = cl->qdisc->qstats.backlog;
13751374
xstats.level = cl->level;
13761375
xstats.period = cl->cl_vtperiod;
@@ -1379,7 +1378,7 @@ hfsc_dump_class_stats(struct Qdisc *sch, unsigned long arg,
13791378

13801379
if (gnet_stats_copy_basic(d, NULL, &cl->bstats) < 0 ||
13811380
gnet_stats_copy_rate_est(d, &cl->bstats, &cl->rate_est) < 0 ||
1382-
gnet_stats_copy_queue(d, &cl->qstats) < 0)
1381+
gnet_stats_copy_queue(d, &cl->qstats, cl->qdisc->q.qlen) < 0)
13831382
return -1;
13841383

13851384
return gnet_stats_copy_app(d, &xstats, sizeof(xstats));

net/sched/sch_htb.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,15 +1138,16 @@ static int
11381138
htb_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct gnet_dump *d)
11391139
{
11401140
struct htb_class *cl = (struct htb_class *)arg;
1141+
__u32 qlen = 0;
11411142

11421143
if (!cl->level && cl->un.leaf.q)
1143-
cl->qstats.qlen = cl->un.leaf.q->q.qlen;
1144+
qlen = cl->un.leaf.q->q.qlen;
11441145
cl->xstats.tokens = PSCHED_NS2TICKS(cl->tokens);
11451146
cl->xstats.ctokens = PSCHED_NS2TICKS(cl->ctokens);
11461147

11471148
if (gnet_stats_copy_basic(d, NULL, &cl->bstats) < 0 ||
11481149
gnet_stats_copy_rate_est(d, NULL, &cl->rate_est) < 0 ||
1149-
gnet_stats_copy_queue(d, &cl->qstats) < 0)
1150+
gnet_stats_copy_queue(d, &cl->qstats, qlen) < 0)
11501151
return -1;
11511152

11521153
return gnet_stats_copy_app(d, &cl->xstats, sizeof(cl->xstats));

net/sched/sch_mq.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ static int mq_dump(struct Qdisc *sch, struct sk_buff *skb)
112112
sch->q.qlen += qdisc->q.qlen;
113113
sch->bstats.bytes += qdisc->bstats.bytes;
114114
sch->bstats.packets += qdisc->bstats.packets;
115-
sch->qstats.qlen += qdisc->qstats.qlen;
116115
sch->qstats.backlog += qdisc->qstats.backlog;
117116
sch->qstats.drops += qdisc->qstats.drops;
118117
sch->qstats.requeues += qdisc->qstats.requeues;
@@ -200,9 +199,8 @@ static int mq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
200199
struct netdev_queue *dev_queue = mq_queue_get(sch, cl);
201200

202201
sch = dev_queue->qdisc_sleeping;
203-
sch->qstats.qlen = sch->q.qlen;
204202
if (gnet_stats_copy_basic(d, NULL, &sch->bstats) < 0 ||
205-
gnet_stats_copy_queue(d, &sch->qstats) < 0)
203+
gnet_stats_copy_queue(d, &sch->qstats, sch->q.qlen) < 0)
206204
return -1;
207205
return 0;
208206
}

net/sched/sch_mqprio.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,6 @@ static int mqprio_dump(struct Qdisc *sch, struct sk_buff *skb)
236236
sch->q.qlen += qdisc->q.qlen;
237237
sch->bstats.bytes += qdisc->bstats.bytes;
238238
sch->bstats.packets += qdisc->bstats.packets;
239-
sch->qstats.qlen += qdisc->qstats.qlen;
240239
sch->qstats.backlog += qdisc->qstats.backlog;
241240
sch->qstats.drops += qdisc->qstats.drops;
242241
sch->qstats.requeues += qdisc->qstats.requeues;
@@ -327,6 +326,7 @@ static int mqprio_dump_class_stats(struct Qdisc *sch, unsigned long cl,
327326

328327
if (cl <= netdev_get_num_tc(dev)) {
329328
int i;
329+
__u32 qlen = 0;
330330
struct Qdisc *qdisc;
331331
struct gnet_stats_queue qstats = {0};
332332
struct gnet_stats_basic_packed bstats = {0};
@@ -344,9 +344,9 @@ static int mqprio_dump_class_stats(struct Qdisc *sch, unsigned long cl,
344344

345345
qdisc = rtnl_dereference(q->qdisc);
346346
spin_lock_bh(qdisc_lock(qdisc));
347+
qlen += qdisc->q.qlen;
347348
bstats.bytes += qdisc->bstats.bytes;
348349
bstats.packets += qdisc->bstats.packets;
349-
qstats.qlen += qdisc->qstats.qlen;
350350
qstats.backlog += qdisc->qstats.backlog;
351351
qstats.drops += qdisc->qstats.drops;
352352
qstats.requeues += qdisc->qstats.requeues;
@@ -356,15 +356,14 @@ static int mqprio_dump_class_stats(struct Qdisc *sch, unsigned long cl,
356356
/* Reclaim root sleeping lock before completing stats */
357357
spin_lock_bh(d->lock);
358358
if (gnet_stats_copy_basic(d, NULL, &bstats) < 0 ||
359-
gnet_stats_copy_queue(d, &qstats) < 0)
359+
gnet_stats_copy_queue(d, &qstats, qlen) < 0)
360360
return -1;
361361
} else {
362362
struct netdev_queue *dev_queue = mqprio_queue_get(sch, cl);
363363

364364
sch = dev_queue->qdisc_sleeping;
365-
sch->qstats.qlen = sch->q.qlen;
366365
if (gnet_stats_copy_basic(d, NULL, &sch->bstats) < 0 ||
367-
gnet_stats_copy_queue(d, &sch->qstats) < 0)
366+
gnet_stats_copy_queue(d, &sch->qstats, sch->q.qlen) < 0)
368367
return -1;
369368
}
370369
return 0;

net/sched/sch_multiq.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,9 +360,8 @@ static int multiq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
360360
struct Qdisc *cl_q;
361361

362362
cl_q = q->queues[cl - 1];
363-
cl_q->qstats.qlen = cl_q->q.qlen;
364363
if (gnet_stats_copy_basic(d, NULL, &cl_q->bstats) < 0 ||
365-
gnet_stats_copy_queue(d, &cl_q->qstats) < 0)
364+
gnet_stats_copy_queue(d, &cl_q->qstats, cl_q->q.qlen) < 0)
366365
return -1;
367366

368367
return 0;

net/sched/sch_prio.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,9 +324,8 @@ static int prio_dump_class_stats(struct Qdisc *sch, unsigned long cl,
324324
struct Qdisc *cl_q;
325325

326326
cl_q = q->queues[cl - 1];
327-
cl_q->qstats.qlen = cl_q->q.qlen;
328327
if (gnet_stats_copy_basic(d, NULL, &cl_q->bstats) < 0 ||
329-
gnet_stats_copy_queue(d, &cl_q->qstats) < 0)
328+
gnet_stats_copy_queue(d, &cl_q->qstats, cl_q->q.qlen) < 0)
330329
return -1;
331330

332331
return 0;

net/sched/sch_qfq.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -664,14 +664,13 @@ static int qfq_dump_class_stats(struct Qdisc *sch, unsigned long arg,
664664
struct tc_qfq_stats xstats;
665665

666666
memset(&xstats, 0, sizeof(xstats));
667-
cl->qdisc->qstats.qlen = cl->qdisc->q.qlen;
668667

669668
xstats.weight = cl->agg->class_weight;
670669
xstats.lmax = cl->agg->lmax;
671670

672671
if (gnet_stats_copy_basic(d, NULL, &cl->bstats) < 0 ||
673672
gnet_stats_copy_rate_est(d, &cl->bstats, &cl->rate_est) < 0 ||
674-
gnet_stats_copy_queue(d, &cl->qdisc->qstats) < 0)
673+
gnet_stats_copy_queue(d, &cl->qdisc->qstats, cl->qdisc->q.qlen) < 0)
675674
return -1;
676675

677676
return gnet_stats_copy_app(d, &xstats, sizeof(xstats));

net/sched/sch_sfq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -871,7 +871,7 @@ static int sfq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
871871
qs.qlen = slot->qlen;
872872
qs.backlog = slot->backlog;
873873
}
874-
if (gnet_stats_copy_queue(d, &qs) < 0)
874+
if (gnet_stats_copy_queue(d, &qs, qs.qlen) < 0)
875875
return -1;
876876
return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
877877
}

0 commit comments

Comments
 (0)