diff options
author | Peter Lieven <pl@dlhnet.de> | 2013-02-25 10:17:08 +0100 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2013-02-27 16:10:47 +0100 |
commit | d26e445c80fddcc7483b83f3115e5067fef28fe6 (patch) | |
tree | 38ddab0d25178b7b2bb792b6bc80078f43f39178 /net/tap-linux.c | |
parent | ce675a7579fea498397c5d2da3c5367671e9f02a (diff) | |
download | qemu-d26e445c80fddcc7483b83f3115e5067fef28fe6.zip qemu-d26e445c80fddcc7483b83f3115e5067fef28fe6.tar.gz qemu-d26e445c80fddcc7483b83f3115e5067fef28fe6.tar.bz2 |
tap: set IFF_ONE_QUEUE per default
historically the kernel queues packets two times. once
at the device and second in qdisc. this is believed to cause
interface stalls if one of these queues overruns.
setting IFF_ONE_QUEUE is the default in kernels >= 3.8. the
flag is ignored since then. see kernel commit
5d097109257c03a71845729f8db6b5770c4bbedc
Signed-off-by: Peter Lieven <pl@kamp.de>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'net/tap-linux.c')
-rw-r--r-- | net/tap-linux.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/net/tap-linux.c b/net/tap-linux.c index a9531892..36c09e2 100644 --- a/net/tap-linux.c +++ b/net/tap-linux.c @@ -42,6 +42,7 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, struct ifreq ifr; int fd, ret; int len = sizeof(struct virtio_net_hdr); + unsigned int features; TFR(fd = open(PATH_NET_TUN, O_RDWR)); if (fd < 0) { @@ -51,9 +52,12 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; - if (*vnet_hdr) { - unsigned int features; + if (ioctl(fd, TUNGETFEATURES, &features) == 0 && + features & IFF_ONE_QUEUE) { + ifr.ifr_flags |= IFF_ONE_QUEUE; + } + if (*vnet_hdr) { if (ioctl(fd, TUNGETFEATURES, &features) == 0 && features & IFF_VNET_HDR) { *vnet_hdr = 1; @@ -78,8 +82,6 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, } if (mq_required) { - unsigned int features; - if ((ioctl(fd, TUNGETFEATURES, &features) != 0) || !(features & IFF_MULTI_QUEUE)) { error_report("multiqueue required, but no kernel " |