diff options
author | David S. Miller <davem@davemloft.net> | 2021-09-15 15:46:02 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-09-15 15:46:02 +0100 |
commit | dc50b930be89b82acc21bdefd24df863e47d5cf1 (patch) | |
tree | dc03eaceb78890ddd8421e13e88b8cae1d1820a0 /net | |
parent | c506cc5bc6e33a20ca615043aa3ddb2da4b8c210 (diff) | |
parent | 2d6a58996ee23f85745a8e42edaad7a2b86d1a83 (diff) | |
download | linux-dc50b930be89b82acc21bdefd24df863e47d5cf1.tar.gz linux-dc50b930be89b82acc21bdefd24df863e47d5cf1.tar.bz2 linux-dc50b930be89b82acc21bdefd24df863e47d5cf1.zip |
Merge branch 'qdisc-visibility'
Jakub Kicinski says:
====================
net: sched: update default qdisc visibility after Tx queue cnt changes
Matthew noticed that number of children reported by mq does not match
number of queues on reconfigured interfaces. For example if mq is
instantiated when there is 8 queues it will always show 8 children,
regardless of config being changed:
# ethtool -L eth0 combined 8
# tc qdisc replace dev eth0 root handle 100: mq
# tc qdisc show dev eth0
qdisc mq 100: root
qdisc pfifo_fast 0: parent 100:8 bands 3 priomap 1 2 ...
qdisc pfifo_fast 0: parent 100:7 bands 3 priomap 1 2 ...
qdisc pfifo_fast 0: parent 100:6 bands 3 priomap 1 2 ...
qdisc pfifo_fast 0: parent 100:5 bands 3 priomap 1 2 ...
qdisc pfifo_fast 0: parent 100:4 bands 3 priomap 1 2 ...
qdisc pfifo_fast 0: parent 100:3 bands 3 priomap 1 2 ...
qdisc pfifo_fast 0: parent 100:2 bands 3 priomap 1 2 ...
qdisc pfifo_fast 0: parent 100:1 bands 3 priomap 1 2 ...
# ethtool -L eth0 combined 1
# tc qdisc show dev eth0
qdisc mq 100: root
qdisc pfifo_fast 0: parent 100:8 bands 3 priomap 1 2 ...
qdisc pfifo_fast 0: parent 100:7 bands 3 priomap 1 2 ...
qdisc pfifo_fast 0: parent 100:6 bands 3 priomap 1 2 ...
qdisc pfifo_fast 0: parent 100:5 bands 3 priomap 1 2 ...
qdisc pfifo_fast 0: parent 100:4 bands 3 priomap 1 2 ...
qdisc pfifo_fast 0: parent 100:3 bands 3 priomap 1 2 ...
qdisc pfifo_fast 0: parent 100:2 bands 3 priomap 1 2 ...
qdisc pfifo_fast 0: parent 100:1 bands 3 priomap 1 2 ...
# ethtool -L eth0 combined 32
# tc qdisc show dev eth0
qdisc mq 100: root
qdisc pfifo_fast 0: parent 100:8 bands 3 priomap 1 2 ...
qdisc pfifo_fast 0: parent 100:7 bands 3 priomap 1 2 ...
qdisc pfifo_fast 0: parent 100:6 bands 3 priomap 1 2 ...
qdisc pfifo_fast 0: parent 100:5 bands 3 priomap 1 2 ...
qdisc pfifo_fast 0: parent 100:4 bands 3 priomap 1 2 ...
qdisc pfifo_fast 0: parent 100:3 bands 3 priomap 1 2 ...
qdisc pfifo_fast 0: parent 100:2 bands 3 priomap 1 2 ...
qdisc pfifo_fast 0: parent 100:1 bands 3 priomap 1 2 ...
This patchset fixes this by hashing and unhasing the default
child qdiscs as number of queues gets adjusted.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/dev.c | 2 | ||||
-rw-r--r-- | net/sched/sch_generic.c | 9 | ||||
-rw-r--r-- | net/sched/sch_mq.c | 24 | ||||
-rw-r--r-- | net/sched/sch_mqprio.c | 23 |
4 files changed, 58 insertions, 0 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 74fd402d26dd..f930329f0dc2 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2921,6 +2921,8 @@ int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq) if (dev->num_tc) netif_setup_tc(dev, txq); + dev_qdisc_change_real_num_tx(dev, txq); + dev->real_num_tx_queues = txq; if (disabling) { diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index a8dd06c74e31..66d2fbe9ef50 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -1330,6 +1330,15 @@ static int qdisc_change_tx_queue_len(struct net_device *dev, return 0; } +void dev_qdisc_change_real_num_tx(struct net_device *dev, + unsigned int new_real_tx) +{ + struct Qdisc *qdisc = dev->qdisc; + + if (qdisc->ops->change_real_num_tx) + qdisc->ops->change_real_num_tx(qdisc, new_real_tx); +} + int dev_qdisc_change_tx_queue_len(struct net_device *dev) { bool up = dev->flags & IFF_UP; diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c index e79f1afe0cfd..db18d8a860f9 100644 --- a/net/sched/sch_mq.c +++ b/net/sched/sch_mq.c @@ -125,6 +125,29 @@ static void mq_attach(struct Qdisc *sch) priv->qdiscs = NULL; } +static void mq_change_real_num_tx(struct Qdisc *sch, unsigned int new_real_tx) +{ +#ifdef CONFIG_NET_SCHED + struct net_device *dev = qdisc_dev(sch); + struct Qdisc *qdisc; + unsigned int i; + + for (i = new_real_tx; i < dev->real_num_tx_queues; i++) { + qdisc = netdev_get_tx_queue(dev, i)->qdisc_sleeping; + /* Only update the default qdiscs we created, + * qdiscs with handles are always hashed. + */ + if (qdisc != &noop_qdisc && !qdisc->handle) + qdisc_hash_del(qdisc); + } + for (i = dev->real_num_tx_queues; i < new_real_tx; i++) { + qdisc = netdev_get_tx_queue(dev, i)->qdisc_sleeping; + if (qdisc != &noop_qdisc && !qdisc->handle) + qdisc_hash_add(qdisc, false); + } +#endif +} + static int mq_dump(struct Qdisc *sch, struct sk_buff *skb) { struct net_device *dev = qdisc_dev(sch); @@ -288,6 +311,7 @@ struct Qdisc_ops mq_qdisc_ops __read_mostly = { .init = mq_init, .destroy = mq_destroy, .attach = mq_attach, + .change_real_num_tx = mq_change_real_num_tx, .dump = mq_dump, .owner = THIS_MODULE, }; diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c index 8766ab5b8788..7f23a92849d5 100644 --- a/net/sched/sch_mqprio.c +++ b/net/sched/sch_mqprio.c @@ -306,6 +306,28 @@ static void mqprio_attach(struct Qdisc *sch) priv->qdiscs = NULL; } +static void mqprio_change_real_num_tx(struct Qdisc *sch, + unsigned int new_real_tx) +{ + struct net_device *dev = qdisc_dev(sch); + struct Qdisc *qdisc; + unsigned int i; + + for (i = new_real_tx; i < dev->real_num_tx_queues; i++) { + qdisc = netdev_get_tx_queue(dev, i)->qdisc_sleeping; + /* Only update the default qdiscs we created, + * qdiscs with handles are always hashed. + */ + if (qdisc != &noop_qdisc && !qdisc->handle) + qdisc_hash_del(qdisc); + } + for (i = dev->real_num_tx_queues; i < new_real_tx; i++) { + qdisc = netdev_get_tx_queue(dev, i)->qdisc_sleeping; + if (qdisc != &noop_qdisc && !qdisc->handle) + qdisc_hash_add(qdisc, false); + } +} + static struct netdev_queue *mqprio_queue_get(struct Qdisc *sch, unsigned long cl) { @@ -623,6 +645,7 @@ static struct Qdisc_ops mqprio_qdisc_ops __read_mostly = { .init = mqprio_init, .destroy = mqprio_destroy, .attach = mqprio_attach, + .change_real_num_tx = mqprio_change_real_num_tx, .dump = mqprio_dump, .owner = THIS_MODULE, }; |