From patchwork Fri Jan 25 13:12:34 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 215736 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 2B38F2C008F for ; Sat, 26 Jan 2013 01:05:51 +1100 (EST) Received: from localhost ([::1]:41908 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tyj6S-0008UB-BU for incoming@patchwork.ozlabs.org; Fri, 25 Jan 2013 08:13:56 -0500 Received: from eggs.gnu.org ([208.118.235.92]:49148) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tyj5e-0007Dr-Dr for qemu-devel@nongnu.org; Fri, 25 Jan 2013 08:13:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Tyj5b-0002B2-7g for qemu-devel@nongnu.org; Fri, 25 Jan 2013 08:13:06 -0500 Received: from mail-qa0-f44.google.com ([209.85.216.44]:61827) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tyj5b-0002Ar-2t for qemu-devel@nongnu.org; Fri, 25 Jan 2013 08:13:03 -0500 Received: by mail-qa0-f44.google.com with SMTP id o13so1076868qaj.17 for ; Fri, 25 Jan 2013 05:13:02 -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=uUX8jOpQ+ExUoYUL1lUuEK02ekTVAD1lrI0y6i/8CRw=; b=GCWMwIhnkurRer9X43CuUxPrxL2jf/W2uvWgrCkM3UVM+06tVR5Sq/BV+asFRMMkHI O6QJBpChKiusBIuFVP1bv4TriMb5ICvxbe5IobYqDLTMViYcpZi3XfvSWSdkmNQokaWt jw2hZ07dOe0E1t5bDt6D43zU/tdIHIDgPLJwXwRNEzNe1/z7Jx2X6MMLygzPtM/JhwR7 vTRHMkb4YK3bcEybT3pArJi7b1JdqbRreNT0Ns4CKAYojLulmQZHG5sB/uSzeD/En5xw 24YZaLXwCapbzQZ2Rq08BwnFBunvt+yD2W5/LectZmWMb1BZAfFxo8PNiO5lcKsi4yBr d6Kw== X-Received: by 10.49.28.73 with SMTP id z9mr4340865qeg.45.1359119582761; Fri, 25 Jan 2013 05:13:02 -0800 (PST) Received: from yakj.usersys.redhat.com (93-34-179-137.ip50.fastwebnet.it. [93.34.179.137]) by mx.google.com with ESMTPS id u8sm416277qeu.2.2013.01.25.05.13.00 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 25 Jan 2013 05:13:02 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Fri, 25 Jan 2013 14:12:34 +0100 Message-Id: <1359119559-19075-9-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.1 In-Reply-To: <1359119559-19075-1-git-send-email-pbonzini@redhat.com> References: <1359119559-19075-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.216.44 Cc: afaerber@suse.de Subject: [Qemu-devel] [PATCH v4 08/13] 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 3c1ec7d..6f1b311 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); } }