qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH] fix unbounded qemu NetQueue


From: Luigi Rizzo
Subject: [Qemu-devel] [PATCH] fix unbounded qemu NetQueue
Date: Thu, 17 Jan 2013 07:07:11 +0100
User-agent: Mutt/1.4.2.3i

The comment at the beginning of net/queue.c says that packets that
cannot be sent by qemu_net_queue_send() should not be enqueued
unless a callback is set.

This patch implements this behaviour, that prevents a queue to grow
unbounded (e.g. when a network backend is not connected).

Also for good measure the patch implements bounded size queues
(though it should not be necessary now because each source can only have
one packet queued). When a packet is dropped because excessive
queue size the callback is not supposed to be called.

cheers
luigi

Signed-off-by: Luigi Rizzo <address@hidden>
--- ../orig/net/queue.c 2012-12-03 11:37:05.000000000 -0800
+++ ./net/queue.c       2013-01-16 21:37:20.109732443 -0800
@@ -50,6 +50,8 @@ struct NetPacket {
 
 struct NetQueue {
     void *opaque;
+    uint32_t nq_maxlen;
+    uint32_t nq_count;
 
     QTAILQ_HEAD(packets, NetPacket) packets;
 
@@ -63,6 +65,8 @@ NetQueue *qemu_new_net_queue(void *opaqu
     queue = g_malloc0(sizeof(NetQueue));
 
     queue->opaque = opaque;
+    queue->nq_maxlen = 10000; /* arbitrary limit */
+    queue->nq_count = 0;
 
     QTAILQ_INIT(&queue->packets);
 
@@ -92,6 +96,8 @@ static void qemu_net_queue_append(NetQue
 {
     NetPacket *packet;
 
+    if (!sent_cb || queue->nq_count >= queue->nq_maxlen)
+       return;
     packet = g_malloc(sizeof(NetPacket) + size);
     packet->sender = sender;
     packet->flags = flags;
@@ -99,6 +105,7 @@ static void qemu_net_queue_append(NetQue
     packet->sent_cb = sent_cb;
     memcpy(packet->data, buf, size);
 
+    queue->nq_count++;
     QTAILQ_INSERT_TAIL(&queue->packets, packet, entry);
 }
 
@@ -113,6 +120,8 @@ static void qemu_net_queue_append_iov(Ne
     size_t max_len = 0;
     int i;
 
+    if (!sent_cb || queue->nq_count >= queue->nq_maxlen)
+       return;
     for (i = 0; i < iovcnt; i++) {
         max_len += iov[i].iov_len;
     }
@@ -130,6 +139,7 @@ static void qemu_net_queue_append_iov(Ne
         packet->size += len;
     }
 
+    queue->nq_count++;
     QTAILQ_INSERT_TAIL(&queue->packets, packet, entry);
 }
 
@@ -220,6 +230,7 @@ void qemu_net_queue_purge(NetQueue *queu
     QTAILQ_FOREACH_SAFE(packet, &queue->packets, entry, next) {
         if (packet->sender == from) {
             QTAILQ_REMOVE(&queue->packets, packet, entry);
+            queue->nq_count--;
             g_free(packet);
         }
     }
@@ -233,6 +244,7 @@ bool qemu_net_queue_flush(NetQueue *queu
 
         packet = QTAILQ_FIRST(&queue->packets);
         QTAILQ_REMOVE(&queue->packets, packet, entry);
+        queue->nq_count--;
 
         ret = qemu_net_queue_deliver(queue,
                                      packet->sender,
@@ -240,6 +252,7 @@ bool qemu_net_queue_flush(NetQueue *queu
                                      packet->data,
                                      packet->size);
         if (ret == 0) {
+            queue->nq_count++;
             QTAILQ_INSERT_HEAD(&queue->packets, packet, entry);
             return false;
         }



reply via email to

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