| .. | .. |
|---|
| 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) |
|---|