sch_mqprio.c (e4655e4a79133503ceec1dcd2f92734293b25610) sch_mqprio.c (32302902ff093891d8e64439cbb8ceae83e21ef8)
1/*
2 * net/sched/sch_mqprio.c
3 *
4 * 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.

--- 139 unchanged lines hidden (view full) ---

148 BUILD_BUG_ON(TC_BITMASK != TC_QOPT_BITMASK);
149
150 if (sch->parent != TC_H_ROOT)
151 return -EOPNOTSUPP;
152
153 if (!netif_is_multiqueue(dev))
154 return -EOPNOTSUPP;
155
1/*
2 * net/sched/sch_mqprio.c
3 *
4 * 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.

--- 139 unchanged lines hidden (view full) ---

148 BUILD_BUG_ON(TC_BITMASK != TC_QOPT_BITMASK);
149
150 if (sch->parent != TC_H_ROOT)
151 return -EOPNOTSUPP;
152
153 if (!netif_is_multiqueue(dev))
154 return -EOPNOTSUPP;
155
156 /* make certain can allocate enough classids to handle queues */
157 if (dev->num_tx_queues >= TC_H_MIN_PRIORITY)
158 return -ENOMEM;
159
156 if (!opt || nla_len(opt) < sizeof(*qopt))
157 return -EINVAL;
158
159 qopt = nla_data(opt);
160 if (mqprio_parse_opt(dev, qopt))
161 return -EINVAL;
162
163 if (len > 0) {

--- 136 unchanged lines hidden (view full) ---

300 kfree(priv->qdiscs);
301 priv->qdiscs = NULL;
302}
303
304static struct netdev_queue *mqprio_queue_get(struct Qdisc *sch,
305 unsigned long cl)
306{
307 struct net_device *dev = qdisc_dev(sch);
160 if (!opt || nla_len(opt) < sizeof(*qopt))
161 return -EINVAL;
162
163 qopt = nla_data(opt);
164 if (mqprio_parse_opt(dev, qopt))
165 return -EINVAL;
166
167 if (len > 0) {

--- 136 unchanged lines hidden (view full) ---

304 kfree(priv->qdiscs);
305 priv->qdiscs = NULL;
306}
307
308static struct netdev_queue *mqprio_queue_get(struct Qdisc *sch,
309 unsigned long cl)
310{
311 struct net_device *dev = qdisc_dev(sch);
308 unsigned long ntx = cl - 1 - netdev_get_num_tc(dev);
312 unsigned long ntx = cl - 1;
309
310 if (ntx >= dev->num_tx_queues)
311 return NULL;
312 return netdev_get_tx_queue(dev, ntx);
313}
314
315static int mqprio_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new,
316 struct Qdisc **old)

--- 125 unchanged lines hidden (view full) ---

442 return dev_queue->qdisc_sleeping;
443}
444
445static unsigned long mqprio_find(struct Qdisc *sch, u32 classid)
446{
447 struct net_device *dev = qdisc_dev(sch);
448 unsigned int ntx = TC_H_MIN(classid);
449
313
314 if (ntx >= dev->num_tx_queues)
315 return NULL;
316 return netdev_get_tx_queue(dev, ntx);
317}
318
319static int mqprio_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new,
320 struct Qdisc **old)

--- 125 unchanged lines hidden (view full) ---

446 return dev_queue->qdisc_sleeping;
447}
448
449static unsigned long mqprio_find(struct Qdisc *sch, u32 classid)
450{
451 struct net_device *dev = qdisc_dev(sch);
452 unsigned int ntx = TC_H_MIN(classid);
453
450 if (ntx > dev->num_tx_queues + netdev_get_num_tc(dev))
451 return 0;
452 return ntx;
454 /* There are essentially two regions here that have valid classid
455 * values. The first region will have a classid value of 1 through
456 * num_tx_queues. All of these are backed by actual Qdiscs.
457 */
458 if (ntx < TC_H_MIN_PRIORITY)
459 return (ntx <= dev->num_tx_queues) ? ntx : 0;
460
461 /* The second region represents the hardware traffic classes. These
462 * are represented by classid values of TC_H_MIN_PRIORITY through
463 * TC_H_MIN_PRIORITY + netdev_get_num_tc - 1
464 */
465 return ((ntx - TC_H_MIN_PRIORITY) < netdev_get_num_tc(dev)) ? ntx : 0;
453}
454
455static int mqprio_dump_class(struct Qdisc *sch, unsigned long cl,
456 struct sk_buff *skb, struct tcmsg *tcm)
457{
466}
467
468static int mqprio_dump_class(struct Qdisc *sch, unsigned long cl,
469 struct sk_buff *skb, struct tcmsg *tcm)
470{
458 struct net_device *dev = qdisc_dev(sch);
471 if (cl < TC_H_MIN_PRIORITY) {
472 struct netdev_queue *dev_queue = mqprio_queue_get(sch, cl);
473 struct net_device *dev = qdisc_dev(sch);
474 int tc = netdev_txq_to_tc(dev, cl - 1);
459
475
460 if (cl <= netdev_get_num_tc(dev)) {
476 tcm->tcm_parent = (tc < 0) ? 0 :
477 TC_H_MAKE(TC_H_MAJ(sch->handle),
478 TC_H_MIN(tc + TC_H_MIN_PRIORITY));
479 tcm->tcm_info = dev_queue->qdisc_sleeping->handle;
480 } else {
461 tcm->tcm_parent = TC_H_ROOT;
462 tcm->tcm_info = 0;
481 tcm->tcm_parent = TC_H_ROOT;
482 tcm->tcm_info = 0;
463 } else {
464 int i;
465 struct netdev_queue *dev_queue;
466
467 dev_queue = mqprio_queue_get(sch, cl);
468 tcm->tcm_parent = 0;
469 for (i = 0; i < netdev_get_num_tc(dev); i++) {
470 struct netdev_tc_txq tc = dev->tc_to_txq[i];
471 int q_idx = cl - netdev_get_num_tc(dev);
472
473 if (q_idx > tc.offset &&
474 q_idx <= tc.offset + tc.count) {
475 tcm->tcm_parent =
476 TC_H_MAKE(TC_H_MAJ(sch->handle),
477 TC_H_MIN(i + 1));
478 break;
479 }
480 }
481 tcm->tcm_info = dev_queue->qdisc_sleeping->handle;
482 }
483 tcm->tcm_handle |= TC_H_MIN(cl);
484 return 0;
485}
486
487static int mqprio_dump_class_stats(struct Qdisc *sch, unsigned long cl,
488 struct gnet_dump *d)
489 __releases(d->lock)
490 __acquires(d->lock)
491{
483 }
484 tcm->tcm_handle |= TC_H_MIN(cl);
485 return 0;
486}
487
488static int mqprio_dump_class_stats(struct Qdisc *sch, unsigned long cl,
489 struct gnet_dump *d)
490 __releases(d->lock)
491 __acquires(d->lock)
492{
492 struct net_device *dev = qdisc_dev(sch);
493
494 if (cl <= netdev_get_num_tc(dev)) {
493 if (cl >= TC_H_MIN_PRIORITY) {
495 int i;
496 __u32 qlen = 0;
497 struct Qdisc *qdisc;
498 struct gnet_stats_queue qstats = {0};
499 struct gnet_stats_basic_packed bstats = {0};
494 int i;
495 __u32 qlen = 0;
496 struct Qdisc *qdisc;
497 struct gnet_stats_queue qstats = {0};
498 struct gnet_stats_basic_packed bstats = {0};
500 struct netdev_tc_txq tc = dev->tc_to_txq[cl - 1];
499 struct net_device *dev = qdisc_dev(sch);
500 struct netdev_tc_txq tc = dev->tc_to_txq[cl & TC_BITMASK];
501
502 /* Drop lock here it will be reclaimed before touching
503 * statistics this is required because the d->lock we
504 * hold here is the look on dev_queue->qdisc_sleeping
505 * also acquired below.
506 */
507 if (d->lock)
508 spin_unlock_bh(d->lock);

--- 36 unchanged lines hidden (view full) ---

545 struct net_device *dev = qdisc_dev(sch);
546 unsigned long ntx;
547
548 if (arg->stop)
549 return;
550
551 /* Walk hierarchy with a virtual class per tc */
552 arg->count = arg->skip;
501
502 /* Drop lock here it will be reclaimed before touching
503 * statistics this is required because the d->lock we
504 * hold here is the look on dev_queue->qdisc_sleeping
505 * also acquired below.
506 */
507 if (d->lock)
508 spin_unlock_bh(d->lock);

--- 36 unchanged lines hidden (view full) ---

545 struct net_device *dev = qdisc_dev(sch);
546 unsigned long ntx;
547
548 if (arg->stop)
549 return;
550
551 /* Walk hierarchy with a virtual class per tc */
552 arg->count = arg->skip;
553 for (ntx = arg->skip;
554 ntx < dev->num_tx_queues + netdev_get_num_tc(dev);
555 ntx++) {
553 for (ntx = arg->skip; ntx < netdev_get_num_tc(dev); ntx++) {
554 if (arg->fn(sch, ntx + TC_H_MIN_PRIORITY, arg) < 0) {
555 arg->stop = 1;
556 return;
557 }
558 arg->count++;
559 }
560
561 /* Pad the values and skip over unused traffic classes */
562 if (ntx < TC_MAX_QUEUE) {
563 arg->count = TC_MAX_QUEUE;
564 ntx = TC_MAX_QUEUE;
565 }
566
567 /* Reset offset, sort out remaining per-queue qdiscs */
568 for (ntx -= TC_MAX_QUEUE; ntx < dev->num_tx_queues; ntx++) {
556 if (arg->fn(sch, ntx + 1, arg) < 0) {
557 arg->stop = 1;
569 if (arg->fn(sch, ntx + 1, arg) < 0) {
570 arg->stop = 1;
558 break;
571 return;
559 }
560 arg->count++;
561 }
562}
563
564static const struct Qdisc_class_ops mqprio_class_ops = {
565 .graft = mqprio_graft,
566 .leaf = mqprio_leaf,

--- 31 unchanged lines hidden ---
572 }
573 arg->count++;
574 }
575}
576
577static const struct Qdisc_class_ops mqprio_class_ops = {
578 .graft = mqprio_graft,
579 .leaf = mqprio_leaf,

--- 31 unchanged lines hidden ---