From 926e61b7c44db83013159ac2f74bccd451607b5a Mon Sep 17 00:00:00 2001 From: Jarek Poplawski Date: Tue, 15 Sep 2009 02:53:07 -0700 Subject: 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 Signed-off-by: Jarek Poplawski Signed-off-by: David S. Miller --- net/sched/sch_mq.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'net/sched/sch_mq.c') diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c index dd5ee022f1f7..600c50143cc7 100644 --- a/net/sched/sch_mq.c +++ b/net/sched/sch_mq.c @@ -125,13 +125,18 @@ static struct netdev_queue *mq_queue_get(struct Qdisc *sch, unsigned long cl) return netdev_get_tx_queue(dev, ntx); } -static unsigned int mq_select_queue(struct Qdisc *sch, struct tcmsg *tcm) +static struct netdev_queue *mq_select_queue(struct Qdisc *sch, + struct tcmsg *tcm) { unsigned int ntx = TC_H_MIN(tcm->tcm_parent); + struct netdev_queue *dev_queue = mq_queue_get(sch, ntx); - if (!mq_queue_get(sch, ntx)) - return 0; - return ntx - 1; + if (!dev_queue) { + struct net_device *dev = qdisc_dev(sch); + + return netdev_get_tx_queue(dev, 0); + } + return dev_queue; } static int mq_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new, -- cgit v1.2.3-59-g8ed1b