From patchwork Mon Jan 21 12:30:17 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 214147 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 49B8B2C007B for ; Tue, 22 Jan 2013 00:20:39 +1100 (EST) Received: from localhost ([::1]:42243 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TxGX1-0006EZ-AB for incoming@patchwork.ozlabs.org; Mon, 21 Jan 2013 07:31:19 -0500 Received: from eggs.gnu.org ([208.118.235.92]:43551) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TxGWV-0005He-MP for qemu-devel@nongnu.org; Mon, 21 Jan 2013 07:30:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TxGWU-0006fU-2i for qemu-devel@nongnu.org; Mon, 21 Jan 2013 07:30:47 -0500 Received: from mail-ee0-f51.google.com ([74.125.83.51]:42984) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TxGWT-0006fN-SY for qemu-devel@nongnu.org; Mon, 21 Jan 2013 07:30:46 -0500 Received: by mail-ee0-f51.google.com with SMTP id d17so2773989eek.10 for ; Mon, 21 Jan 2013 04:30:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:sender:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references; bh=IUZTUw1n4e94dBXv4UsEthjVfUOCBT1hsbZCnQNNqig=; b=iB/oLyL7XQfdwQJoLAelVeBp0FSiLorWJy7xD0xJr8xnzf1SghDPBgBM8yVtGCP9VS FGURrBDA5cuRll7lz7NdKZm6lu3HyldSwCqLE2keCZdxG1eQcDZPa5FQNhPBDhF+iFcD Q2YnQgI6bX/Wtx6kOkieg5pyttLX6u5WJEkrz4CaJKkDysaCdDHOe9QdzHmqHylobsAM b8gXLnhOnNmU78T7vKPJZJD9GORhmYY6ghc0tpE5WMP/F111Cuw95yzTaI1SRCEoS3ov fIkoKRh/lPoX6jSRd/H/giROmMZexQ8CadH3MTkqQWrkoWzcF3p71Vwh7IwgCfblglmP DnYA== X-Received: by 10.14.224.199 with SMTP id x47mr59733339eep.19.1358771443539; Mon, 21 Jan 2013 04:30:43 -0800 (PST) Received: from yakj.lan (93-34-179-137.ip50.fastwebnet.it. [93.34.179.137]) by mx.google.com with ESMTPS id 46sm22102581eeg.4.2013.01.21.04.30.41 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Mon, 21 Jan 2013 04:30:42 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Mon, 21 Jan 2013 13:30:17 +0100 Message-Id: <1358771422-14282-8-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.1 In-Reply-To: <1358771422-14282-1-git-send-email-pbonzini@redhat.com> References: <1358771422-14282-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 74.125.83.51 Cc: aliguori@us.ibm.com, afaerber@suse.de Subject: [Qemu-devel] [PATCH v2 07/12] qdev: move unrealization of devices from finalize to unparent 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 Similarly, a bus holds a reference back to the device, and this will prevent the device from going away as soon as this reference is counted properly. To avoid this, move the unrealization of devices to the unparent callback. This includes recursively unparenting all the buses and (after the previous patch) the devices on those buses, which ensures that the web of references completely disappears for all devices that reside (in the qdev tree) below the one being unplugged. After this patch, the qdev tree and the bus<->child relationship is defined as "A is above B, iff unplugging A will automatically unplug B". Signed-off-by: Paolo Bonzini --- hw/qdev.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/hw/qdev.c b/hw/qdev.c index 83420ac..aad360f 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -738,23 +738,8 @@ static void device_initfn(Object *obj) static void device_finalize(Object *obj) { DeviceState *dev = DEVICE(obj); - BusState *bus; - DeviceClass *dc = DEVICE_GET_CLASS(dev); - - if (dev->realized) { - while (dev->num_child_bus) { - bus = QLIST_FIRST(&dev->child_bus); - qbus_free(bus); - } - if (qdev_get_vmsd(dev)) { - vmstate_unregister(dev, qdev_get_vmsd(dev), dev); - } - if (dc->exit) { - dc->exit(dev); - } - if (dev->opts) { - qemu_opts_del(dev->opts); - } + if (dev->opts) { + qemu_opts_del(dev->opts); } } @@ -771,8 +756,22 @@ static void device_class_base_init(ObjectClass *class, void *data) static void device_unparent(Object *obj) { DeviceState *dev = DEVICE(obj); + DeviceClass *dc = DEVICE_GET_CLASS(dev); + BusState *bus; - if (dev->parent_bus != NULL) { + while (dev->num_child_bus) { + bus = QLIST_FIRST(&dev->child_bus); + qbus_free(bus); + } + if (dev->realized) { + if (qdev_get_vmsd(dev)) { + vmstate_unregister(dev, qdev_get_vmsd(dev), dev); + } + if (dc->exit) { + dc->exit(dev); + } + } + if (dev->parent_bus) { bus_remove_child(dev->parent_bus, dev); } }