From patchwork Sat Sep 19 14:43:12 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andreas_F=C3=A4rber?= X-Patchwork-Id: 519742 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id B36F114016A for ; Sun, 20 Sep 2015 00:46:40 +1000 (AEST) Received: from localhost ([::1]:46322 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZdJPS-0004Tq-G3 for incoming@patchwork.ozlabs.org; Sat, 19 Sep 2015 10:46:38 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47349) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZdJMY-00089b-JS for qemu-devel@nongnu.org; Sat, 19 Sep 2015 10:43:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZdJMV-0006Yh-Ud for qemu-devel@nongnu.org; Sat, 19 Sep 2015 10:43:38 -0400 Received: from mx2.suse.de ([195.135.220.15]:40301) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZdJMV-0006YU-Oe for qemu-devel@nongnu.org; Sat, 19 Sep 2015 10:43:35 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id E51DCAD9B; Sat, 19 Sep 2015 14:43:34 +0000 (UTC) From: =?UTF-8?q?Andreas=20F=C3=A4rber?= To: qemu-devel@nongnu.org Date: Sat, 19 Sep 2015 16:43:12 +0200 Message-Id: <1442673810-2679-4-git-send-email-afaerber@suse.de> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1442673810-2679-1-git-send-email-afaerber@suse.de> References: <1442673810-2679-1-git-send-email-afaerber@suse.de> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] X-Received-From: 195.135.220.15 Cc: Pavel Fedin , =?UTF-8?q?Andreas=20F=C3=A4rber?= Subject: [Qemu-devel] [PULL 03/21] qdev: Do not use slow [*] expansion for GPIO creation 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 From: Pavel Fedin Expansion of [*] suffix is very slow because index expansion is done using trial and error strategy, starting every time from zero and retrying with the next index until insertion succeeds. With large number of already added properties this process takes huge amount of time (O(n^2) complexity). Some architectures (like ARM) use very large amount of IRQ pins in interrupt controller models. This flaw makes machine startup extremely slow (~20 seconds for ARM64 with 32 CPUs). This patch decreases this time down to ~10 seconds. Also in qdev_init_gpio_out_named() memset() is now called only once for the whole array instead of per-cell cleaning Signed-off-by: Pavel Fedin Reviewed-by: Daniel P. Berrange Signed-off-by: Andreas Färber --- hw/core/qdev.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index a24493a..4ab04aa 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -417,17 +417,21 @@ void qdev_init_gpio_in_named(DeviceState *dev, qemu_irq_handler handler, { int i; NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name); - char *propname = g_strdup_printf("%s[*]", name ? name : "unnamed-gpio-in"); assert(gpio_list->num_out == 0 || !name); gpio_list->in = qemu_extend_irqs(gpio_list->in, gpio_list->num_in, handler, dev, n); + if (!name) { + name = "unnamed-gpio-in"; + } for (i = gpio_list->num_in; i < gpio_list->num_in + n; i++) { + gchar *propname = g_strdup_printf("%s[%u]", name, i); + object_property_add_child(OBJECT(dev), propname, OBJECT(gpio_list->in[i]), &error_abort); + g_free(propname); } - g_free(propname); gpio_list->num_in += n; } @@ -442,20 +446,25 @@ void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins, { int i; NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name); - char *propname = g_strdup_printf("%s[*]", name ? name : "unnamed-gpio-out"); assert(gpio_list->num_in == 0 || !name); - gpio_list->num_out += n; + if (!name) { + name = "unnamed-gpio-out"; + } + memset(pins, 0, sizeof(*pins) * n); for (i = 0; i < n; ++i) { - memset(&pins[i], 0, sizeof(*pins)); + gchar *propname = g_strdup_printf("%s[%u]", name, + gpio_list->num_out + i); + object_property_add_link(OBJECT(dev), propname, TYPE_IRQ, (Object **)&pins[i], object_property_allow_set_link, OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort); + g_free(propname); } - g_free(propname); + gpio_list->num_out += n; } void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)