KVM: set IFF_ONE_QUEUE on created tap interfaces
authorApollon Oikonomopoulos <apoikos@gmail.com>
Tue, 6 May 2014 12:28:46 +0000 (15:28 +0300)
committerHrvoje Ribicic <riba@google.com>
Thu, 8 May 2014 13:36:56 +0000 (13:36 +0000)
The IFF_ONE_QUEUE flag directs the kernel to only queue tap packets once
(as opposed to queueing them twice, once for the device, and once for the
qdisc), possibly avoiding interface stalls when one of the queues overruns.

This is the default behaviour of the kernel tun/tap driver in Linux
>= 3.8. Also, qemu >= 1.5.0 sets this flag when opening the tap device
itself (but not for tap interfaces inherited via fds), according to this
commit:

  commit d26e445c80fddcc7483b83f3115e5067fef28fe6
  Author: Peter Lieven <pl@dlhnet.de>
  Date:   Mon Feb 25 10:17:08 2013 +0100

      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>

Since we handle tap creation ourselves, we duplicate this behavior in
_OpenTap. IFF_ONE_QUEUE has been there as far back as the kernel's git
history goes (2.6.12), so it is safe to add the flag unconditionally.
Also the flag is invisible to the guest and will not break migrations of
already running instances.

Signed-off-by: Apollon Oikonomopoulos <apoikos@gmail.com>
Reviewed-by: Hrvoje Ribicic <riba@google.com>

lib/hypervisor/hv_kvm.py

index 7af296e..5f17410 100644 (file)
@@ -66,6 +66,7 @@ TUNGETIFF = 0x800454d2
 TUNGETFEATURES = 0x800454cf
 IFF_TAP = 0x0002
 IFF_NO_PI = 0x1000
+IFF_ONE_QUEUE = 0x2000
 IFF_VNET_HDR = 0x4000
 
 #: SPICE parameters which depend on L{constants.HV_KVM_SPICE_BIND}
@@ -145,7 +146,7 @@ def _OpenTap(vnet_hdr=True):
   except EnvironmentError:
     raise errors.HypervisorError("Failed to open /dev/net/tun")
 
-  flags = IFF_TAP | IFF_NO_PI
+  flags = IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE
 
   if vnet_hdr and _ProbeTapVnetHdr(tapfd):
     flags |= IFF_VNET_HDR