| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * net/sched/sch_mq.c Classful multiqueue dummy scheduler |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (c) 2009 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/types.h> |
|---|
| .. | .. |
|---|
| 38 | 35 | return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_MQ, &opt); |
|---|
| 39 | 36 | } |
|---|
| 40 | 37 | |
|---|
| 41 | | -static void mq_offload_stats(struct Qdisc *sch) |
|---|
| 38 | +static int mq_offload_stats(struct Qdisc *sch) |
|---|
| 42 | 39 | { |
|---|
| 43 | | - struct net_device *dev = qdisc_dev(sch); |
|---|
| 44 | 40 | struct tc_mq_qopt_offload opt = { |
|---|
| 45 | 41 | .command = TC_MQ_STATS, |
|---|
| 46 | 42 | .handle = sch->handle, |
|---|
| .. | .. |
|---|
| 50 | 46 | }, |
|---|
| 51 | 47 | }; |
|---|
| 52 | 48 | |
|---|
| 53 | | - if (tc_can_offload(dev) && dev->netdev_ops->ndo_setup_tc) |
|---|
| 54 | | - dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_MQ, &opt); |
|---|
| 49 | + return qdisc_offload_dump_helper(sch, TC_SETUP_QDISC_MQ, &opt); |
|---|
| 55 | 50 | } |
|---|
| 56 | 51 | |
|---|
| 57 | 52 | static void mq_destroy(struct Qdisc *sch) |
|---|
| .. | .. |
|---|
| 172 | 167 | |
|---|
| 173 | 168 | spin_unlock_bh(qdisc_lock(qdisc)); |
|---|
| 174 | 169 | } |
|---|
| 175 | | - mq_offload_stats(sch); |
|---|
| 176 | 170 | |
|---|
| 177 | | - return 0; |
|---|
| 171 | + return mq_offload_stats(sch); |
|---|
| 178 | 172 | } |
|---|
| 179 | 173 | |
|---|
| 180 | 174 | static struct netdev_queue *mq_queue_get(struct Qdisc *sch, unsigned long cl) |
|---|
| .. | .. |
|---|
| 197 | 191 | struct Qdisc **old, struct netlink_ext_ack *extack) |
|---|
| 198 | 192 | { |
|---|
| 199 | 193 | struct netdev_queue *dev_queue = mq_queue_get(sch, cl); |
|---|
| 194 | + struct tc_mq_qopt_offload graft_offload; |
|---|
| 200 | 195 | struct net_device *dev = qdisc_dev(sch); |
|---|
| 201 | 196 | |
|---|
| 202 | 197 | if (dev->flags & IFF_UP) |
|---|
| .. | .. |
|---|
| 207 | 202 | new->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; |
|---|
| 208 | 203 | if (dev->flags & IFF_UP) |
|---|
| 209 | 204 | dev_activate(dev); |
|---|
| 205 | + |
|---|
| 206 | + graft_offload.handle = sch->handle; |
|---|
| 207 | + graft_offload.graft_params.queue = cl - 1; |
|---|
| 208 | + graft_offload.graft_params.child_handle = new ? new->handle : 0; |
|---|
| 209 | + graft_offload.command = TC_MQ_GRAFT; |
|---|
| 210 | + |
|---|
| 211 | + qdisc_offload_graft_helper(qdisc_dev(sch), sch, new, *old, |
|---|
| 212 | + TC_SETUP_QDISC_MQ, &graft_offload, extack); |
|---|
| 210 | 213 | return 0; |
|---|
| 211 | 214 | } |
|---|
| 212 | 215 | |
|---|
| .. | .. |
|---|
| 245 | 248 | sch = dev_queue->qdisc_sleeping; |
|---|
| 246 | 249 | if (gnet_stats_copy_basic(&sch->running, d, sch->cpu_bstats, |
|---|
| 247 | 250 | &sch->bstats) < 0 || |
|---|
| 248 | | - gnet_stats_copy_queue(d, NULL, &sch->qstats, sch->q.qlen) < 0) |
|---|
| 251 | + qdisc_qstats_copy(d, sch) < 0) |
|---|
| 249 | 252 | return -1; |
|---|
| 250 | 253 | return 0; |
|---|
| 251 | 254 | } |
|---|