]> Git Repo - qemu.git/commitdiff
tap: set IFF_ONE_QUEUE per default
authorPeter Lieven <[email protected]>
Mon, 25 Feb 2013 09:17:08 +0000 (10:17 +0100)
committerStefan Hajnoczi <[email protected]>
Wed, 27 Feb 2013 15:10:47 +0000 (16:10 +0100)
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 <[email protected]>
Acked-by: Michael S. Tsirkin <[email protected]>
Signed-off-by: Stefan Hajnoczi <[email protected]>
net/tap-linux.c
net/tap-linux.h

index a9531892a61a1e1db0c9351c93b882880968766d..36c09e24d8a697841563aba1ad6e72111d9d3388 100644 (file)
@@ -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 "
index 65087e1419de9873a2135734f4c1ac452bc154a4..1cf35d41bd843f1732ea3d0c3ebe0f60b44a7079 100644 (file)
 #endif
 
 /* TUNSETIFF ifr flags */
-#define IFF_TAP                0x0002
-#define IFF_NO_PI      0x1000
-#define IFF_VNET_HDR   0x4000
-#define IFF_MULTI_QUEUE 0x0100
+#define IFF_TAP          0x0002
+#define IFF_NO_PI        0x1000
+#define IFF_ONE_QUEUE    0x2000
+#define IFF_VNET_HDR     0x4000
+#define IFF_MULTI_QUEUE  0x0100
 #define IFF_ATTACH_QUEUE 0x0200
 #define IFF_DETACH_QUEUE 0x0400
 
This page took 0.024831 seconds and 4 git commands to generate.