We need to be able to send fragmented packets in KVM to avoid an extra copy
in the TX path.  This patch adds a qemu_sendv_packet() function to send
fragemented packets.  It also provides backwards compatibility for old clients
that don't support the new interface.

Signed-off-by: Anthony Liguori <[EMAIL PROTECTED]>

diff --git a/qemu/net.h b/qemu/net.h
index 13daa27..5fb190e 100644
--- a/qemu/net.h
+++ b/qemu/net.h
@@ -1,12 +1,17 @@
 #ifndef QEMU_NET_H
 #define QEMU_NET_H
 
+#include <sys/uio.h>
+
 /* VLANs support */
 
+typedef ssize_t (IOReadvHandler)(void *, const struct iovec *, int);
+
 typedef struct VLANClientState VLANClientState;
 
 struct VLANClientState {
     IOReadHandler *fd_read;
+    IOReadvHandler *fd_readv;
     /* Packets may still be sent if this returns zero.  It's used to
        rate-limit the slirp code.  */
     IOCanRWHandler *fd_can_read;
@@ -30,6 +35,8 @@ VLANClientState *qemu_new_vlan_client(VLANState *vlan,
                                       void *opaque);
 int qemu_can_send_packet(VLANClientState *vc);
 void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size);
+ssize_t qemu_sendv_packet(VLANClientState *vc, const struct iovec *iov,
+                         int iovcnt);
 void qemu_handler_true(void *opaque);
 
 void do_info_network(void);
diff --git a/qemu/vl.c b/qemu/vl.c
index 45c97af..1f0a6ac 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -3820,6 +3820,50 @@ void qemu_send_packet(VLANClientState *vc1, const 
uint8_t *buf, int size)
     }
 }
 
+static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov,
+                              int iovcnt)
+{
+    char buffer[4096];
+    size_t offset = 0;
+    int i;
+
+    for (i = 0; i < iovcnt; i++) {
+       size_t len;
+
+       len = MIN(sizeof(buffer) - offset, iov[i].iov_len);
+       memcpy(buffer + offset, iov[i].iov_base, len);
+       offset += len;
+    }
+
+    vc->fd_read(vc->opaque, buffer, offset);
+
+    return offset;
+}
+
+ssize_t qemu_sendv_packet(VLANClientState *vc1, const struct iovec *iov,
+                         int iovcnt)
+{
+    VLANState *vlan = vc1->vlan;
+    VLANClientState *vc;
+    ssize_t max_len = 0;
+
+    for (vc = vlan->first_client; vc != NULL; vc = vc->next) {
+       ssize_t len = 0;
+
+       if (vc == vc1)
+           continue;
+
+       if (vc->fd_readv)
+           len = vc->fd_readv(vc->opaque, iov, iovcnt);
+       else if (vc->fd_read)
+           len = vc_sendv_compat(vc, iov, iovcnt);
+
+       max_len = MAX(max_len, len);
+    }
+
+    return max_len;
+}
+
 #if defined(CONFIG_SLIRP)
 
 /* slirp network adapter */

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to