diff mbox

[PATCHv3] tap: set IFF_ONE_QUEUE per default

Message ID 512B2C14.2010108@dlhnet.de
State New
Headers show

Commit Message

Peter Lieven Feb. 25, 2013, 9:17 a.m. UTC
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

v3:
  - probe if IFF_ONE_QUEUE feature is available

v2:
  - do only set the flag on linux as it breaks macvtap
  - define IFF_ONE_QUEUE in tap-linux.h

Signed-off-by: Peter Lieven <pl@kamp.de>
---
  net/tap-linux.c |   10 ++++++----
  net/tap-linux.h |    9 +++++----
  2 files changed, 11 insertions(+), 8 deletions(-)

Comments

Michael S. Tsirkin Feb. 25, 2013, 10:13 a.m. UTC | #1
On Mon, Feb 25, 2013 at 10:17:08AM +0100, Peter Lieven wrote:
> 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
> 
> v3:
>  - probe if IFF_ONE_QUEUE feature is available
> 
> v2:
>  - do only set the flag on linux as it breaks macvtap
>  - define IFF_ONE_QUEUE in tap-linux.h
> 
> Signed-off-by: Peter Lieven <pl@kamp.de>


Acked-by: Michael S. Tsirkin <mst@redhat.com>

> ---
>  net/tap-linux.c |   10 ++++++----
>  net/tap-linux.h |    9 +++++----
>  2 files changed, 11 insertions(+), 8 deletions(-)
> 
> diff --git a/net/tap-linux.c b/net/tap-linux.c
> index a953189..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..5704efb 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
> 
> -- 
> 1.7.9.5
Stefan Hajnoczi Feb. 25, 2013, 10:39 a.m. UTC | #2
On Mon, Feb 25, 2013 at 10:17:08AM +0100, Peter Lieven wrote:

git-am(1) cannot apply this patch.  There is whitespace damage,
untouched lines have an extra space.  I applied it manually, please use
git-send-email(1) or fix your email client configuration for future
patches.

> 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
> 
> v3:
>  - probe if IFF_ONE_QUEUE feature is available
> 
> v2:
>  - do only set the flag on linux as it breaks macvtap
>  - define IFF_ONE_QUEUE in tap-linux.h

In the future, please put patch revision below the '---' in the future
so it's not part of the commit description.  That way it is not stored
in git (the information isn't useful once the patch has been merged).

> Signed-off-by: Peter Lieven <pl@kamp.de>
> ---
>  net/tap-linux.c |   10 ++++++----
>  net/tap-linux.h |    9 +++++----
>  2 files changed, 11 insertions(+), 8 deletions(-)

Thanks, applied to my net tree:
https://github.com/stefanha/qemu/commits/net

Stefan
diff mbox

Patch

diff --git a/net/tap-linux.c b/net/tap-linux.c
index a953189..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..5704efb 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