Patchwork [PATCHv3] tap: set IFF_ONE_QUEUE per default

login
register
mail settings
Submitter Peter Lieven
Date Feb. 25, 2013, 9:17 a.m.
Message ID <512B2C14.2010108@dlhnet.de>
Download mbox | patch
Permalink /patch/222872/
State New
Headers show

Comments

Peter Lieven - Feb. 25, 2013, 9:17 a.m.
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(-)
Michael S. Tsirkin - Feb. 25, 2013, 10:13 a.m.
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.
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

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