hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/net/sched/sch_multiq.c
....@@ -1,17 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2008, Intel Corporation.
3
- *
4
- * This program is free software; you can redistribute it and/or modify it
5
- * under the terms and conditions of the GNU General Public License,
6
- * version 2, as published by the Free Software Foundation.
7
- *
8
- * This program is distributed in the hope it will be useful, but WITHOUT
9
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11
- * more details.
12
- *
13
- * You should have received a copy of the GNU General Public License along with
14
- * this program; if not, see <http://www.gnu.org/licenses/>.
154 *
165 * Author: Alexander Duyck <alexander.h.duyck@intel.com>
176 */
....@@ -54,7 +43,7 @@
5443 case TC_ACT_QUEUED:
5544 case TC_ACT_TRAP:
5645 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
57
- /* fall through */
46
+ fallthrough;
5847 case TC_ACT_SHOT:
5948 return NULL;
6049 }
....@@ -163,7 +152,6 @@
163152
164153 for (band = 0; band < q->bands; band++)
165154 qdisc_reset(q->queues[band]);
166
- sch->q.qlen = 0;
167155 q->curband = 0;
168156 }
169157
....@@ -185,7 +173,8 @@
185173 {
186174 struct multiq_sched_data *q = qdisc_priv(sch);
187175 struct tc_multiq_qopt *qopt;
188
- int i;
176
+ struct Qdisc **removed;
177
+ int i, n_removed = 0;
189178
190179 if (!netif_is_multiqueue(qdisc_dev(sch)))
191180 return -EOPNOTSUPP;
....@@ -196,19 +185,28 @@
196185
197186 qopt->bands = qdisc_dev(sch)->real_num_tx_queues;
198187
188
+ removed = kmalloc(sizeof(*removed) * (q->max_bands - q->bands),
189
+ GFP_KERNEL);
190
+ if (!removed)
191
+ return -ENOMEM;
192
+
199193 sch_tree_lock(sch);
200194 q->bands = qopt->bands;
201195 for (i = q->bands; i < q->max_bands; i++) {
202196 if (q->queues[i] != &noop_qdisc) {
203197 struct Qdisc *child = q->queues[i];
198
+
204199 q->queues[i] = &noop_qdisc;
205
- qdisc_tree_reduce_backlog(child, child->q.qlen,
206
- child->qstats.backlog);
207
- qdisc_put(child);
200
+ qdisc_purge_queue(child);
201
+ removed[n_removed++] = child;
208202 }
209203 }
210204
211205 sch_tree_unlock(sch);
206
+
207
+ for (i = 0; i < n_removed; i++)
208
+ qdisc_put(removed[i]);
209
+ kfree(removed);
212210
213211 for (i = 0; i < q->bands; i++) {
214212 if (q->queues[i] == &noop_qdisc) {
....@@ -224,13 +222,10 @@
224222 if (child != &noop_qdisc)
225223 qdisc_hash_add(child, true);
226224
227
- if (old != &noop_qdisc) {
228
- qdisc_tree_reduce_backlog(old,
229
- old->q.qlen,
230
- old->qstats.backlog);
231
- qdisc_put(old);
232
- }
225
+ if (old != &noop_qdisc)
226
+ qdisc_purge_queue(old);
233227 sch_tree_unlock(sch);
228
+ qdisc_put(old);
234229 }
235230 }
236231 }
....@@ -344,7 +339,7 @@
344339 cl_q = q->queues[cl - 1];
345340 if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch),
346341 d, cl_q->cpu_bstats, &cl_q->bstats) < 0 ||
347
- gnet_stats_copy_queue(d, NULL, &cl_q->qstats, cl_q->q.qlen) < 0)
342
+ qdisc_qstats_copy(d, cl_q) < 0)
348343 return -1;
349344
350345 return 0;