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 <p...@kamp.de>
Acked-by: Michael S. Tsirkin <m...@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