From mboxrd@z Thu Jan 1 00:00:00 1970 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) Sender: Paolo Bonzini From: Paolo Bonzini Date: Wed, 5 Dec 2012 21:44:37 +0100 Message-Id: <1354740282-20679-7-git-send-email-pbonzini@redhat.com> In-Reply-To: <1354740282-20679-1-git-send-email-pbonzini@redhat.com> References: <1354740282-20679-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH 06/11] qdev: move unrealization of devices from finalize to unparent List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: aliguori@us.ibm.com, afaerber@suse.de 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) -- 1.8.0.1