All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mark McLoughlin <markmc@redhat.com>
To: Anthony Liguori <aliguori@us.ibm.com>
Cc: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 10/13] net: split out packet queueing and flushing into separate functions
Date: Fri, 22 May 2009 15:23:36 +0100	[thread overview]
Message-ID: <1243002216.29542.5.camel@blaa> (raw)
In-Reply-To: <1242726931-5726-10-git-send-email-markmc@redhat.com>

We'll be doing more packet queueing in later commits.

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
 net.c |  155 +++++++++++++++++++++++++++++++++++++++++------------------------
 1 files changed, 98 insertions(+), 57 deletions(-)

diff --git a/net.c b/net.c
index 07bf8d8..2f4743e 100644
--- a/net.c
+++ b/net.c
@@ -415,6 +415,8 @@ qemu_deliver_packet(VLANClientState *sender, const uint8_t *buf, int size)
     VLANClientState *vc;
     int ret = -1;
 
+    sender->vlan->delivering = 1;
+
     for (vc = sender->vlan->first_client; vc != NULL; vc = vc->next) {
         ssize_t len;
 
@@ -432,13 +434,38 @@ qemu_deliver_packet(VLANClientState *sender, const uint8_t *buf, int size)
         ret = (ret >= 0) ? ret : len;
     }
 
+    sender->vlan->delivering = 0;
+
     return ret;
 }
 
+static void qemu_flush_queued_packets(VLANClientState *vc)
+{
+    VLANPacket *packet;
+
+    while ((packet = vc->vlan->send_queue) != NULL) {
+        vc->vlan->send_queue = packet->next;
+        qemu_deliver_packet(packet->sender, packet->data, packet->size);
+        qemu_free(packet);
+    }
+}
+
+static void
+qemu_enqueue_packet(VLANClientState *sender, const uint8_t *buf, int size)
+{
+    VLANPacket *packet;
+
+    packet = qemu_malloc(sizeof(VLANPacket) + size);
+    packet->next = sender->vlan->send_queue;
+    packet->sender = sender;
+    packet->size = size;
+    memcpy(packet->data, buf, size);
+    sender->vlan->send_queue = packet;
+}
+
 void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
 {
     VLANState *vlan = vc->vlan;
-    VLANPacket *packet;
 
     if (vc->link_down)
         return;
@@ -448,22 +475,12 @@ void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
     hex_dump(stdout, buf, size);
 #endif
     if (vlan->delivering) {
-        packet = qemu_malloc(sizeof(VLANPacket) + size);
-        packet->next = vlan->send_queue;
-        packet->sender = vc;
-        packet->size = size;
-        memcpy(packet->data, buf, size);
-        vlan->send_queue = packet;
-    } else {
-        vlan->delivering = 1;
-        qemu_deliver_packet(vc, buf, size);
-        while ((packet = vlan->send_queue) != NULL) {
-            vlan->send_queue = packet->next;
-            qemu_deliver_packet(packet->sender, packet->data, packet->size);
-            qemu_free(packet);
-        }
-        vlan->delivering = 0;
+        qemu_enqueue_packet(vc, buf, size);
+        return;
     }
+
+    qemu_deliver_packet(vc, buf, size);
+    qemu_flush_queued_packets(vc);
 }
 
 static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov,
@@ -496,60 +513,84 @@ static ssize_t calc_iov_length(const struct iovec *iov, int iovcnt)
     return offset;
 }
 
-ssize_t qemu_sendv_packet(VLANClientState *sender, const struct iovec *iov,
-                          int iovcnt)
+static int qemu_deliver_packet_iov(VLANClientState *sender,
+                                   const struct iovec *iov, int iovcnt)
 {
-    VLANState *vlan = sender->vlan;
     VLANClientState *vc;
+    int ret = -1;
+
+    sender->vlan->delivering = 1;
+
+    for (vc = sender->vlan->first_client; vc != NULL; vc = vc->next) {
+        ssize_t len;
+
+        if (vc == sender) {
+            continue;
+        }
+
+        if (vc->link_down) {
+            ret = calc_iov_length(iov, iovcnt);
+            continue;
+        }
+
+        if (vc->receive_iov) {
+            len = vc->receive_iov(vc, iov, iovcnt);
+        } else {
+            len = vc_sendv_compat(vc, iov, iovcnt);
+        }
+
+        ret = (ret >= 0) ? ret : len;
+    }
+
+    sender->vlan->delivering = 0;
+
+    return ret;
+}
+
+static ssize_t qemu_enqueue_packet_iov(VLANClientState *sender,
+                                       const struct iovec *iov, int iovcnt)
+{
     VLANPacket *packet;
-    ssize_t max_len = 0;
+    size_t max_len = 0;
     int i;
 
-    if (sender->link_down)
-        return calc_iov_length(iov, iovcnt);
+    max_len = calc_iov_length(iov, iovcnt);
 
-    if (vlan->delivering) {
-        max_len = calc_iov_length(iov, iovcnt);
+    packet = qemu_malloc(sizeof(VLANPacket) + max_len);
+    packet->next = sender->vlan->send_queue;
+    packet->sender = sender;
+    packet->size = 0;
 
-        packet = qemu_malloc(sizeof(VLANPacket) + max_len);
-        packet->next = vlan->send_queue;
-        packet->sender = sender;
-        packet->size = 0;
-        for (i = 0; i < iovcnt; i++) {
-            size_t len = iov[i].iov_len;
+    for (i = 0; i < iovcnt; i++) {
+        size_t len = iov[i].iov_len;
 
-            memcpy(packet->data + packet->size, iov[i].iov_base, len);
-            packet->size += len;
-        }
-        vlan->send_queue = packet;
-    } else {
-        vlan->delivering = 1;
+        memcpy(packet->data + packet->size, iov[i].iov_base, len);
+        packet->size += len;
+    }
 
-        for (vc = vlan->first_client; vc != NULL; vc = vc->next) {
-            ssize_t len = 0;
+    sender->vlan->send_queue = packet;
 
-            if (vc == sender) {
-                continue;
-            }
-            if (vc->link_down) {
-                len = calc_iov_length(iov, iovcnt);
-            } else if (vc->receive_iov) {
-                len = vc->receive_iov(vc, iov, iovcnt);
-            } else if (vc->receive) {
-                len = vc_sendv_compat(vc, iov, iovcnt);
-            }
-            max_len = MAX(max_len, len);
-        }
+    return packet->size;
+}
 
-        while ((packet = vlan->send_queue) != NULL) {
-            vlan->send_queue = packet->next;
-            qemu_deliver_packet(packet->sender, packet->data, packet->size);
-            qemu_free(packet);
-        }
-        vlan->delivering = 0;
+ssize_t qemu_sendv_packet(VLANClientState *sender, const struct iovec *iov,
+                          int iovcnt)
+{
+    int ret;
+
+    if (sender->link_down) {
+        return calc_iov_length(iov, iovcnt);
+    }
+
+    if (sender->vlan->delivering) {
+        return qemu_enqueue_packet_iov(sender, iov, iovcnt);
     }
 
-    return max_len;
+    ret = qemu_deliver_packet_iov(sender, iov, iovcnt);
+
+    qemu_flush_queued_packets(sender);
+
+    return ret;
 }
 
 #if defined(CONFIG_SLIRP)
-- 
1.6.0.6

  reply	other threads:[~2009-05-22 14:23 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-05-19  9:55 [Qemu-devel] [PATCH 0/13] Add generic packet buffering API Mark McLoughlin
2009-05-19  9:55 ` [Qemu-devel] [PATCH 01/13] net: factor tap_read_packet() out of tap_send() Mark McLoughlin
2009-05-19  9:55   ` [Qemu-devel] [PATCH 02/13] net: move the tap buffer into TAPState Mark McLoughlin
2009-05-19  9:55     ` [Qemu-devel] [PATCH 03/13] net: vlan clients with no fd_can_read() can always receive Mark McLoughlin
2009-05-19  9:55       ` [Qemu-devel] [PATCH 04/13] net: only read from tapfd when we can send Mark McLoughlin
2009-05-19  9:55         ` [Qemu-devel] [PATCH 05/13] net: add fd_readv() handler to qemu_new_vlan_client() args Mark McLoughlin
2009-05-19  9:55           ` [Qemu-devel] [PATCH 06/13] net: re-name vc->fd_read() to vc->receive() Mark McLoughlin
2009-05-19  9:55             ` [Qemu-devel] [PATCH 07/13] net: pass VLANClientState* as first arg to receive handlers Mark McLoughlin
2009-05-19  9:55               ` [Qemu-devel] [PATCH 08/13] net: add return value to packet receive handler Mark McLoughlin
2009-05-19  9:55                 ` [Qemu-devel] [PATCH 09/13] net: return status from qemu_deliver_packet() Mark McLoughlin
2009-05-22 14:23                   ` Mark McLoughlin [this message]
2009-05-22 14:24                     ` [Qemu-devel] [PATCH 11/13] net: add qemu_send_packet_async() Mark McLoughlin
2009-05-22 14:24                       ` [Qemu-devel] [PATCH 12/13] net: make use of async packet sending API in tap client Mark McLoughlin
2009-05-22 14:25                         ` [Qemu-devel] [PATCH 13/13] virtio-net: implement rx packet queueing Mark McLoughlin
2009-05-19 10:18 ` [Qemu-devel] [PATCH 0/13] Add generic packet buffering API Avi Kivity
2009-05-19 10:33   ` Mark McLoughlin
2009-05-19 11:56     ` Avi Kivity
2009-05-22 13:43 ` [Qemu-devel] " Anthony Liguori
2009-05-22 14:23   ` Mark McLoughlin

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=1243002216.29542.5.camel@blaa \
    --to=markmc@redhat.com \
    --cc=aliguori@us.ibm.com \
    --cc=qemu-devel@nongnu.org \
    /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.