public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] Add method to send fragmented packets
@ 2008-05-13 19:13 Anthony Liguori
  2008-05-13 19:13 ` [PATCH 2/4] Add fd_readv handler to tap Anthony Liguori
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Anthony Liguori @ 2008-05-13 19:13 UTC (permalink / raw)
  To: kvm-devel; +Cc: Anthony Liguori, Avi Kivity

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 <aliguori@us.ibm.com>

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/

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/4] Add fd_readv handler to tap
  2008-05-13 19:13 [PATCH 1/4] Add method to send fragmented packets Anthony Liguori
@ 2008-05-13 19:13 ` Anthony Liguori
  2008-05-13 19:13 ` [PATCH 3/4] Use fragmented send for virtio Anthony Liguori
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Anthony Liguori @ 2008-05-13 19:13 UTC (permalink / raw)
  To: kvm-devel; +Cc: Anthony Liguori, Avi Kivity

This allows fragmented packets to be sent with no additional copies over the
tap interface.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/qemu/vl.c b/qemu/vl.c
index 1f0a6ac..7900b76 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -4086,6 +4086,19 @@ static void tap_receive(void *opaque, const uint8_t *buf, int size)
     }
 }
 
+static ssize_t tap_readv(void *opaque, const struct iovec *iov,
+			 int iovcnt)
+{
+    TAPState *s = opaque;
+    ssize_t len;
+
+    do {
+	len = writev(s->fd, iov, iovcnt);
+    } while (len == -1 && (errno == EINTR || errno == EAGAIN));
+
+    return len;
+}
+
 static void tap_send(void *opaque)
 {
     TAPState *s = opaque;
@@ -4135,6 +4148,7 @@ static TAPState *net_tap_fd_init(VLANState *vlan, int fd)
     s->no_poll = 0;
     enable_sigio_timer(fd);
     s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s);
+    s->vc->fd_readv = tap_readv;
     qemu_set_fd_handler2(s->fd, tap_read_poll, tap_send, NULL, s);
     snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd);
     return s;

-------------------------------------------------------------------------
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/

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/4] Use fragmented send for virtio
  2008-05-13 19:13 [PATCH 1/4] Add method to send fragmented packets Anthony Liguori
  2008-05-13 19:13 ` [PATCH 2/4] Add fd_readv handler to tap Anthony Liguori
@ 2008-05-13 19:13 ` Anthony Liguori
  2008-05-13 19:13 ` [PATCH 4/4] Validate virtio-net TX header Anthony Liguori
  2008-05-14 12:38 ` [PATCH 1/4] Add method to send fragmented packets Avi Kivity
  3 siblings, 0 replies; 5+ messages in thread
From: Anthony Liguori @ 2008-05-13 19:13 UTC (permalink / raw)
  To: kvm-devel; +Cc: Anthony Liguori, Avi Kivity

This patch converts virtio-net to use the new fragmented send interface.
We should have always supported this.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/qemu/hw/virtio-net.c b/qemu/hw/virtio-net.c
index 85cc9d2..93bca1d 100644
--- a/qemu/hw/virtio-net.c
+++ b/qemu/hw/virtio-net.c
@@ -239,23 +239,15 @@ again:
 static void virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq)
 {
     VirtQueueElement elem;
-    int count = 0;
 
     if (!(n->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK))
         return;
 
     while (virtqueue_pop(vq, &elem)) {
-	int i;
-	size_t len = 0;
+	ssize_t len = 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;
-	}
-
-	count++;
+	len = qemu_sendv_packet(n->vc, &elem.out_sg[1], elem.out_num - 1);
 
 	virtqueue_push(vq, &elem, sizeof(struct virtio_net_hdr) + len);
 	virtio_notify(&n->vdev, vq);

-------------------------------------------------------------------------
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/

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 4/4] Validate virtio-net TX header
  2008-05-13 19:13 [PATCH 1/4] Add method to send fragmented packets Anthony Liguori
  2008-05-13 19:13 ` [PATCH 2/4] Add fd_readv handler to tap Anthony Liguori
  2008-05-13 19:13 ` [PATCH 3/4] Use fragmented send for virtio Anthony Liguori
@ 2008-05-13 19:13 ` Anthony Liguori
  2008-05-14 12:38 ` [PATCH 1/4] Add method to send fragmented packets Avi Kivity
  3 siblings, 0 replies; 5+ messages in thread
From: Anthony Liguori @ 2008-05-13 19:13 UTC (permalink / raw)
  To: kvm-devel; +Cc: Anthony Liguori, Avi Kivity

Missed this one in my last series.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/qemu/hw/virtio-net.c b/qemu/hw/virtio-net.c
index 93bca1d..ca45775 100644
--- a/qemu/hw/virtio-net.c
+++ b/qemu/hw/virtio-net.c
@@ -246,6 +246,12 @@ static void virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq)
     while (virtqueue_pop(vq, &elem)) {
 	ssize_t len = 0;
 
+	if (elem.out_num < 1 ||
+	    elem.out_sg[0].iov_len != sizeof(struct virtio_net_hdr)) {
+		fprintf(stderr, "virtio-net header not in first element\n");
+		exit(1);
+	}
+
 	/* ignore the header for now */
 	len = qemu_sendv_packet(n->vc, &elem.out_sg[1], elem.out_num - 1);
 

-------------------------------------------------------------------------
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/

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/4] Add method to send fragmented packets
  2008-05-13 19:13 [PATCH 1/4] Add method to send fragmented packets Anthony Liguori
                   ` (2 preceding siblings ...)
  2008-05-13 19:13 ` [PATCH 4/4] Validate virtio-net TX header Anthony Liguori
@ 2008-05-14 12:38 ` Avi Kivity
  3 siblings, 0 replies; 5+ messages in thread
From: Avi Kivity @ 2008-05-14 12:38 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: kvm-devel

Anthony Liguori wrote:
> 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.
>   

Applied all, thanks.

-- 
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
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/

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2008-05-14 12:38 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-13 19:13 [PATCH 1/4] Add method to send fragmented packets Anthony Liguori
2008-05-13 19:13 ` [PATCH 2/4] Add fd_readv handler to tap Anthony Liguori
2008-05-13 19:13 ` [PATCH 3/4] Use fragmented send for virtio Anthony Liguori
2008-05-13 19:13 ` [PATCH 4/4] Validate virtio-net TX header Anthony Liguori
2008-05-14 12:38 ` [PATCH 1/4] Add method to send fragmented packets Avi Kivity

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox