Hi, while testing the tx path in qemu without a network backend connected, i noticed that qemu_net_queue_send() builds up an unbounded queue, because QTAILQ* have no notion of a queue length.
As a result, memory usage of a qemu instance can grow to extremely large values. I wonder if it makes sense to implement a hard limit on size of NetQue's. The patch below is only a partial implementation but probably sufficient for these purposes. cheers luigi diff -urp qemu-1.3.0-orig/net/queue.c qemu-1.3.0/net/queue.c --- qemu-1.3.0-orig/net/queue.c 2012-12-03 20:37:05.000000000 +0100 +++ qemu-1.3.0/net/queue.c 2013-01-06 19:38:12.000000000 +0100 @@ -92,6 +92,9 @@ static void qemu_net_queue_append(NetQue { NetPacket *packet; + if (queue->packets.tqh_count > 10000) + return; // XXX drop + packet = g_malloc(sizeof(NetPacket) + size); packet->sender = sender; packet->flags = flags; diff -urp qemu-1.3.0-orig/qemu-queue.h qemu-1.3.0/qemu-queue.h --- qemu-1.3.0-orig/qemu-queue.h 2012-12-03 20:37:05.000000000 +0100 +++ qemu-1.3.0/qemu-queue.h 2013-01-06 19:34:01.000000000 +0100 @@ -320,11 +320,12 @@ struct { struct name { \ qual type *tqh_first; /* first element */ \ qual type *qual *tqh_last; /* addr of last next element */ \ + int32_t tqh_count; \ } #define QTAILQ_HEAD(name, type) Q_TAILQ_HEAD(name, struct type,) #define QTAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first } + { NULL, &(head).tqh_first, 0 } #define Q_TAILQ_ENTRY(type, qual) \ struct { \ @@ -339,6 +340,7 @@ struct { #define QTAILQ_INIT(head) do { \ (head)->tqh_first = NULL; \ (head)->tqh_last = &(head)->tqh_first; \ + (head)->tqh_count = 0; \ } while (/*CONSTCOND*/0) #define QTAILQ_INSERT_HEAD(head, elm, field) do { \ @@ -348,6 +350,7 @@ struct { else \ (head)->tqh_last = &(elm)->field.tqe_next; \ (head)->tqh_first = (elm); \ + (head)->tqh_count++; \ (elm)->field.tqe_prev = &(head)->tqh_first; \ } while (/*CONSTCOND*/0) @@ -356,6 +359,7 @@ struct { (elm)->field.tqe_prev = (head)->tqh_last; \ *(head)->tqh_last = (elm); \ (head)->tqh_last = &(elm)->field.tqe_next; \ + (head)->tqh_count++; \ } while (/*CONSTCOND*/0) #define QTAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ @@ -381,6 +385,7 @@ struct { (elm)->field.tqe_prev; \ else \ (head)->tqh_last = (elm)->field.tqe_prev; \ + (head)->tqh_count--; \ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ } while (/*CONSTCOND*/0)