Skip to content

Commit

Permalink
Merge branch 'iff_no_queue'
Browse files Browse the repository at this point in the history
Phil Sutter says:

====================
net: introduce IFF_NO_QUEUE as successor of zero tx_queue_len

This series adds a new private net_device flag indicating that a device may
(and probably should) be used without a queueing discipline attached to it.
This is already common practice for many virtual device types like e.g.
loopback, VLAN (802.1Q) or bridges (802.1D). The reason for this is that these
devices lack an underlying layer which could impose back pressure and therefore
making a TX queue necessary to not slow down senders.

Up to now, drivers being aware of the above applying to them set
dev->tx_queue_len to zero to indicate no qdisc should be attached to the
interface they drive and the kernel reacts upon this by assigning the noop
qdisc instead of the default pfifo_fast. This implicit agreement though leads
to an inconvenient situation once a user tries to attach a real qdisc to these
devices, as the formerly special tx_queue_len value becomes a regular one,
limiting the queue to zero packets and thus prevents any TX from happening. To
overcome this, practically all qdisc implementations intercept and sanitize the
malicious value.

With this series applied, drivers may signal the lack of need for a qdisc
without having to tamper with tx_queue_len, making fallbacks in qdiscs and
caveats in userspace unnecessary.

Upon upstream acceptance, this series will be followed up by a set of patches
converting device drivers, adding a warning so out-of-tree driver authors get
aware of this change and dropping all special handling of tx_queue_len in
net/sched/.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Aug 17, 2015
2 parents 8f8ff91 + 4b46995 commit f3ae683
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 2 deletions.
3 changes: 3 additions & 0 deletions include/linux/netdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -1262,6 +1262,7 @@ struct net_device_ops {
* @IFF_LIVE_ADDR_CHANGE: device supports hardware address
* change when it's running
* @IFF_MACVLAN: Macvlan device
* @IFF_NO_QUEUE: device can run without qdisc attached
*/
enum netdev_priv_flags {
IFF_802_1Q_VLAN = 1<<0,
Expand Down Expand Up @@ -1290,6 +1291,7 @@ enum netdev_priv_flags {
IFF_IPVLAN_MASTER = 1<<23,
IFF_IPVLAN_SLAVE = 1<<24,
IFF_VRF_MASTER = 1<<25,
IFF_NO_QUEUE = 1<<26,
};

#define IFF_802_1Q_VLAN IFF_802_1Q_VLAN
Expand Down Expand Up @@ -1318,6 +1320,7 @@ enum netdev_priv_flags {
#define IFF_IPVLAN_MASTER IFF_IPVLAN_MASTER
#define IFF_IPVLAN_SLAVE IFF_IPVLAN_SLAVE
#define IFF_VRF_MASTER IFF_VRF_MASTER
#define IFF_NO_QUEUE IFF_NO_QUEUE

/**
* struct net_device - The DEVICE structure.
Expand Down
6 changes: 4 additions & 2 deletions net/sched/sch_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -735,7 +735,7 @@ static void attach_one_default_qdisc(struct net_device *dev,
{
struct Qdisc *qdisc = &noqueue_qdisc;

if (dev->tx_queue_len) {
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) {
Expand All @@ -755,7 +755,9 @@ 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) {
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;
atomic_inc(&dev->qdisc->refcnt);
Expand Down

0 comments on commit f3ae683

Please sign in to comment.