qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 10/13] net: split out packet queueing and flushing i


From: Mark McLoughlin
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

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

Signed-off-by: Mark McLoughlin <address@hidden>
---
 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 via email to

[Prev in Thread] Current Thread [Next in Thread]