From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MgG4W-0001IU-Bw for qemu-devel@nongnu.org; Wed, 26 Aug 2009 06:49:44 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MgG4R-0001HH-H3 for qemu-devel@nongnu.org; Wed, 26 Aug 2009 06:49:43 -0400 Received: from [199.232.76.173] (port=44302 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MgG4R-0001HA-3j for qemu-devel@nongnu.org; Wed, 26 Aug 2009 06:49:39 -0400 Received: from david.siemens.de ([192.35.17.14]:23762) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1MgG4Q-0002GV-8q for qemu-devel@nongnu.org; Wed, 26 Aug 2009 06:49:38 -0400 Message-ID: <4A951340.4060807@siemens.com> Date: Wed, 26 Aug 2009 12:49:36 +0200 From: Jan Kiszka MIME-Version: 1.0 References: <4A9512A8.1070709@siemens.com> In-Reply-To: <4A9512A8.1070709@siemens.com> Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] Re: [PATCH] net: Fix send queue ordering List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Anthony Liguori Cc: Mark McLoughlin , qemu-devel Jan Kiszka wrote: > Ensure that packets enqueued for delayed delivery are dequeued in FIFO > order. At least one simplistic guest TCP/IP stack became unhappy due to > sporadically reordered packet streams. Before I forget: This should also be considered for 0.11-rc (it's a 0.11 regression). > > At this chance, switch the send queue implementation to TAILQ. > > Signed-off-by: Jan Kiszka > --- > > net.c | 29 ++++++++++++----------------- > net.h | 5 +++-- > 2 files changed, 15 insertions(+), 19 deletions(-) > > diff --git a/net.c b/net.c > index 1b531e7..d7a1ab6 100644 > --- a/net.c > +++ b/net.c > @@ -436,33 +436,28 @@ qemu_deliver_packet(VLANClientState *sender, const uint8_t *buf, int size) > > void qemu_purge_queued_packets(VLANClientState *vc) > { > - VLANPacket **pp = &vc->vlan->send_queue; > - > - while (*pp != NULL) { > - VLANPacket *packet = *pp; > + VLANPacket *packet, *next; > > + TAILQ_FOREACH_SAFE(packet, &vc->vlan->send_queue, entry, next) { > if (packet->sender == vc) { > - *pp = packet->next; > + TAILQ_REMOVE(&vc->vlan->send_queue, packet, entry); > qemu_free(packet); > - } else { > - pp = &packet->next; > } > } > } > > void qemu_flush_queued_packets(VLANClientState *vc) > { > - VLANPacket *packet; > - > - while ((packet = vc->vlan->send_queue) != NULL) { > + while (!TAILQ_EMPTY(&vc->vlan->send_queue)) { > + VLANPacket *packet; > int ret; > > - vc->vlan->send_queue = packet->next; > + packet = TAILQ_FIRST(&vc->vlan->send_queue); > + TAILQ_REMOVE(&vc->vlan->send_queue, packet, entry); > > ret = qemu_deliver_packet(packet->sender, packet->data, packet->size); > if (ret == 0 && packet->sent_cb != NULL) { > - packet->next = vc->vlan->send_queue; > - vc->vlan->send_queue = packet; > + TAILQ_INSERT_HEAD(&vc->vlan->send_queue, packet, entry); > break; > } > > @@ -480,12 +475,12 @@ static void qemu_enqueue_packet(VLANClientState *sender, > VLANPacket *packet; > > packet = qemu_malloc(sizeof(VLANPacket) + size); > - packet->next = sender->vlan->send_queue; > packet->sender = sender; > packet->size = size; > packet->sent_cb = sent_cb; > memcpy(packet->data, buf, size); > - sender->vlan->send_queue = packet; > + > + TAILQ_INSERT_TAIL(&sender->vlan->send_queue, packet, entry); > } > > ssize_t qemu_send_packet_async(VLANClientState *sender, > @@ -597,7 +592,6 @@ static ssize_t qemu_enqueue_packet_iov(VLANClientState *sender, > max_len = calc_iov_length(iov, iovcnt); > > packet = qemu_malloc(sizeof(VLANPacket) + max_len); > - packet->next = sender->vlan->send_queue; > packet->sender = sender; > packet->sent_cb = sent_cb; > packet->size = 0; > @@ -609,7 +603,7 @@ static ssize_t qemu_enqueue_packet_iov(VLANClientState *sender, > packet->size += len; > } > > - sender->vlan->send_queue = packet; > + TAILQ_INSERT_TAIL(&sender->vlan->send_queue, packet, entry); > > return packet->size; > } > @@ -2330,6 +2324,7 @@ VLANState *qemu_find_vlan(int id, int allocate) > } > vlan = qemu_mallocz(sizeof(VLANState)); > vlan->id = id; > + TAILQ_INIT(&vlan->send_queue); > vlan->next = NULL; > pvlan = &first_vlan; > while (*pvlan != NULL) > diff --git a/net.h b/net.h > index 3ac9e8c..bab02f5 100644 > --- a/net.h > +++ b/net.h > @@ -1,6 +1,7 @@ > #ifndef QEMU_NET_H > #define QEMU_NET_H > > +#include "sys-queue.h" > #include "qemu-common.h" > > /* VLANs support */ > @@ -35,7 +36,7 @@ typedef struct VLANPacket VLANPacket; > typedef void (NetPacketSent) (VLANClientState *, ssize_t); > > struct VLANPacket { > - struct VLANPacket *next; > + TAILQ_ENTRY(VLANPacket) entry; > VLANClientState *sender; > int size; > NetPacketSent *sent_cb; > @@ -47,7 +48,7 @@ struct VLANState { > VLANClientState *first_client; > struct VLANState *next; > unsigned int nb_guest_devs, nb_host_devs; > - VLANPacket *send_queue; > + TAILQ_HEAD(send_queue, VLANPacket) send_queue; > int delivering; > }; > > Jan -- Siemens AG, Corporate Technology, CT SE 2 Corporate Competence Center Embedded Linux