aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Lieven <pl@dlhnet.de>2013-02-25 10:17:08 +0100
committerStefan Hajnoczi <stefanha@redhat.com>2013-02-27 16:10:47 +0100
commitd26e445c80fddcc7483b83f3115e5067fef28fe6 (patch)
tree38ddab0d25178b7b2bb792b6bc80078f43f39178
parentce675a7579fea498397c5d2da3c5367671e9f02a (diff)
downloadqemu-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>
-rw-r--r--net/tap-linux.c10
-rw-r--r--net/tap-linux.h9
2 files changed, 11 insertions, 8 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 "
diff --git a/net/tap-linux.h b/net/tap-linux.h
index 65087e1..1cf35d4 100644
--- a/net/tap-linux.h
+++ b/net/tap-linux.h
@@ -34,10 +34,11 @@
#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