aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2012-04-12 10:22:37 +0300
committerMichael S. Tsirkin <mst@redhat.com>2012-04-30 22:23:21 +0300
commitb295cfd75d02d6db159e76185e050417aa286a15 (patch)
tree3f626aecaebf8bdb7d47589202eb23b9f41b2767
parenta0f8762459c50a95445010a10e213c6bb8aacbdc (diff)
downloadvhost-b295cfd75d02d6db159e76185e050417aa286a15.tar.gz
tun: disable qdisc queueing
commit 0110d6f22f392f976e84ab49da1b42f85b64a3c5 tun: orphan an skb on tx Fixed a configuration where skbs get queued at the tun device forever, blocking senders. However this fix isn't waterproof: userspace can control whether the interface is stopped, and if it is, packets get queued in the qdisc, again potentially forever. To complete the fix, this patch sets tun qdisc to 0 when it's registered to disable qdisc queueing. As user controls this variable to set queueing within tun as well, set it back to 500 after the registration. Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-rw-r--r--drivers/net/tun.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index bb8c72c79c6f31..418abd1a250e6a 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -521,7 +521,6 @@ static void tun_net_init(struct net_device *dev)
/* Zero header length */
dev->type = ARPHRD_NONE;
dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
- dev->tx_queue_len = TUN_READQ_SIZE; /* We prefer our own queue length */
break;
case TUN_TAP_DEV:
@@ -531,10 +530,9 @@ static void tun_net_init(struct net_device *dev)
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
eth_hw_addr_random(dev);
-
- dev->tx_queue_len = TUN_READQ_SIZE; /* We prefer our own queue length */
break;
}
+ dev->tx_queue_len = 0; /* Disable qdisc queueing */
}
/* Character device part */
@@ -1143,6 +1141,12 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
if (err < 0)
goto err_free_sk;
+ /*
+ * We (ab)use queue length to limit our amount of buffering.
+ * Set our own default queue length.
+ */
+ dev->tx_queue_len = TUN_READQ_SIZE;
+
if (device_create_file(&tun->dev->dev, &dev_attr_tun_flags) ||
device_create_file(&tun->dev->dev, &dev_attr_owner) ||
device_create_file(&tun->dev->dev, &dev_attr_group))