From patchwork Wed Dec 5 20:44:37 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 203965 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 D51F72C0377 for ; Thu, 6 Dec 2012 08:31:31 +1100 (EST) Received: from localhost ([::1]:51082 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TgLr9-0002U6-Fa for incoming@patchwork.ozlabs.org; Wed, 05 Dec 2012 15:46:11 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52540) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TgLq2-0000Ai-HH for qemu-devel@nongnu.org; Wed, 05 Dec 2012 15:45:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TgLq0-0001DM-Ms for qemu-devel@nongnu.org; Wed, 05 Dec 2012 15:45:02 -0500 Received: from mail-ea0-f173.google.com ([209.85.215.173]:49597) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TgLq0-0001D6-FM for qemu-devel@nongnu.org; Wed, 05 Dec 2012 15:45:00 -0500 Received: by mail-ea0-f173.google.com with SMTP id i13so2322945eaa.4 for ; Wed, 05 Dec 2012 12:44:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=Ll/aSeHetzkcFr8nneKQyLEbrPWkV7CfSgMZjHDNbFE=; b=FYd6zDWaE86oorieG+Dka1VTVMvT8F0FHo83m74jytTpcOAj2behGBIS8oyn3yRx1+ kJWndLmRilipukkrQsFnZCjDVzuGUCQif7ueAzhV3M7XfS98P+B37LIva+85k2juFG4H y2fy0Jv1sQlOHk1CxlblC3vmS6lHdbwVpiFN3TvW743PHvFE6CUo9P7DXRyfAnaoBTyO rDL3hv1XDa2TJSQWj4H4F+sxXKxk0avZfRFKKosB0cIMA9BLHOOsJpmy0qqex1gUAzL0 Je5PipoK03yoh0UO9YWOYJiU7ytXJS5Nk1ubBsm9p5HAJvfkOSMlbFWxYei9yAm0HFOo JPNQ== Received: by 10.14.223.135 with SMTP id v7mr64708625eep.41.1354740299577; Wed, 05 Dec 2012 12:44:59 -0800 (PST) Received: from yakj.usersys.redhat.com (93-34-219-150.ip51.fastwebnet.it. [93.34.219.150]) by mx.google.com with ESMTPS id a44sm11396163eeo.7.2012.12.05.12.44.58 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 05 Dec 2012 12:44:58 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Wed, 5 Dec 2012 21:44:37 +0100 Message-Id: <1354740282-20679-7-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.0.1 In-Reply-To: <1354740282-20679-1-git-send-email-pbonzini@redhat.com> References: <1354740282-20679-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 209.85.215.173 Cc: aliguori@us.ibm.com, afaerber@suse.de Subject: [Qemu-devel] [PATCH 06/11] 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 | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/hw/qdev.c b/hw/qdev.c index 12b1529..d7f1545 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -699,23 +699,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->state == DEV_STATE_INITIALIZED) { - 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); } } @@ -732,8 +717,24 @@ static void device_class_base_init(ObjectClass *class, void *data) static void qdev_remove_from_bus(Object *obj) { DeviceState *dev = DEVICE(obj); + DeviceClass *dc = DEVICE_GET_CLASS(dev); + BusState *bus; - bus_remove_child(dev->parent_bus, dev); + while (dev->num_child_bus) { + bus = QLIST_FIRST(&dev->child_bus); + qbus_free(bus); + } + if (dev->state == DEV_STATE_INITIALIZED) { + 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); + } } static void device_class_init(ObjectClass *class, void *data)