.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * net/sched/sch_prio.c Simple 3-band priority "scheduler". |
---|
3 | | - * |
---|
4 | | - * This program is free software; you can redistribute it and/or |
---|
5 | | - * modify it under the terms of the GNU General Public License |
---|
6 | | - * as published by the Free Software Foundation; either version |
---|
7 | | - * 2 of the License, or (at your option) any later version. |
---|
8 | 4 | * |
---|
9 | 5 | * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> |
---|
10 | 6 | * Fixes: 19990609: J Hadi Salim <hadi@nortelnetworks.com>: |
---|
.. | .. |
---|
50 | 46 | case TC_ACT_QUEUED: |
---|
51 | 47 | case TC_ACT_TRAP: |
---|
52 | 48 | *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN; |
---|
53 | | - /* fall through */ |
---|
| 49 | + fallthrough; |
---|
54 | 50 | case TC_ACT_SHOT: |
---|
55 | 51 | return NULL; |
---|
56 | 52 | } |
---|
.. | .. |
---|
72 | 68 | static int |
---|
73 | 69 | prio_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) |
---|
74 | 70 | { |
---|
| 71 | + unsigned int len = qdisc_pkt_len(skb); |
---|
75 | 72 | struct Qdisc *qdisc; |
---|
76 | 73 | int ret; |
---|
77 | 74 | |
---|
.. | .. |
---|
88 | 85 | |
---|
89 | 86 | ret = qdisc_enqueue(skb, qdisc, to_free); |
---|
90 | 87 | if (ret == NET_XMIT_SUCCESS) { |
---|
91 | | - qdisc_qstats_backlog_inc(sch, skb); |
---|
| 88 | + sch->qstats.backlog += len; |
---|
92 | 89 | sch->q.qlen++; |
---|
93 | 90 | return NET_XMIT_SUCCESS; |
---|
94 | 91 | } |
---|
.. | .. |
---|
138 | 135 | |
---|
139 | 136 | for (prio = 0; prio < q->bands; prio++) |
---|
140 | 137 | qdisc_reset(q->queues[prio]); |
---|
141 | | - sch->qstats.backlog = 0; |
---|
142 | | - sch->q.qlen = 0; |
---|
143 | 138 | } |
---|
144 | 139 | |
---|
145 | 140 | static int prio_offload(struct Qdisc *sch, struct tc_prio_qopt *qopt) |
---|
.. | .. |
---|
215 | 210 | q->bands = qopt->bands; |
---|
216 | 211 | memcpy(q->prio2band, qopt->priomap, TC_PRIO_MAX+1); |
---|
217 | 212 | |
---|
218 | | - for (i = q->bands; i < oldbands; i++) { |
---|
219 | | - struct Qdisc *child = q->queues[i]; |
---|
220 | | - |
---|
221 | | - qdisc_tree_reduce_backlog(child, child->q.qlen, |
---|
222 | | - child->qstats.backlog); |
---|
223 | | - qdisc_put(child); |
---|
224 | | - } |
---|
| 213 | + for (i = q->bands; i < oldbands; i++) |
---|
| 214 | + qdisc_tree_flush_backlog(q->queues[i]); |
---|
225 | 215 | |
---|
226 | 216 | for (i = oldbands; i < q->bands; i++) { |
---|
227 | 217 | q->queues[i] = queues[i]; |
---|
.. | .. |
---|
230 | 220 | } |
---|
231 | 221 | |
---|
232 | 222 | sch_tree_unlock(sch); |
---|
| 223 | + |
---|
| 224 | + for (i = q->bands; i < oldbands; i++) |
---|
| 225 | + qdisc_put(q->queues[i]); |
---|
233 | 226 | return 0; |
---|
234 | 227 | } |
---|
235 | 228 | |
---|
.. | .. |
---|
251 | 244 | |
---|
252 | 245 | static int prio_dump_offload(struct Qdisc *sch) |
---|
253 | 246 | { |
---|
254 | | - struct net_device *dev = qdisc_dev(sch); |
---|
255 | 247 | struct tc_prio_qopt_offload hw_stats = { |
---|
256 | 248 | .command = TC_PRIO_STATS, |
---|
257 | 249 | .handle = sch->handle, |
---|
.. | .. |
---|
263 | 255 | }, |
---|
264 | 256 | }, |
---|
265 | 257 | }; |
---|
266 | | - int err; |
---|
267 | 258 | |
---|
268 | | - sch->flags &= ~TCQ_F_OFFLOADED; |
---|
269 | | - if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc) |
---|
270 | | - return 0; |
---|
271 | | - |
---|
272 | | - err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_PRIO, |
---|
273 | | - &hw_stats); |
---|
274 | | - if (err == -EOPNOTSUPP) |
---|
275 | | - return 0; |
---|
276 | | - |
---|
277 | | - if (!err) |
---|
278 | | - sch->flags |= TCQ_F_OFFLOADED; |
---|
279 | | - |
---|
280 | | - return err; |
---|
| 259 | + return qdisc_offload_dump_helper(sch, TC_SETUP_QDISC_PRIO, &hw_stats); |
---|
281 | 260 | } |
---|
282 | 261 | |
---|
283 | 262 | static int prio_dump(struct Qdisc *sch, struct sk_buff *skb) |
---|
.. | .. |
---|
309 | 288 | { |
---|
310 | 289 | struct prio_sched_data *q = qdisc_priv(sch); |
---|
311 | 290 | struct tc_prio_qopt_offload graft_offload; |
---|
312 | | - struct net_device *dev = qdisc_dev(sch); |
---|
313 | 291 | unsigned long band = arg - 1; |
---|
314 | | - bool any_qdisc_is_offloaded; |
---|
315 | | - int err; |
---|
316 | 292 | |
---|
317 | 293 | if (!new) { |
---|
318 | 294 | new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, |
---|
.. | .. |
---|
325 | 301 | |
---|
326 | 302 | *old = qdisc_replace(sch, new, &q->queues[band]); |
---|
327 | 303 | |
---|
328 | | - if (!tc_can_offload(dev)) |
---|
329 | | - return 0; |
---|
330 | | - |
---|
331 | 304 | graft_offload.handle = sch->handle; |
---|
332 | 305 | graft_offload.parent = sch->parent; |
---|
333 | 306 | graft_offload.graft_params.band = band; |
---|
334 | 307 | graft_offload.graft_params.child_handle = new->handle; |
---|
335 | 308 | graft_offload.command = TC_PRIO_GRAFT; |
---|
336 | 309 | |
---|
337 | | - err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_PRIO, |
---|
338 | | - &graft_offload); |
---|
339 | | - |
---|
340 | | - /* Don't report error if the graft is part of destroy operation. */ |
---|
341 | | - if (err && new != &noop_qdisc) { |
---|
342 | | - /* Don't report error if the parent, the old child and the new |
---|
343 | | - * one are not offloaded. |
---|
344 | | - */ |
---|
345 | | - any_qdisc_is_offloaded = sch->flags & TCQ_F_OFFLOADED; |
---|
346 | | - any_qdisc_is_offloaded |= new->flags & TCQ_F_OFFLOADED; |
---|
347 | | - if (*old) |
---|
348 | | - any_qdisc_is_offloaded |= (*old)->flags & |
---|
349 | | - TCQ_F_OFFLOADED; |
---|
350 | | - |
---|
351 | | - if (any_qdisc_is_offloaded) |
---|
352 | | - NL_SET_ERR_MSG(extack, "Offloading graft operation failed."); |
---|
353 | | - } |
---|
354 | | - |
---|
| 310 | + qdisc_offload_graft_helper(qdisc_dev(sch), sch, new, *old, |
---|
| 311 | + TC_SETUP_QDISC_PRIO, &graft_offload, |
---|
| 312 | + extack); |
---|
355 | 313 | return 0; |
---|
356 | 314 | } |
---|
357 | 315 | |
---|
.. | .. |
---|
403 | 361 | cl_q = q->queues[cl - 1]; |
---|
404 | 362 | if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch), |
---|
405 | 363 | d, cl_q->cpu_bstats, &cl_q->bstats) < 0 || |
---|
406 | | - gnet_stats_copy_queue(d, NULL, &cl_q->qstats, cl_q->q.qlen) < 0) |
---|
| 364 | + qdisc_qstats_copy(d, cl_q) < 0) |
---|
407 | 365 | return -1; |
---|
408 | 366 | |
---|
409 | 367 | return 0; |
---|