From patchwork Thu Jan 17 06:07:11 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luigi Rizzo X-Patchwork-Id: 213145 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id B7D242C007A for ; Thu, 17 Jan 2013 17:08:00 +1100 (EST) Received: from localhost ([::1]:49663 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tvidq-0007Ep-HC for incoming@patchwork.ozlabs.org; Thu, 17 Jan 2013 01:07:58 -0500 Received: from eggs.gnu.org ([208.118.235.92]:41749) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tvidh-0007EX-Vd for qemu-devel@nongnu.org; Thu, 17 Jan 2013 01:07:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Tvidg-000315-74 for qemu-devel@nongnu.org; Thu, 17 Jan 2013 01:07:49 -0500 Received: from onelab2.iet.unipi.it ([131.114.59.238]:54172) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tvidf-00030c-V6 for qemu-devel@nongnu.org; Thu, 17 Jan 2013 01:07:48 -0500 Received: by onelab2.iet.unipi.it (Postfix, from userid 275) id 001457300A; Thu, 17 Jan 2013 07:07:11 +0100 (CET) Date: Thu, 17 Jan 2013 07:07:11 +0100 From: Luigi Rizzo To: qemu-devel@nongnu.org Message-ID: <20130117060711.GA59416@onelab2.iet.unipi.it> References: <20130106192356.GB5019@onelab2.iet.unipi.it> <20130107134944.GE17997@stefanha-thinkpad.redhat.com> Mime-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.4.2.3i X-detected-operating-system: by eggs.gnu.org: Mac OS X 10.x X-Received-From: 131.114.59.238 Subject: [Qemu-devel] [PATCH] fix unbounded qemu NetQueue X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- ../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; }