From patchwork Sun Jan 6 19:23:56 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luigi Rizzo X-Patchwork-Id: 209796 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 C7C1A2C0082 for ; Mon, 7 Jan 2013 06:25:00 +1100 (EST) Received: from localhost ([::1]:52324 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Trvq6-00025t-VO for incoming@patchwork.ozlabs.org; Sun, 06 Jan 2013 14:24:58 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52937) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Trvpw-00022W-CA for qemu-devel@nongnu.org; Sun, 06 Jan 2013 14:24:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Trvpv-0004UC-2O for qemu-devel@nongnu.org; Sun, 06 Jan 2013 14:24:48 -0500 Received: from onelab2.iet.unipi.it ([131.114.59.238]:64502) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Trvpu-0004QT-S4 for qemu-devel@nongnu.org; Sun, 06 Jan 2013 14:24:46 -0500 Received: by onelab2.iet.unipi.it (Postfix, from userid 275) id 3401073027; Sun, 6 Jan 2013 20:23:56 +0100 (CET) Date: Sun, 6 Jan 2013 20:23:56 +0100 From: Luigi Rizzo To: qemu-devel@nongnu.org Message-ID: <20130106192356.GB5019@onelab2.iet.unipi.it> Mime-Version: 1.0 Content-Disposition: inline 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] unbounded qemu NetQue's ? 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 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)