forked from luck/tmp_suning_uos_patched
Merge branch 'iff_no_queue_fixups'
Phil Sutter says: ==================== fixup IFF_NO_QUEUE conversion This series serves two purposes: On one hand it fixes a quite embarrassing bug around the warning I added for drivers still setting tx_queue_len = 0 to achieve noqueue operation. It turned out to be quite useless as due to using alloc_netdev(), many in-kernel drivers fell into the trap by accident, as well. Instead this place serves pretty well as a sanitizing point to set IFF_NO_QUEUE for drivers not initializing tx_queue_len, which in turn allows to drop all special treatment of the latter being zero since that can not happen anymore without IFF_NO_QUEUE being set. On the other hand, it provides a better solution for Eric Dumazet's concern regarding how to assign noqueue to an interface which does not default to it already. In order to make this possible, noqueue is being registered so users can 'tc qd add dev eth0 root noqueue'. In addition, it resolves the ugly situation of 'tc qd show' not showing noqueue. Finally, the former changes allow for some code cleanup. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
55f14da669
@ -340,6 +340,7 @@ extern struct Qdisc noop_qdisc;
|
||||
extern struct Qdisc_ops noop_qdisc_ops;
|
||||
extern struct Qdisc_ops pfifo_fast_ops;
|
||||
extern struct Qdisc_ops mq_qdisc_ops;
|
||||
extern struct Qdisc_ops noqueue_qdisc_ops;
|
||||
extern const struct Qdisc_ops *default_qdisc_ops;
|
||||
|
||||
struct Qdisc_class_common {
|
||||
|
@ -7010,7 +7010,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
|
||||
setup(dev);
|
||||
|
||||
if (!dev->tx_queue_len)
|
||||
printk(KERN_WARNING "%s uses DEPRECATED zero tx_queue_len - convert driver to use IFF_NO_QUEUE instead.\n", name);
|
||||
dev->priv_flags |= IFF_NO_QUEUE;
|
||||
|
||||
dev->num_tx_queues = txqs;
|
||||
dev->real_num_tx_queues = txqs;
|
||||
|
@ -1942,6 +1942,7 @@ static int __init pktsched_init(void)
|
||||
register_qdisc(&bfifo_qdisc_ops);
|
||||
register_qdisc(&pfifo_head_drop_qdisc_ops);
|
||||
register_qdisc(&mq_qdisc_ops);
|
||||
register_qdisc(&noqueue_qdisc_ops);
|
||||
|
||||
rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL, NULL);
|
||||
rtnl_register(PF_UNSPEC, RTM_DELQDISC, tc_get_qdisc, NULL, NULL);
|
||||
|
@ -416,33 +416,25 @@ struct Qdisc noop_qdisc = {
|
||||
};
|
||||
EXPORT_SYMBOL(noop_qdisc);
|
||||
|
||||
static struct Qdisc_ops noqueue_qdisc_ops __read_mostly = {
|
||||
static int noqueue_init(struct Qdisc *qdisc, struct nlattr *opt)
|
||||
{
|
||||
/* register_qdisc() assigns a default of noop_enqueue if unset,
|
||||
* but __dev_queue_xmit() treats noqueue only as such
|
||||
* if this is NULL - so clear it here. */
|
||||
qdisc->enqueue = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct Qdisc_ops noqueue_qdisc_ops __read_mostly = {
|
||||
.id = "noqueue",
|
||||
.priv_size = 0,
|
||||
.init = noqueue_init,
|
||||
.enqueue = noop_enqueue,
|
||||
.dequeue = noop_dequeue,
|
||||
.peek = noop_dequeue,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct Qdisc noqueue_qdisc;
|
||||
static struct netdev_queue noqueue_netdev_queue = {
|
||||
.qdisc = &noqueue_qdisc,
|
||||
.qdisc_sleeping = &noqueue_qdisc,
|
||||
};
|
||||
|
||||
static struct Qdisc noqueue_qdisc = {
|
||||
.enqueue = NULL,
|
||||
.dequeue = noop_dequeue,
|
||||
.flags = TCQ_F_BUILTIN,
|
||||
.ops = &noqueue_qdisc_ops,
|
||||
.list = LIST_HEAD_INIT(noqueue_qdisc.list),
|
||||
.q.lock = __SPIN_LOCK_UNLOCKED(noqueue_qdisc.q.lock),
|
||||
.dev_queue = &noqueue_netdev_queue,
|
||||
.busylock = __SPIN_LOCK_UNLOCKED(noqueue_qdisc.busylock),
|
||||
};
|
||||
|
||||
|
||||
static const u8 prio2band[TC_PRIO_MAX + 1] = {
|
||||
1, 2, 2, 2, 1, 2, 0, 0 , 1, 1, 1, 1, 1, 1, 1, 1
|
||||
};
|
||||
@ -733,18 +725,19 @@ static void attach_one_default_qdisc(struct net_device *dev,
|
||||
struct netdev_queue *dev_queue,
|
||||
void *_unused)
|
||||
{
|
||||
struct Qdisc *qdisc = &noqueue_qdisc;
|
||||
struct Qdisc *qdisc;
|
||||
const struct Qdisc_ops *ops = default_qdisc_ops;
|
||||
|
||||
if (dev->tx_queue_len && !(dev->priv_flags & IFF_NO_QUEUE)) {
|
||||
qdisc = qdisc_create_dflt(dev_queue,
|
||||
default_qdisc_ops, TC_H_ROOT);
|
||||
if (!qdisc) {
|
||||
netdev_info(dev, "activation failed\n");
|
||||
return;
|
||||
}
|
||||
if (!netif_is_multiqueue(dev))
|
||||
qdisc->flags |= TCQ_F_ONETXQUEUE;
|
||||
if (dev->priv_flags & IFF_NO_QUEUE)
|
||||
ops = &noqueue_qdisc_ops;
|
||||
|
||||
qdisc = qdisc_create_dflt(dev_queue, ops, TC_H_ROOT);
|
||||
if (!qdisc) {
|
||||
netdev_info(dev, "activation failed\n");
|
||||
return;
|
||||
}
|
||||
if (!netif_is_multiqueue(dev))
|
||||
qdisc->flags |= TCQ_F_ONETXQUEUE;
|
||||
dev_queue->qdisc_sleeping = qdisc;
|
||||
}
|
||||
|
||||
@ -756,7 +749,6 @@ static void attach_default_qdiscs(struct net_device *dev)
|
||||
txq = netdev_get_tx_queue(dev, 0);
|
||||
|
||||
if (!netif_is_multiqueue(dev) ||
|
||||
dev->tx_queue_len == 0 ||
|
||||
dev->priv_flags & IFF_NO_QUEUE) {
|
||||
netdev_for_each_tx_queue(dev, attach_one_default_qdisc, NULL);
|
||||
dev->qdisc = txq->qdisc_sleeping;
|
||||
@ -781,7 +773,7 @@ static void transition_one_qdisc(struct net_device *dev,
|
||||
clear_bit(__QDISC_STATE_DEACTIVATED, &new_qdisc->state);
|
||||
|
||||
rcu_assign_pointer(dev_queue->qdisc, new_qdisc);
|
||||
if (need_watchdog_p && new_qdisc != &noqueue_qdisc) {
|
||||
if (need_watchdog_p) {
|
||||
dev_queue->trans_start = 0;
|
||||
*need_watchdog_p = 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user