Lines Matching +full:pre +full:- +full:verified
1 // SPDX-License-Identifier: GPL-2.0-only
36 if (priv->qdiscs) { in mqprio_destroy()
38 ntx < dev->num_tx_queues && priv->qdiscs[ntx]; in mqprio_destroy()
40 qdisc_put(priv->qdiscs[ntx]); in mqprio_destroy()
41 kfree(priv->qdiscs); in mqprio_destroy()
44 if (priv->hw_offload && dev->netdev_ops->ndo_setup_tc) { in mqprio_destroy()
47 switch (priv->mode) { in mqprio_destroy()
50 dev->netdev_ops->ndo_setup_tc(dev, in mqprio_destroy()
67 if (qopt->num_tc > TC_MAX_QUEUE) in mqprio_parse_opt()
68 return -EINVAL; in mqprio_parse_opt()
72 if (qopt->prio_tc_map[i] >= qopt->num_tc) in mqprio_parse_opt()
73 return -EINVAL; in mqprio_parse_opt()
76 /* Limit qopt->hw to maximum supported offload value. Drivers have in mqprio_parse_opt()
80 if (qopt->hw > TC_MQPRIO_HW_OFFLOAD_MAX) in mqprio_parse_opt()
81 qopt->hw = TC_MQPRIO_HW_OFFLOAD_MAX; in mqprio_parse_opt()
88 if (qopt->hw) in mqprio_parse_opt()
89 return dev->netdev_ops->ndo_setup_tc ? 0 : -EINVAL; in mqprio_parse_opt()
91 for (i = 0; i < qopt->num_tc; i++) { in mqprio_parse_opt()
92 unsigned int last = qopt->offset[i] + qopt->count[i]; in mqprio_parse_opt()
97 if (qopt->offset[i] >= dev->real_num_tx_queues || in mqprio_parse_opt()
98 !qopt->count[i] || in mqprio_parse_opt()
99 last > dev->real_num_tx_queues) in mqprio_parse_opt()
100 return -EINVAL; in mqprio_parse_opt()
103 for (j = i + 1; j < qopt->num_tc; j++) { in mqprio_parse_opt()
104 if (last > qopt->offset[j]) in mqprio_parse_opt()
105 return -EINVAL; in mqprio_parse_opt()
122 int nested_len = nla_len(nla) - NLA_ALIGN(len); in parse_attr()
140 int i, err = -EOPNOTSUPP; in mqprio_init()
150 if (sch->parent != TC_H_ROOT) in mqprio_init()
151 return -EOPNOTSUPP; in mqprio_init()
154 return -EOPNOTSUPP; in mqprio_init()
157 if (dev->num_tx_queues >= TC_H_MIN_PRIORITY) in mqprio_init()
158 return -ENOMEM; in mqprio_init()
161 return -EINVAL; in mqprio_init()
165 return -EINVAL; in mqprio_init()
167 len = nla_len(opt) - NLA_ALIGN(sizeof(*qopt)); in mqprio_init()
174 if (!qopt->hw) in mqprio_init()
175 return -EINVAL; in mqprio_init()
178 priv->flags |= TC_MQPRIO_F_MODE; in mqprio_init()
179 priv->mode = *(u16 *)nla_data(tb[TCA_MQPRIO_MODE]); in mqprio_init()
183 priv->flags |= TC_MQPRIO_F_SHAPER; in mqprio_init()
184 priv->shaper = *(u16 *)nla_data(tb[TCA_MQPRIO_SHAPER]); in mqprio_init()
188 if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) in mqprio_init()
189 return -EINVAL; in mqprio_init()
194 return -EINVAL; in mqprio_init()
195 if (i >= qopt->num_tc) in mqprio_init()
197 priv->min_rate[i] = *(u64 *)nla_data(attr); in mqprio_init()
200 priv->flags |= TC_MQPRIO_F_MIN_RATE; in mqprio_init()
204 if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) in mqprio_init()
205 return -EINVAL; in mqprio_init()
210 return -EINVAL; in mqprio_init()
211 if (i >= qopt->num_tc) in mqprio_init()
213 priv->max_rate[i] = *(u64 *)nla_data(attr); in mqprio_init()
216 priv->flags |= TC_MQPRIO_F_MAX_RATE; in mqprio_init()
220 /* pre-allocate qdisc, attachment can't fail */ in mqprio_init()
221 priv->qdiscs = kcalloc(dev->num_tx_queues, sizeof(priv->qdiscs[0]), in mqprio_init()
223 if (!priv->qdiscs) in mqprio_init()
224 return -ENOMEM; in mqprio_init()
226 for (i = 0; i < dev->num_tx_queues; i++) { in mqprio_init()
230 TC_H_MAKE(TC_H_MAJ(sch->handle), in mqprio_init()
233 return -ENOMEM; in mqprio_init()
235 priv->qdiscs[i] = qdisc; in mqprio_init()
236 qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; in mqprio_init()
241 * supplied and verified mapping in mqprio_init()
243 if (qopt->hw) { in mqprio_init()
246 switch (priv->mode) { in mqprio_init()
248 if (priv->shaper != TC_MQPRIO_SHAPER_DCB) in mqprio_init()
249 return -EINVAL; in mqprio_init()
252 mqprio.flags = priv->flags; in mqprio_init()
253 if (priv->flags & TC_MQPRIO_F_MODE) in mqprio_init()
254 mqprio.mode = priv->mode; in mqprio_init()
255 if (priv->flags & TC_MQPRIO_F_SHAPER) in mqprio_init()
256 mqprio.shaper = priv->shaper; in mqprio_init()
257 if (priv->flags & TC_MQPRIO_F_MIN_RATE) in mqprio_init()
259 mqprio.min_rate[i] = priv->min_rate[i]; in mqprio_init()
260 if (priv->flags & TC_MQPRIO_F_MAX_RATE) in mqprio_init()
262 mqprio.max_rate[i] = priv->max_rate[i]; in mqprio_init()
265 return -EINVAL; in mqprio_init()
267 err = dev->netdev_ops->ndo_setup_tc(dev, in mqprio_init()
273 priv->hw_offload = mqprio.qopt.hw; in mqprio_init()
275 netdev_set_num_tc(dev, qopt->num_tc); in mqprio_init()
276 for (i = 0; i < qopt->num_tc; i++) in mqprio_init()
278 qopt->count[i], qopt->offset[i]); in mqprio_init()
283 netdev_set_prio_tc_map(dev, i, qopt->prio_tc_map[i]); in mqprio_init()
285 sch->flags |= TCQ_F_MQROOT; in mqprio_init()
297 for (ntx = 0; ntx < dev->num_tx_queues; ntx++) { in mqprio_attach()
298 qdisc = priv->qdiscs[ntx]; in mqprio_attach()
299 old = dev_graft_qdisc(qdisc->dev_queue, qdisc); in mqprio_attach()
302 if (ntx < dev->real_num_tx_queues) in mqprio_attach()
305 kfree(priv->qdiscs); in mqprio_attach()
306 priv->qdiscs = NULL; in mqprio_attach()
313 unsigned long ntx = cl - 1; in mqprio_queue_get()
315 if (ntx >= dev->num_tx_queues) in mqprio_queue_get()
327 return -EINVAL; in mqprio_graft()
329 if (dev->flags & IFF_UP) in mqprio_graft()
335 new->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; in mqprio_graft()
337 if (dev->flags & IFF_UP) in mqprio_graft()
349 if (priv->flags & TC_MQPRIO_F_MIN_RATE) { in dump_rates()
354 for (i = 0; i < opt->num_tc; i++) { in dump_rates()
356 sizeof(priv->min_rate[i]), in dump_rates()
357 &priv->min_rate[i])) in dump_rates()
363 if (priv->flags & TC_MQPRIO_F_MAX_RATE) { in dump_rates()
368 for (i = 0; i < opt->num_tc; i++) { in dump_rates()
370 sizeof(priv->max_rate[i]), in dump_rates()
371 &priv->max_rate[i])) in dump_rates()
380 return -1; in dump_rates()
392 sch->q.qlen = 0; in mqprio_dump()
393 gnet_stats_basic_sync_init(&sch->bstats); in mqprio_dump()
394 memset(&sch->qstats, 0, sizeof(sch->qstats)); in mqprio_dump()
398 * qdiscs. Percpu stats are added to counters in-band and locking in mqprio_dump()
401 for (ntx = 0; ntx < dev->num_tx_queues; ntx++) { in mqprio_dump()
402 qdisc = netdev_get_tx_queue(dev, ntx)->qdisc_sleeping; in mqprio_dump()
405 gnet_stats_add_basic(&sch->bstats, qdisc->cpu_bstats, in mqprio_dump()
406 &qdisc->bstats, false); in mqprio_dump()
407 gnet_stats_add_queue(&sch->qstats, qdisc->cpu_qstats, in mqprio_dump()
408 &qdisc->qstats); in mqprio_dump()
409 sch->q.qlen += qdisc_qlen(qdisc); in mqprio_dump()
415 memcpy(opt.prio_tc_map, dev->prio_tc_map, sizeof(opt.prio_tc_map)); in mqprio_dump()
416 opt.hw = priv->hw_offload; in mqprio_dump()
419 opt.count[tc] = dev->tc_to_txq[tc].count; in mqprio_dump()
420 opt.offset[tc] = dev->tc_to_txq[tc].offset; in mqprio_dump()
426 if ((priv->flags & TC_MQPRIO_F_MODE) && in mqprio_dump()
427 nla_put_u16(skb, TCA_MQPRIO_MODE, priv->mode)) in mqprio_dump()
430 if ((priv->flags & TC_MQPRIO_F_SHAPER) && in mqprio_dump()
431 nla_put_u16(skb, TCA_MQPRIO_SHAPER, priv->shaper)) in mqprio_dump()
434 if ((priv->flags & TC_MQPRIO_F_MIN_RATE || in mqprio_dump()
435 priv->flags & TC_MQPRIO_F_MAX_RATE) && in mqprio_dump()
442 return -1; in mqprio_dump()
452 return dev_queue->qdisc_sleeping; in mqprio_leaf()
465 return (ntx <= dev->num_tx_queues) ? ntx : 0; in mqprio_find()
469 * TC_H_MIN_PRIORITY + netdev_get_num_tc - 1 in mqprio_find()
471 return ((ntx - TC_H_MIN_PRIORITY) < netdev_get_num_tc(dev)) ? ntx : 0; in mqprio_find()
480 int tc = netdev_txq_to_tc(dev, cl - 1); in mqprio_dump_class()
482 tcm->tcm_parent = (tc < 0) ? 0 : in mqprio_dump_class()
483 TC_H_MAKE(TC_H_MAJ(sch->handle), in mqprio_dump_class()
485 tcm->tcm_info = dev_queue->qdisc_sleeping->handle; in mqprio_dump_class()
487 tcm->tcm_parent = TC_H_ROOT; in mqprio_dump_class()
488 tcm->tcm_info = 0; in mqprio_dump_class()
490 tcm->tcm_handle |= TC_H_MIN(cl); in mqprio_dump_class()
496 __releases(d->lock) in mqprio_dump_class_stats()
497 __acquires(d->lock) in mqprio_dump_class_stats()
505 struct netdev_tc_txq tc = dev->tc_to_txq[cl & TC_BITMASK]; in mqprio_dump_class_stats()
509 * statistics this is required because the d->lock we in mqprio_dump_class_stats()
510 * hold here is the look on dev_queue->qdisc_sleeping in mqprio_dump_class_stats()
513 if (d->lock) in mqprio_dump_class_stats()
514 spin_unlock_bh(d->lock); in mqprio_dump_class_stats()
518 struct Qdisc *qdisc = rtnl_dereference(q->qdisc); in mqprio_dump_class_stats()
522 gnet_stats_add_basic(&bstats, qdisc->cpu_bstats, in mqprio_dump_class_stats()
523 &qdisc->bstats, false); in mqprio_dump_class_stats()
524 gnet_stats_add_queue(&qstats, qdisc->cpu_qstats, in mqprio_dump_class_stats()
525 &qdisc->qstats); in mqprio_dump_class_stats()
526 sch->q.qlen += qdisc_qlen(qdisc); in mqprio_dump_class_stats()
533 if (d->lock) in mqprio_dump_class_stats()
534 spin_lock_bh(d->lock); in mqprio_dump_class_stats()
537 return -1; in mqprio_dump_class_stats()
541 sch = dev_queue->qdisc_sleeping; in mqprio_dump_class_stats()
542 if (gnet_stats_copy_basic(d, sch->cpu_bstats, in mqprio_dump_class_stats()
543 &sch->bstats, true) < 0 || in mqprio_dump_class_stats()
545 return -1; in mqprio_dump_class_stats()
555 if (arg->stop) in mqprio_walk()
559 arg->count = arg->skip; in mqprio_walk()
560 for (ntx = arg->skip; ntx < netdev_get_num_tc(dev); ntx++) { in mqprio_walk()
567 arg->count = TC_MAX_QUEUE; in mqprio_walk()
571 /* Reset offset, sort out remaining per-queue qdiscs */ in mqprio_walk()
572 for (ntx -= TC_MAX_QUEUE; ntx < dev->num_tx_queues; ntx++) { in mqprio_walk()
573 if (arg->fn(sch, ntx + 1, arg) < 0) { in mqprio_walk()
574 arg->stop = 1; in mqprio_walk()
577 arg->count++; in mqprio_walk()
584 return mqprio_queue_get(sch, TC_H_MIN(tcm->tcm_parent)); in mqprio_select_queue()