.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * net/sched/sch_sfb.c Stochastic Fair Blue |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (c) 2008-2011 Juliusz Chroboczek <jch@pps.jussieu.fr> |
---|
5 | 6 | * Copyright (c) 2011 Eric Dumazet <eric.dumazet@gmail.com> |
---|
6 | 7 | * |
---|
7 | | - * This program is free software; you can redistribute it and/or |
---|
8 | | - * modify it under the terms of the GNU General Public License |
---|
9 | | - * version 2 as published by the Free Software Foundation. |
---|
10 | | - * |
---|
11 | 8 | * W. Feng, D. Kandlur, D. Saha, K. Shin. Blue: |
---|
12 | 9 | * A New Class of Active Queue Management Algorithms. |
---|
13 | 10 | * U. Michigan CSE-TR-387-99, April 1999. |
---|
14 | 11 | * |
---|
15 | 12 | * http://www.thefengs.com/wuchang/blue/CSE-TR-387-99.pdf |
---|
16 | | - * |
---|
17 | 13 | */ |
---|
18 | 14 | |
---|
19 | 15 | #include <linux/module.h> |
---|
.. | .. |
---|
139 | 135 | } |
---|
140 | 136 | } |
---|
141 | 137 | |
---|
142 | | -static void increment_qlen(const struct sk_buff *skb, struct sfb_sched_data *q) |
---|
| 138 | +static void increment_qlen(const struct sfb_skb_cb *cb, struct sfb_sched_data *q) |
---|
143 | 139 | { |
---|
144 | 140 | u32 sfbhash; |
---|
145 | 141 | |
---|
146 | | - sfbhash = sfb_hash(skb, 0); |
---|
| 142 | + sfbhash = cb->hashes[0]; |
---|
147 | 143 | if (sfbhash) |
---|
148 | 144 | increment_one_qlen(sfbhash, 0, q); |
---|
149 | 145 | |
---|
150 | | - sfbhash = sfb_hash(skb, 1); |
---|
| 146 | + sfbhash = cb->hashes[1]; |
---|
151 | 147 | if (sfbhash) |
---|
152 | 148 | increment_one_qlen(sfbhash, 1, q); |
---|
153 | 149 | } |
---|
.. | .. |
---|
269 | 265 | case TC_ACT_QUEUED: |
---|
270 | 266 | case TC_ACT_TRAP: |
---|
271 | 267 | *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN; |
---|
272 | | - /* fall through */ |
---|
| 268 | + fallthrough; |
---|
273 | 269 | case TC_ACT_SHOT: |
---|
274 | 270 | return false; |
---|
275 | 271 | } |
---|
.. | .. |
---|
285 | 281 | { |
---|
286 | 282 | |
---|
287 | 283 | struct sfb_sched_data *q = qdisc_priv(sch); |
---|
| 284 | + unsigned int len = qdisc_pkt_len(skb); |
---|
288 | 285 | struct Qdisc *child = q->qdisc; |
---|
289 | 286 | struct tcf_proto *fl; |
---|
| 287 | + struct sfb_skb_cb cb; |
---|
290 | 288 | int i; |
---|
291 | 289 | u32 p_min = ~0; |
---|
292 | 290 | u32 minqlen = ~0; |
---|
.. | .. |
---|
403 | 401 | } |
---|
404 | 402 | |
---|
405 | 403 | enqueue: |
---|
| 404 | + memcpy(&cb, sfb_skb_cb(skb), sizeof(cb)); |
---|
406 | 405 | ret = qdisc_enqueue(skb, child, to_free); |
---|
407 | 406 | if (likely(ret == NET_XMIT_SUCCESS)) { |
---|
408 | | - qdisc_qstats_backlog_inc(sch, skb); |
---|
| 407 | + sch->qstats.backlog += len; |
---|
409 | 408 | sch->q.qlen++; |
---|
410 | | - increment_qlen(skb, q); |
---|
| 409 | + increment_qlen(&cb, q); |
---|
411 | 410 | } else if (net_xmit_drop_count(ret)) { |
---|
412 | 411 | q->stats.childdrop++; |
---|
413 | 412 | qdisc_qstats_drop(sch); |
---|
.. | .. |
---|
456 | 455 | { |
---|
457 | 456 | struct sfb_sched_data *q = qdisc_priv(sch); |
---|
458 | 457 | |
---|
459 | | - qdisc_reset(q->qdisc); |
---|
460 | | - sch->qstats.backlog = 0; |
---|
461 | | - sch->q.qlen = 0; |
---|
| 458 | + if (likely(q->qdisc)) |
---|
| 459 | + qdisc_reset(q->qdisc); |
---|
462 | 460 | q->slot = 0; |
---|
463 | 461 | q->double_buffering = false; |
---|
464 | 462 | sfb_zero_all_buckets(q); |
---|
.. | .. |
---|
493 | 491 | struct netlink_ext_ack *extack) |
---|
494 | 492 | { |
---|
495 | 493 | struct sfb_sched_data *q = qdisc_priv(sch); |
---|
496 | | - struct Qdisc *child; |
---|
| 494 | + struct Qdisc *child, *old; |
---|
497 | 495 | struct nlattr *tb[TCA_SFB_MAX + 1]; |
---|
498 | 496 | const struct tc_sfb_qopt *ctl = &sfb_default_ops; |
---|
499 | 497 | u32 limit; |
---|
500 | 498 | int err; |
---|
501 | 499 | |
---|
502 | 500 | if (opt) { |
---|
503 | | - err = nla_parse_nested(tb, TCA_SFB_MAX, opt, sfb_policy, NULL); |
---|
| 501 | + err = nla_parse_nested_deprecated(tb, TCA_SFB_MAX, opt, |
---|
| 502 | + sfb_policy, NULL); |
---|
504 | 503 | if (err < 0) |
---|
505 | 504 | return -EINVAL; |
---|
506 | 505 | |
---|
.. | .. |
---|
522 | 521 | qdisc_hash_add(child, true); |
---|
523 | 522 | sch_tree_lock(sch); |
---|
524 | 523 | |
---|
525 | | - qdisc_tree_reduce_backlog(q->qdisc, q->qdisc->q.qlen, |
---|
526 | | - q->qdisc->qstats.backlog); |
---|
527 | | - qdisc_put(q->qdisc); |
---|
| 524 | + qdisc_purge_queue(q->qdisc); |
---|
| 525 | + old = q->qdisc; |
---|
528 | 526 | q->qdisc = child; |
---|
529 | 527 | |
---|
530 | 528 | q->rehash_interval = msecs_to_jiffies(ctl->rehash_interval); |
---|
.. | .. |
---|
547 | 545 | sfb_init_perturbation(1, q); |
---|
548 | 546 | |
---|
549 | 547 | sch_tree_unlock(sch); |
---|
| 548 | + qdisc_put(old); |
---|
550 | 549 | |
---|
551 | 550 | return 0; |
---|
552 | 551 | } |
---|
.. | .. |
---|
582 | 581 | }; |
---|
583 | 582 | |
---|
584 | 583 | sch->qstats.backlog = q->qdisc->qstats.backlog; |
---|
585 | | - opts = nla_nest_start(skb, TCA_OPTIONS); |
---|
| 584 | + opts = nla_nest_start_noflag(skb, TCA_OPTIONS); |
---|
586 | 585 | if (opts == NULL) |
---|
587 | 586 | goto nla_put_failure; |
---|
588 | 587 | if (nla_put(skb, TCA_SFB_PARMS, sizeof(opt), &opt)) |
---|