rpms/kvm/F-9 kvm-65-tap-add-compat-macros-for-tungetfeatures-etc.patch, NONE, 1.1.2.1 kvm-65-virtio-net-add-sg-gso-support.patch, NONE, 1.1.2.1 kvm.spec, 1.54, 1.54.2.1

Mark McLoughlin (markmc) fedora-extras-commits at redhat.com
Tue May 20 14:43:42 UTC 2008


Author: markmc

Update of /cvs/pkgs/rpms/kvm/F-9
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv5237

Modified Files:
      Tag: private-markmc-virtio-gso-branch
	kvm.spec 
Added Files:
      Tag: private-markmc-virtio-gso-branch
	kvm-65-tap-add-compat-macros-for-tungetfeatures-etc.patch 
	kvm-65-virtio-net-add-sg-gso-support.patch 
Log Message:
* Tue May 20 2008 Mark McLoughlin <markmc at redhat.com> - 65-4.1.virtio_gso.fc9
- Add herbert's GSO patch


kvm-65-tap-add-compat-macros-for-tungetfeatures-etc.patch:

--- NEW FILE kvm-65-tap-add-compat-macros-for-tungetfeatures-etc.patch ---
>From 6cf37361d81f8e9c49a9e84c11a9aa6e62276439 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc at redhat.com>
Date: Tue, 20 May 2008 15:16:42 +0100
Subject: [PATCH 2/2] tap: Add compat macros for TUNGETFEATURES etc.

Signed-off-by: Mark McLoughlin <markmc at redhat.com>
---
 qemu/vl.c |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

Index: kvm-65/qemu/vl.c
===================================================================
--- kvm-65.orig/qemu/vl.c	2008-05-20 15:18:42.000000000 +0100
+++ kvm-65.orig/qemu/vl.c	2008-05-20 15:18:42.000000000 +0100
@@ -4203,6 +4203,16 @@ static int tap_open(char *ifname, int if
 #else
 static int tap_open(char *ifname, int ifname_size, int *gso)
 {
+#ifndef TUNGETFEATURES
+#define TUNGETFEATURES
+#endif
+
+#ifndef IFF_VIRTIO_HDR
+#define IFF_VIRTIO_HDR 0x4000
+#define IFF_RECV_CSUM  0x8000
+#define IFF_RECV_GSO   0x0800
+#endif
+
     struct ifreq ifr;
     int fd, ret;
     unsigned int features;

kvm-65-virtio-net-add-sg-gso-support.patch:

--- NEW FILE kvm-65-virtio-net-add-sg-gso-support.patch ---
>From a7dc45489753bf7c5edb898fe44408b80f921340 Mon Sep 17 00:00:00 2001
From: Herbert Xu <herbert at gondor.apana.org.au>
Date: Fri, 18 Apr 2008 11:19:39 +0800
Subject: [PATCH 1/2] virtio-net: Add SG/GSO support

Here's the patch to get the KVM backend to do GSO.  Please note
that this was a quick hack and I haven't even tested the case
where the tun device doesn't support GSO so it'll probably break
there.

It does the stupidest thing possible for guest => host by copying
the data so that it can use write(2).
---
 qemu/hw/virtio-net.c |   50 ++++++++++++++++++++++++++++++++++++--------------
 qemu/net.h           |    1 +
 qemu/vl.c            |   33 +++++++++++++++++++++++++++++----
 3 files changed, 66 insertions(+), 18 deletions(-)

diff --git a/qemu/hw/virtio-net.c b/qemu/hw/virtio-net.c
index 3d54c4e..5228c87 100644
--- a/qemu/hw/virtio-net.c
+++ b/qemu/hw/virtio-net.c
@@ -22,9 +22,9 @@
 #define VIRTIO_ID_NET	1
 
 /* The feature bitmap for virtio net */
-#define VIRTIO_NET_F_NO_CSUM	0
+#define VIRTIO_NET_F_CSUM	0
 #define VIRTIO_NET_F_MAC	5
-#define VIRTIO_NET_F_GS0	6
+#define VIRTIO_NET_F_GSO	6
 
 #define TX_TIMER_INTERVAL (1000 / 500)
 
@@ -87,7 +87,10 @@ static void virtio_net_update_config(VirtIODevice *vdev, uint8_t *config)
 
 static uint32_t virtio_net_get_features(VirtIODevice *vdev)
 {
-    return (1 << VIRTIO_NET_F_MAC);
+    int gso = tap_has_gso(to_virtio_net(vdev)->vc->vlan->first_client);
+
+    return (1 << VIRTIO_NET_F_MAC) |
+	   (gso ? (1 << VIRTIO_NET_F_CSUM) | (1 << VIRTIO_NET_F_GSO) : 0);
 }
 
 /* RX */
@@ -112,6 +115,7 @@ static void virtio_net_receive(void *opaque, const uint8_t *buf, int size)
     VirtQueueElement elem;
     struct virtio_net_hdr *hdr;
     int offset, i;
+    int total;
 
     /* FIXME: the drivers really need to set their status better */
     if (n->rx_vq->vring.avail == NULL) {
@@ -129,18 +133,26 @@ static void virtio_net_receive(void *opaque, const uint8_t *buf, int size)
     hdr->flags = 0;
     hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
 
-    /* copy in packet.  ugh */
     offset = 0;
+    total = sizeof(*hdr);
+
+    if (tap_has_gso(n->vc->vlan->first_client)) {
+	memcpy(hdr, buf, sizeof(*hdr));
+	offset += total;
+    }
+
+    /* copy in packet.  ugh */
     i = 1;
     while (offset < size && i < elem.in_num) {
 	int len = MIN(elem.in_sg[i].iov_len, size - offset);
 	memcpy(elem.in_sg[i].iov_base, buf + offset, len);
 	offset += len;
+	total += len;
 	i++;
     }
 
     /* signal other side */
-    virtqueue_push(n->rx_vq, &elem, sizeof(*hdr) + offset);
+    virtqueue_push(n->rx_vq, &elem, total);
     virtio_notify(&n->vdev, n->rx_vq);
 }
 
@@ -201,7 +213,10 @@ void virtio_net_poll(void)
             hdr->flags = 0;
             hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
 again:
-            len = readv(vnet->tap_fd, &elem.in_sg[1], elem.in_num - 1);
+	    if (tap_has_gso(vnet->vc->vlan->first_client))
+		len = readv(vnet->tap_fd, &elem.in_sg[0], elem.in_num);
+	    else
+		len = readv(vnet->tap_fd, &elem.in_sg[1], elem.in_num - 1);
             if (len == -1) {
                 if (errno == EINTR || errno == EAGAIN)
                     goto again;
@@ -229,25 +244,32 @@ again:
 static void virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq)
 {
     VirtQueueElement elem;
+    uint8_t buf[sizeof(struct virtio_net_hdr) + 65536];
+    int size = sizeof(buf);
     int count = 0;
+    int nogso = !tap_has_gso(n->vc->vlan->first_client);
 
     if (!(n->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK))
         return;
 
     while (virtqueue_pop(vq, &elem)) {
 	int i;
-	size_t len = 0;
+	int offset = 0;
 
-	/* ignore the header for now */
-	for (i = 1; i < elem.out_num; i++) {
-	    qemu_send_packet(n->vc, elem.out_sg[i].iov_base,
-			     elem.out_sg[i].iov_len);
-	    len += elem.out_sg[i].iov_len;
+	/* Ignore the header if GSO is not supported. */
+	for (i = nogso; i < elem.out_num; i++) {
+	    int len = MIN(elem.out_sg[i].iov_len, size - offset);
+	    memcpy(buf + offset, elem.out_sg[i].iov_base, len);
+	    offset += len;
 	}
 
+	qemu_send_packet(n->vc, buf, offset);
+
 	count++;
 
-	virtqueue_push(vq, &elem, sizeof(struct virtio_net_hdr) + len);
+	if (nogso)
+	    offset += elem.out_sg[0].iov_len;
+	virtqueue_push(vq, &elem, offset);
 	virtio_notify(&n->vdev, vq);
     }
 }
@@ -296,7 +318,7 @@ PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn)
     n->vdev.update_config = virtio_net_update_config;
     n->vdev.get_features = virtio_net_get_features;
     n->rx_vq = virtio_add_queue(&n->vdev, 512, virtio_net_handle_rx);
-    n->tx_vq = virtio_add_queue(&n->vdev, 128, virtio_net_handle_tx);
+    n->tx_vq = virtio_add_queue(&n->vdev, 512, virtio_net_handle_tx);
     n->can_receive = 0;
     memcpy(n->mac, nd->macaddr, 6);
     n->vc = qemu_new_vlan_client(nd->vlan, virtio_net_receive,
diff --git a/qemu/net.h b/qemu/net.h
index 13daa27..5ce3b02 100644
--- a/qemu/net.h
+++ b/qemu/net.h
@@ -36,6 +36,7 @@ void do_info_network(void);
 
 /* virtio hack for zero copy receive */
 int hack_around_tap(void *opaque);
+int tap_has_gso(void *opaque);
 
 int net_client_init(const char *str);
 void net_client_uninit(NICInfo *nd);
diff --git a/qemu/vl.c b/qemu/vl.c
index 49d9af2..13925ad 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -3961,6 +3961,7 @@ typedef struct TAPState {
     int fd;
     char down_script[1024];
     int no_poll;
+    int gso;
 } TAPState;
 
 static int tap_read_poll(void *opaque)
@@ -4018,6 +4019,14 @@ int hack_around_tap(void *opaque)
     return -1;
 }
 
+int tap_has_gso(void *opaque)
+{
+    VLANClientState *vc = opaque;
+    TAPState *ts = vc->opaque;
+
+    return ts ? ts->gso : 0;
+}
+
 /* fd support */
 
 static TAPState *net_tap_fd_init(VLANState *vlan, int fd)
@@ -4037,7 +4046,7 @@ static TAPState *net_tap_fd_init(VLANState *vlan, int fd)
 }
 
 #if defined (_BSD) || defined (__FreeBSD_kernel__)
-static int tap_open(char *ifname, int ifname_size)
+static int tap_open(char *ifname, int ifname_size, int *gso)
 {
     int fd;
     char *dev;
@@ -4179,7 +4188,7 @@ int tap_alloc(char *dev)
     return tap_fd;
 }
 
-static int tap_open(char *ifname, int ifname_size)
+static int tap_open(char *ifname, int ifname_size, int *gso)
 {
     char  dev[10]="";
     int fd;
@@ -4192,18 +4201,30 @@ static int tap_open(char *ifname, int ifname_size)
     return fd;
 }
 #else
-static int tap_open(char *ifname, int ifname_size)
+static int tap_open(char *ifname, int ifname_size, int *gso)
 {
     struct ifreq ifr;
     int fd, ret;
+    unsigned int features;
 
     TFR(fd = open("/dev/net/tun", O_RDWR));
     if (fd < 0) {
         fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
         return -1;
     }
+
+    if (ioctl(fd, TUNGETFEATURES, &features))
+	features = IFF_TUN | IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE;
+
     memset(&ifr, 0, sizeof(ifr));
     ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+
+    if (features & IFF_VIRTIO_HDR && features & IFF_RECV_CSUM &&
+	features & IFF_RECV_GSO) {
+	*gso = 1;
+	ifr.ifr_flags |= IFF_VIRTIO_HDR | IFF_RECV_CSUM | IFF_RECV_GSO;
+    }
+
     if (ifname[0] != '\0')
         pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
     else
@@ -4261,13 +4282,15 @@ static int net_tap_init(VLANState *vlan, const char *ifname1,
 {
     TAPState *s;
     int fd;
+    int gso;
     char ifname[128];
 
     if (ifname1 != NULL)
         pstrcpy(ifname, sizeof(ifname), ifname1);
     else
         ifname[0] = '\0';
-    TFR(fd = tap_open(ifname, sizeof(ifname)));
+    gso = 0;
+    TFR(fd = tap_open(ifname, sizeof(ifname), &gso));
     if (fd < 0)
         return -1;
 
@@ -4280,6 +4303,8 @@ static int net_tap_init(VLANState *vlan, const char *ifname1,
     s = net_tap_fd_init(vlan, fd);
     if (!s)
         return -1;
+
+    s->gso = gso;
     snprintf(s->vc->info_str, sizeof(s->vc->info_str),
              "tap: ifname=%s setup_script=%s", ifname, setup_script);
     if (down_script && strcmp(down_script, "no"))
-- 
1.5.4.1



Index: kvm.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kvm/F-9/kvm.spec,v
retrieving revision 1.54
retrieving revision 1.54.2.1
diff -u -r1.54 -r1.54.2.1
--- kvm.spec	16 May 2008 18:06:17 -0000	1.54
+++ kvm.spec	20 May 2008 14:42:52 -0000	1.54.2.1
@@ -1,7 +1,7 @@
 Summary: Kernel-based Virtual Machine
 Name: kvm
 Version: 65
-Release: 3%{?dist}
+Release: 4.1.virtio_gso%{?dist}
 License: GPLv2+ and LGPLv2+
 Group: Development/Tools
 URL: http://%{name}.sf.net
@@ -12,7 +12,9 @@
 Patch2: %{name}-62-block-rw-range-check.patch
 Patch3: %{name}-62-e1000-default.patch
 Patch4: %{name}-65-kernel-virtio-boot.patch
-Patch4: %{name}-65-cirrus.patch
+Patch5: %{name}-65-cirrus.patch
+Patch6: %{name}-65-virtio-net-add-sg-gso-support.patch
+Patch7: %{name}-65-tap-add-compat-macros-for-tungetfeatures-etc.patch
 # patches from upstream qemu
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: SDL-devel
@@ -46,6 +48,9 @@
 %patch2 -p1
 #patch3 -p1
 %patch4 -p1
+%patch5 -p1
+%patch6 -p1
+%patch7 -p1
 
 %build
 # we need to install the data bits in a different path
@@ -100,6 +105,12 @@
 %{_sysconfdir}/sysconfig/modules/%{name}.modules
 
 %changelog
+* Tue May 20 2008 Mark McLoughlin <markmc at redhat.com> - 65-4.1.virtio_gso.fc9
+- Add herbert's GSO patch
+
+* Tue May 20 2008 Mark McLoughlin <markmc at redhat.com> - 65-4.fc9
+- Re-enable patch to fix -kernel with virtio/extboot drives (#444578)
+
 * Fri May 16 2008 Glauber Costa <gcosta at redhat.com> - 65-3.fc9
 - Fix problem with cirrus device that was breaking vnc connections (rhbz #446830)
 




More information about the fedora-extras-commits mailing list