All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sridhar Samudrala <sri@us.ibm.com>
To: Mark McLoughlin <markmc@redhat.com>
Cc: avi@redhat.com, aliguori@us.ibm.com, kvm@vger.kernel.org
Subject: Re: [PATCH qemu-kvm] Enable UFO on virtio-net and tap devices
Date: Thu, 08 Oct 2009 15:31:41 -0700	[thread overview]
Message-ID: <1255041101.20627.51.camel@w-sridhar.beaverton.ibm.com> (raw)
In-Reply-To: <1254996477.8069.17.camel@blaa>

On Thu, 2009-10-08 at 11:07 +0100, Mark McLoughlin wrote:
> On Wed, 2009-10-07 at 14:50 -0700, Sridhar Samudrala wrote:
> > linux 2.6.32 includes UDP fragmentation offload support in software. 
> > So we can enable UFO on the host tap device if supported and allow setting
> > UFO on virtio-net in the guest.
> 
> Hmm, we really need to detect whether the host has tuntap UFO support
> before advertising it to the guest. Maybe in net_tap_fd_init() we should
> toggle TUN_F_UFO back and forth and check for EINVAL?

Sure. Here is an updated patch that checks for UFO support in host.

Thanks
Sridhar

Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>

diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index ce8e6cb..9561f34 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -150,7 +150,10 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev)
         features |= (1 << VIRTIO_NET_F_HOST_TSO6);
         features |= (1 << VIRTIO_NET_F_HOST_ECN);
         features |= (1 << VIRTIO_NET_F_MRG_RXBUF);
-        /* Kernel can't actually handle UFO in software currently. */
+        if (tap_has_ufo(host)) {
+            features |= (1 << VIRTIO_NET_F_GUEST_UFO);
+            features |= (1 << VIRTIO_NET_F_HOST_UFO);
+        }
     }
 #endif
 
@@ -189,7 +192,8 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
                       (features >> VIRTIO_NET_F_GUEST_CSUM) & 1,
                       (features >> VIRTIO_NET_F_GUEST_TSO4) & 1,
                       (features >> VIRTIO_NET_F_GUEST_TSO6) & 1,
-                      (features >> VIRTIO_NET_F_GUEST_ECN)  & 1);
+                      (features >> VIRTIO_NET_F_GUEST_ECN)  & 1,
+                      (features >> VIRTIO_NET_F_GUEST_UFO)  & 1);
 #endif
 }
 
diff --git a/net.c b/net.c
index 8032ff8..838e42c 100644
--- a/net.c
+++ b/net.c
@@ -1271,6 +1271,11 @@ void tap_using_vnet_hdr(void *opaque, int using_vnet_hdr)
 {
 }
 
+int tap_has_ufo(void *opaque)
+{
+    return 0;
+}
+
 #else /* !defined(_WIN32) */
 
 /* Maximum GSO packet size (64k) plus plenty of room for
@@ -1292,6 +1297,7 @@ typedef struct TAPState {
     unsigned int write_poll : 1;
     unsigned int has_vnet_hdr : 1;
     unsigned int using_vnet_hdr : 1;
+    unsigned int has_ufo: 1;
 } TAPState;
 
 static int launch_script(const char *setup_script, const char *ifname, int fd);
@@ -1527,9 +1533,22 @@ static int tap_probe_vnet_hdr(int fd)
 #endif
 }
 
+int tap_has_ufo(void *opaque)
+{
+    VLANClientState *vc = opaque;
+    TAPState *s = vc->opaque;
+
+    return s ? s->has_ufo : 0;
+}
+
 #ifdef TUNSETOFFLOAD
+
+#ifndef TUN_F_UFO
+#define TUN_F_UFO	0x10
+#endif
+
 static void tap_set_offload(VLANClientState *vc, int csum, int tso4, int tso6,
-			    int ecn)
+			    int ecn, int ufo)
 {
     TAPState *s = vc->opaque;
     unsigned int offload = 0;
@@ -1542,11 +1561,18 @@ static void tap_set_offload(VLANClientState *vc, int csum, int tso4, int tso6,
 	    offload |= TUN_F_TSO6;
 	if ((tso4 || tso6) && ecn)
 	    offload |= TUN_F_TSO_ECN;
+	if (ufo)
+	    offload |= TUN_F_UFO;
     }
 
-    if (ioctl(s->fd, TUNSETOFFLOAD, offload) != 0)
-	fprintf(stderr, "TUNSETOFFLOAD ioctl() failed: %s\n",
-		strerror(errno));
+    if (ioctl(s->fd, TUNSETOFFLOAD, offload) != 0) {
+        /* Try without UFO */
+        offload &= ~TUN_F_UFO;
+        if (ioctl(s->fd, TUNSETOFFLOAD, offload) != 0) {
+	    fprintf(stderr, "TUNSETOFFLOAD ioctl() failed: %s\n",
+	   	strerror(errno));
+        }
+    }
 }
 #endif /* TUNSETOFFLOAD */
 
@@ -1574,6 +1600,7 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
                                  int vnet_hdr)
 {
     TAPState *s;
+    unsigned int offload;
 
     s = qemu_mallocz(sizeof(TAPState));
     s->fd = fd;
@@ -1583,7 +1610,14 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
     s->vc->receive_raw = tap_receive_raw;
 #ifdef TUNSETOFFLOAD
     s->vc->set_offload = tap_set_offload;
-    tap_set_offload(s->vc, 0, 0, 0, 0);
+
+    s->has_ufo = 0; 
+    /* Check if tap supports UFO */
+    offload = TUN_F_CSUM | TUN_F_UFO;
+    if (ioctl(s->fd, TUNSETOFFLOAD, offload) == 0)
+       s->has_ufo = 1;
+
+    tap_set_offload(s->vc, 0, 0, 0, 0, 0);
 #endif
     tap_read_poll(s, 1);
     snprintf(s->vc->info_str, sizeof(s->vc->info_str), "fd=%d", fd);
diff --git a/net.h b/net.h
index 925c67c..6bb6434 100644
--- a/net.h
+++ b/net.h
@@ -14,7 +14,7 @@ typedef ssize_t (NetReceive)(VLANClientState *, const uint8_t *, size_t);
 typedef ssize_t (NetReceiveIOV)(VLANClientState *, const struct iovec *, int);
 typedef void (NetCleanup) (VLANClientState *);
 typedef void (LinkStatusChanged)(VLANClientState *);
-typedef void (SetOffload)(VLANClientState *, int, int, int, int);
+typedef void (SetOffload)(VLANClientState *, int, int, int, int, int);
 
 struct VLANClientState {
     NetReceive *receive;
@@ -92,6 +92,7 @@ void do_info_usernet(Monitor *mon);
 
 int tap_has_vnet_hdr(void *opaque);
 void tap_using_vnet_hdr(void *opaque, int using_vnet_hdr);
+int tap_has_ufo(void *opaque);
 
 /* NIC info */
 



  reply	other threads:[~2009-10-08 22:32 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-10-07 21:50 [PATCH qemu-kvm] Enable UFO on virtio-net and tap devices Sridhar Samudrala
2009-10-08 10:07 ` Mark McLoughlin
2009-10-08 22:31   ` Sridhar Samudrala [this message]
2009-10-09  7:11     ` Mark McLoughlin
2009-10-13 15:35       ` Marcelo Tosatti

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1255041101.20627.51.camel@w-sridhar.beaverton.ibm.com \
    --to=sri@us.ibm.com \
    --cc=aliguori@us.ibm.com \
    --cc=avi@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=markmc@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.