hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/sched/sch_mqprio.c
....@@ -1,11 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * net/sched/sch_mqprio.c
34 *
45 * Copyright (c) 2010 John Fastabend <john.r.fastabend@intel.com>
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.
96 */
107
118 #include <linux/types.h>
....@@ -125,10 +122,102 @@
125122 int nested_len = nla_len(nla) - NLA_ALIGN(len);
126123
127124 if (nested_len >= nla_attr_size(0))
128
- return nla_parse(tb, maxtype, nla_data(nla) + NLA_ALIGN(len),
129
- nested_len, policy, NULL);
125
+ return nla_parse_deprecated(tb, maxtype,
126
+ nla_data(nla) + NLA_ALIGN(len),
127
+ nested_len, policy, NULL);
130128
131129 memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
130
+ return 0;
131
+}
132
+
133
+static int mqprio_parse_nlattr(struct Qdisc *sch, struct tc_mqprio_qopt *qopt,
134
+ struct nlattr *opt,
135
+ struct netlink_ext_ack *extack)
136
+{
137
+ struct mqprio_sched *priv = qdisc_priv(sch);
138
+ struct nlattr *tb[TCA_MQPRIO_MAX + 1];
139
+ struct nlattr *attr;
140
+ int i, rem, err;
141
+
142
+ err = parse_attr(tb, TCA_MQPRIO_MAX, opt, mqprio_policy,
143
+ sizeof(*qopt));
144
+ if (err < 0)
145
+ return err;
146
+
147
+ if (!qopt->hw) {
148
+ NL_SET_ERR_MSG(extack,
149
+ "mqprio TCA_OPTIONS can only contain netlink attributes in hardware mode");
150
+ return -EINVAL;
151
+ }
152
+
153
+ if (tb[TCA_MQPRIO_MODE]) {
154
+ priv->flags |= TC_MQPRIO_F_MODE;
155
+ priv->mode = *(u16 *)nla_data(tb[TCA_MQPRIO_MODE]);
156
+ }
157
+
158
+ if (tb[TCA_MQPRIO_SHAPER]) {
159
+ priv->flags |= TC_MQPRIO_F_SHAPER;
160
+ priv->shaper = *(u16 *)nla_data(tb[TCA_MQPRIO_SHAPER]);
161
+ }
162
+
163
+ if (tb[TCA_MQPRIO_MIN_RATE64]) {
164
+ if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) {
165
+ NL_SET_ERR_MSG_ATTR(extack, tb[TCA_MQPRIO_MIN_RATE64],
166
+ "min_rate accepted only when shaper is in bw_rlimit mode");
167
+ return -EINVAL;
168
+ }
169
+ i = 0;
170
+ nla_for_each_nested(attr, tb[TCA_MQPRIO_MIN_RATE64],
171
+ rem) {
172
+ if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64) {
173
+ NL_SET_ERR_MSG_ATTR(extack, attr,
174
+ "Attribute type expected to be TCA_MQPRIO_MIN_RATE64");
175
+ return -EINVAL;
176
+ }
177
+
178
+ if (nla_len(attr) != sizeof(u64)) {
179
+ NL_SET_ERR_MSG_ATTR(extack, attr,
180
+ "Attribute TCA_MQPRIO_MIN_RATE64 expected to have 8 bytes length");
181
+ return -EINVAL;
182
+ }
183
+
184
+ if (i >= qopt->num_tc)
185
+ break;
186
+ priv->min_rate[i] = *(u64 *)nla_data(attr);
187
+ i++;
188
+ }
189
+ priv->flags |= TC_MQPRIO_F_MIN_RATE;
190
+ }
191
+
192
+ if (tb[TCA_MQPRIO_MAX_RATE64]) {
193
+ if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) {
194
+ NL_SET_ERR_MSG_ATTR(extack, tb[TCA_MQPRIO_MAX_RATE64],
195
+ "max_rate accepted only when shaper is in bw_rlimit mode");
196
+ return -EINVAL;
197
+ }
198
+ i = 0;
199
+ nla_for_each_nested(attr, tb[TCA_MQPRIO_MAX_RATE64],
200
+ rem) {
201
+ if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64) {
202
+ NL_SET_ERR_MSG_ATTR(extack, attr,
203
+ "Attribute type expected to be TCA_MQPRIO_MAX_RATE64");
204
+ return -EINVAL;
205
+ }
206
+
207
+ if (nla_len(attr) != sizeof(u64)) {
208
+ NL_SET_ERR_MSG_ATTR(extack, attr,
209
+ "Attribute TCA_MQPRIO_MAX_RATE64 expected to have 8 bytes length");
210
+ return -EINVAL;
211
+ }
212
+
213
+ if (i >= qopt->num_tc)
214
+ break;
215
+ priv->max_rate[i] = *(u64 *)nla_data(attr);
216
+ i++;
217
+ }
218
+ priv->flags |= TC_MQPRIO_F_MAX_RATE;
219
+ }
220
+
132221 return 0;
133222 }
134223
....@@ -141,9 +230,6 @@
141230 struct Qdisc *qdisc;
142231 int i, err = -EOPNOTSUPP;
143232 struct tc_mqprio_qopt *qopt = NULL;
144
- struct nlattr *tb[TCA_MQPRIO_MAX + 1];
145
- struct nlattr *attr;
146
- int rem;
147233 int len;
148234
149235 BUILD_BUG_ON(TC_MAX_QUEUE != TC_QOPT_MAX_QUEUE);
....@@ -168,55 +254,9 @@
168254
169255 len = nla_len(opt) - NLA_ALIGN(sizeof(*qopt));
170256 if (len > 0) {
171
- err = parse_attr(tb, TCA_MQPRIO_MAX, opt, mqprio_policy,
172
- sizeof(*qopt));
173
- if (err < 0)
257
+ err = mqprio_parse_nlattr(sch, qopt, opt, extack);
258
+ if (err)
174259 return err;
175
-
176
- if (!qopt->hw)
177
- return -EINVAL;
178
-
179
- if (tb[TCA_MQPRIO_MODE]) {
180
- priv->flags |= TC_MQPRIO_F_MODE;
181
- priv->mode = *(u16 *)nla_data(tb[TCA_MQPRIO_MODE]);
182
- }
183
-
184
- if (tb[TCA_MQPRIO_SHAPER]) {
185
- priv->flags |= TC_MQPRIO_F_SHAPER;
186
- priv->shaper = *(u16 *)nla_data(tb[TCA_MQPRIO_SHAPER]);
187
- }
188
-
189
- if (tb[TCA_MQPRIO_MIN_RATE64]) {
190
- if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE)
191
- return -EINVAL;
192
- i = 0;
193
- nla_for_each_nested(attr, tb[TCA_MQPRIO_MIN_RATE64],
194
- rem) {
195
- if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64)
196
- return -EINVAL;
197
- if (i >= qopt->num_tc)
198
- break;
199
- priv->min_rate[i] = *(u64 *)nla_data(attr);
200
- i++;
201
- }
202
- priv->flags |= TC_MQPRIO_F_MIN_RATE;
203
- }
204
-
205
- if (tb[TCA_MQPRIO_MAX_RATE64]) {
206
- if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE)
207
- return -EINVAL;
208
- i = 0;
209
- nla_for_each_nested(attr, tb[TCA_MQPRIO_MAX_RATE64],
210
- rem) {
211
- if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64)
212
- return -EINVAL;
213
- if (i >= qopt->num_tc)
214
- break;
215
- priv->max_rate[i] = *(u64 *)nla_data(attr);
216
- i++;
217
- }
218
- priv->flags |= TC_MQPRIO_F_MAX_RATE;
219
- }
220260 }
221261
222262 /* pre-allocate qdisc, attachment can't fail */
....@@ -349,7 +389,7 @@
349389 int i;
350390
351391 if (priv->flags & TC_MQPRIO_F_MIN_RATE) {
352
- nest = nla_nest_start(skb, TCA_MQPRIO_MIN_RATE64);
392
+ nest = nla_nest_start_noflag(skb, TCA_MQPRIO_MIN_RATE64);
353393 if (!nest)
354394 goto nla_put_failure;
355395
....@@ -363,7 +403,7 @@
363403 }
364404
365405 if (priv->flags & TC_MQPRIO_F_MAX_RATE) {
366
- nest = nla_nest_start(skb, TCA_MQPRIO_MAX_RATE64);
406
+ nest = nla_nest_start_noflag(skb, TCA_MQPRIO_MAX_RATE64);
367407 if (!nest)
368408 goto nla_put_failure;
369409
....@@ -568,8 +608,7 @@
568608 sch = dev_queue->qdisc_sleeping;
569609 if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch), d,
570610 sch->cpu_bstats, &sch->bstats) < 0 ||
571
- gnet_stats_copy_queue(d, NULL,
572
- &sch->qstats, sch->q.qlen) < 0)
611
+ qdisc_qstats_copy(d, sch) < 0)
573612 return -1;
574613 }
575614 return 0;