.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * net/sched/sch_drr.c Deficit Round Robin scheduler |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (c) 2008 Patrick McHardy <kaber@trash.net> |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or |
---|
7 | | - * modify it under the terms of the GNU General Public License |
---|
8 | | - * version 2 as published by the Free Software Foundation. |
---|
9 | 6 | */ |
---|
10 | 7 | |
---|
11 | 8 | #include <linux/module.h> |
---|
.. | .. |
---|
50 | 47 | return container_of(clc, struct drr_class, common); |
---|
51 | 48 | } |
---|
52 | 49 | |
---|
53 | | -static void drr_purge_queue(struct drr_class *cl) |
---|
54 | | -{ |
---|
55 | | - unsigned int len = cl->qdisc->q.qlen; |
---|
56 | | - unsigned int backlog = cl->qdisc->qstats.backlog; |
---|
57 | | - |
---|
58 | | - qdisc_reset(cl->qdisc); |
---|
59 | | - qdisc_tree_reduce_backlog(cl->qdisc, len, backlog); |
---|
60 | | -} |
---|
61 | | - |
---|
62 | 50 | static const struct nla_policy drr_policy[TCA_DRR_MAX + 1] = { |
---|
63 | 51 | [TCA_DRR_QUANTUM] = { .type = NLA_U32 }, |
---|
64 | 52 | }; |
---|
.. | .. |
---|
79 | 67 | return -EINVAL; |
---|
80 | 68 | } |
---|
81 | 69 | |
---|
82 | | - err = nla_parse_nested(tb, TCA_DRR_MAX, opt, drr_policy, extack); |
---|
| 70 | + err = nla_parse_nested_deprecated(tb, TCA_DRR_MAX, opt, drr_policy, |
---|
| 71 | + extack); |
---|
83 | 72 | if (err < 0) |
---|
84 | 73 | return err; |
---|
85 | 74 | |
---|
.. | .. |
---|
167 | 156 | |
---|
168 | 157 | sch_tree_lock(sch); |
---|
169 | 158 | |
---|
170 | | - drr_purge_queue(cl); |
---|
| 159 | + qdisc_purge_queue(cl->qdisc); |
---|
171 | 160 | qdisc_class_hash_remove(&q->clhash, &cl->common); |
---|
172 | 161 | |
---|
173 | 162 | sch_tree_unlock(sch); |
---|
.. | .. |
---|
253 | 242 | tcm->tcm_handle = cl->common.classid; |
---|
254 | 243 | tcm->tcm_info = cl->qdisc->handle; |
---|
255 | 244 | |
---|
256 | | - nest = nla_nest_start(skb, TCA_OPTIONS); |
---|
| 245 | + nest = nla_nest_start_noflag(skb, TCA_OPTIONS); |
---|
257 | 246 | if (nest == NULL) |
---|
258 | 247 | goto nla_put_failure; |
---|
259 | 248 | if (nla_put_u32(skb, TCA_DRR_QUANTUM, cl->quantum)) |
---|
.. | .. |
---|
269 | 258 | struct gnet_dump *d) |
---|
270 | 259 | { |
---|
271 | 260 | struct drr_class *cl = (struct drr_class *)arg; |
---|
272 | | - __u32 qlen = cl->qdisc->q.qlen; |
---|
| 261 | + __u32 qlen = qdisc_qlen_sum(cl->qdisc); |
---|
| 262 | + struct Qdisc *cl_q = cl->qdisc; |
---|
273 | 263 | struct tc_drr_stats xstats; |
---|
274 | 264 | |
---|
275 | 265 | memset(&xstats, 0, sizeof(xstats)); |
---|
.. | .. |
---|
279 | 269 | if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch), |
---|
280 | 270 | d, NULL, &cl->bstats) < 0 || |
---|
281 | 271 | gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 || |
---|
282 | | - gnet_stats_copy_queue(d, NULL, &cl->qdisc->qstats, qlen) < 0) |
---|
| 272 | + gnet_stats_copy_queue(d, cl_q->cpu_qstats, &cl_q->qstats, qlen) < 0) |
---|
283 | 273 | return -1; |
---|
284 | 274 | |
---|
285 | 275 | return gnet_stats_copy_app(d, &xstats, sizeof(xstats)); |
---|
.. | .. |
---|
334 | 324 | case TC_ACT_STOLEN: |
---|
335 | 325 | case TC_ACT_TRAP: |
---|
336 | 326 | *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN; |
---|
337 | | - /* fall through */ |
---|
| 327 | + fallthrough; |
---|
338 | 328 | case TC_ACT_SHOT: |
---|
339 | 329 | return NULL; |
---|
340 | 330 | } |
---|
.. | .. |
---|
350 | 340 | static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch, |
---|
351 | 341 | struct sk_buff **to_free) |
---|
352 | 342 | { |
---|
| 343 | + unsigned int len = qdisc_pkt_len(skb); |
---|
353 | 344 | struct drr_sched *q = qdisc_priv(sch); |
---|
354 | 345 | struct drr_class *cl; |
---|
355 | 346 | int err = 0; |
---|
| 347 | + bool first; |
---|
356 | 348 | |
---|
357 | 349 | cl = drr_classify(skb, sch, &err); |
---|
358 | 350 | if (cl == NULL) { |
---|
.. | .. |
---|
362 | 354 | return err; |
---|
363 | 355 | } |
---|
364 | 356 | |
---|
| 357 | + first = !cl->qdisc->q.qlen; |
---|
365 | 358 | err = qdisc_enqueue(skb, cl->qdisc, to_free); |
---|
366 | 359 | if (unlikely(err != NET_XMIT_SUCCESS)) { |
---|
367 | 360 | if (net_xmit_drop_count(err)) { |
---|
.. | .. |
---|
371 | 364 | return err; |
---|
372 | 365 | } |
---|
373 | 366 | |
---|
374 | | - if (cl->qdisc->q.qlen == 1) { |
---|
| 367 | + if (first) { |
---|
375 | 368 | list_add_tail(&cl->alist, &q->active); |
---|
376 | 369 | cl->deficit = cl->quantum; |
---|
377 | 370 | } |
---|
378 | 371 | |
---|
379 | | - qdisc_qstats_backlog_inc(sch, skb); |
---|
| 372 | + sch->qstats.backlog += len; |
---|
380 | 373 | sch->q.qlen++; |
---|
381 | 374 | return err; |
---|
382 | 375 | } |
---|
.. | .. |
---|
450 | 443 | qdisc_reset(cl->qdisc); |
---|
451 | 444 | } |
---|
452 | 445 | } |
---|
453 | | - sch->qstats.backlog = 0; |
---|
454 | | - sch->q.qlen = 0; |
---|
455 | 446 | } |
---|
456 | 447 | |
---|
457 | 448 | static void drr_destroy_qdisc(struct Qdisc *sch) |
---|