Commit 926e61b7c44db83013159ac2f74bccd451607b5a
Committed by
David S. Miller
1 parent
ca519274d5
Exists in
master
and in
39 other branches
pkt_sched: Fix tx queue selection in tc_modify_qdisc
After the recent mq change there is the new select_queue qdisc class method used in tc_modify_qdisc, but it works OK only for direct child qdiscs of mq qdisc. Grandchildren always get the first tx queue, which would give wrong qdisc_root etc. results (e.g. for sch_htb as child of sch_prio). This patch fixes it by using parent's dev_queue for such grandchildren qdiscs. The select_queue method's return type is changed BTW. With feedback from: Patrick McHardy <kaber@trash.net> Signed-off-by: Jarek Poplawski <jarkao2@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 3 changed files with 17 additions and 8 deletions Side-by-side Diff
include/net/sch_generic.h
... | ... | @@ -81,7 +81,7 @@ |
81 | 81 | struct Qdisc_class_ops |
82 | 82 | { |
83 | 83 | /* Child qdisc manipulation */ |
84 | - unsigned int (*select_queue)(struct Qdisc *, struct tcmsg *); | |
84 | + struct netdev_queue * (*select_queue)(struct Qdisc *, struct tcmsg *); | |
85 | 85 | int (*graft)(struct Qdisc *, unsigned long cl, |
86 | 86 | struct Qdisc *, struct Qdisc **); |
87 | 87 | struct Qdisc * (*leaf)(struct Qdisc *, unsigned long cl); |
net/sched/sch_api.c
... | ... | @@ -1116,12 +1116,16 @@ |
1116 | 1116 | tcm->tcm_parent, tcm->tcm_parent, |
1117 | 1117 | tca, &err); |
1118 | 1118 | else { |
1119 | - unsigned int ntx = 0; | |
1119 | + struct netdev_queue *dev_queue; | |
1120 | 1120 | |
1121 | 1121 | if (p && p->ops->cl_ops && p->ops->cl_ops->select_queue) |
1122 | - ntx = p->ops->cl_ops->select_queue(p, tcm); | |
1122 | + dev_queue = p->ops->cl_ops->select_queue(p, tcm); | |
1123 | + else if (p) | |
1124 | + dev_queue = p->dev_queue; | |
1125 | + else | |
1126 | + dev_queue = netdev_get_tx_queue(dev, 0); | |
1123 | 1127 | |
1124 | - q = qdisc_create(dev, netdev_get_tx_queue(dev, ntx), p, | |
1128 | + q = qdisc_create(dev, dev_queue, p, | |
1125 | 1129 | tcm->tcm_parent, tcm->tcm_handle, |
1126 | 1130 | tca, &err); |
1127 | 1131 | } |
net/sched/sch_mq.c
... | ... | @@ -125,13 +125,18 @@ |
125 | 125 | return netdev_get_tx_queue(dev, ntx); |
126 | 126 | } |
127 | 127 | |
128 | -static unsigned int mq_select_queue(struct Qdisc *sch, struct tcmsg *tcm) | |
128 | +static struct netdev_queue *mq_select_queue(struct Qdisc *sch, | |
129 | + struct tcmsg *tcm) | |
129 | 130 | { |
130 | 131 | unsigned int ntx = TC_H_MIN(tcm->tcm_parent); |
132 | + struct netdev_queue *dev_queue = mq_queue_get(sch, ntx); | |
131 | 133 | |
132 | - if (!mq_queue_get(sch, ntx)) | |
133 | - return 0; | |
134 | - return ntx - 1; | |
134 | + if (!dev_queue) { | |
135 | + struct net_device *dev = qdisc_dev(sch); | |
136 | + | |
137 | + return netdev_get_tx_queue(dev, 0); | |
138 | + } | |
139 | + return dev_queue; | |
135 | 140 | } |
136 | 141 | |
137 | 142 | static int mq_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new, |