From patchwork Thu Feb 21 09:45:57 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Wang X-Patchwork-Id: 222228 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 3817F2C008E for ; Thu, 21 Feb 2013 20:55:14 +1100 (EST) Received: from localhost ([::1]:34127 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U8Srv-0007yh-B2 for incoming@patchwork.ozlabs.org; Thu, 21 Feb 2013 04:55:11 -0500 Received: from eggs.gnu.org ([208.118.235.92]:33597) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U8Srl-0007wg-L4 for qemu-devel@nongnu.org; Thu, 21 Feb 2013 04:55:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1U8Sre-0008SQ-OS for qemu-devel@nongnu.org; Thu, 21 Feb 2013 04:55:01 -0500 Received: from mx1.redhat.com ([209.132.183.28]:51213) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U8Sre-0008Rx-H0; Thu, 21 Feb 2013 04:54:54 -0500 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r1L9sr9U016927 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 21 Feb 2013 04:54:53 -0500 Received: from amd-6168-8-1.englab.nay.redhat.com (amd-6168-8-1.englab.nay.redhat.com [10.66.104.52]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r1L9smAU014440; Thu, 21 Feb 2013 04:54:49 -0500 From: Jason Wang To: stefanha@redhat.com, aliguori@us.ibm.com, qemu-devel@nongnu.org Date: Thu, 21 Feb 2013 17:45:57 +0800 Message-Id: <1361439957-16507-1-git-send-email-jasowang@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Jason Wang , qemu-stable@nongnu.org, Edivaldo de Araujo Pereira Subject: [Qemu-devel] [PATCH] net: reduce the unnecessary memory allocation of multiqueue 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 Edivaldo reports a problem that the array of NetClientState in NICState is too large - MAX_QUEUE_NUM(1024) which will wastes memory even if multiqueue is not used. Instead of static arrays, solving this issue by allocating the queues on demand for both the NetClientState array in NICState and VirtIONetQueue array in VirtIONet. Tested by myself, with single virtio-net-pci device. The memory allocation is almost the same as when multiqueue is not merged. Cc: Edivaldo de Araujo Pereira Cc: qemu-stable@nongnu.org Signed-off-by: Jason Wang --- hw/virtio-net.c | 6 ++++-- include/net/net.h | 2 +- net/net.c | 19 +++++++++---------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/hw/virtio-net.c b/hw/virtio-net.c index 573c669..70ab641 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -44,7 +44,7 @@ typedef struct VirtIONet VirtIODevice vdev; uint8_t mac[ETH_ALEN]; uint16_t status; - VirtIONetQueue vqs[MAX_QUEUE_NUM]; + VirtIONetQueue *vqs; VirtQueue *ctrl_vq; NICState *nic; uint32_t tx_timeout; @@ -1326,8 +1326,9 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf, n->vdev.set_status = virtio_net_set_status; n->vdev.guest_notifier_mask = virtio_net_guest_notifier_mask; n->vdev.guest_notifier_pending = virtio_net_guest_notifier_pending; + n->max_queues = MAX(conf->queues, 1); + n->vqs = g_malloc0(sizeof(VirtIONetQueue) * n->max_queues); n->vqs[0].rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx); - n->max_queues = conf->queues; n->curr_queues = 1; n->vqs[0].n = n; n->tx_timeout = net->txtimer; @@ -1397,6 +1398,7 @@ void virtio_net_exit(VirtIODevice *vdev) g_free(n->mac_table.macs); g_free(n->vlans); + g_free(n->vqs); for (i = 0; i < n->max_queues; i++) { VirtIONetQueue *q = &n->vqs[i]; diff --git a/include/net/net.h b/include/net/net.h index 43a045e..cb049a1 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -72,7 +72,7 @@ struct NetClientState { }; typedef struct NICState { - NetClientState ncs[MAX_QUEUE_NUM]; + NetClientState *ncs; NICConf *conf; void *opaque; bool peer_deleted; diff --git a/net/net.c b/net/net.c index be03a8d..6262ed0 100644 --- a/net/net.c +++ b/net/net.c @@ -235,23 +235,20 @@ NICState *qemu_new_nic(NetClientInfo *info, const char *name, void *opaque) { - NetClientState *nc; NetClientState **peers = conf->peers.ncs; NICState *nic; - int i; + int i, queues = MAX(1, conf->queues); assert(info->type == NET_CLIENT_OPTIONS_KIND_NIC); assert(info->size >= sizeof(NICState)); - nc = qemu_new_net_client(info, peers[0], model, name); - nc->queue_index = 0; - - nic = qemu_get_nic(nc); + nic = g_malloc0(info->size + sizeof(NetClientState) * queues); + nic->ncs = (void *)nic + info->size; nic->conf = conf; nic->opaque = opaque; - for (i = 1; i < conf->queues; i++) { - qemu_net_client_setup(&nic->ncs[i], info, peers[i], model, nc->name, + for (i = 0; i < queues; i++) { + qemu_net_client_setup(&nic->ncs[i], info, peers[i], model, name, NULL); nic->ncs[i].queue_index = i; } @@ -261,7 +258,7 @@ NICState *qemu_new_nic(NetClientInfo *info, NetClientState *qemu_get_subqueue(NICState *nic, int queue_index) { - return &nic->ncs[queue_index]; + return nic->ncs + queue_index; } NetClientState *qemu_get_queue(NICState *nic) @@ -273,7 +270,7 @@ NICState *qemu_get_nic(NetClientState *nc) { NetClientState *nc0 = nc - nc->queue_index; - return DO_UPCAST(NICState, ncs[0], nc0); + return (NICState *)((void *)nc0 - nc->info->size); } void *qemu_get_nic_opaque(NetClientState *nc) @@ -368,6 +365,8 @@ void qemu_del_nic(NICState *nic) qemu_cleanup_net_client(nc); qemu_free_net_client(nc); } + + g_free(nic); } void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)