Message ID | 512B2C14.2010108@dlhnet.de |
---|---|
State | New |
Headers | show |
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
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 --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
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(-)