diff mbox

[23/23] not-for-upstream: fix device_del

Message ID 1327957741-5842-23-git-send-email-aliguori@us.ibm.com
State New
Headers show

Commit Message

Anthony Liguori Jan. 30, 2012, 9:09 p.m. UTC
This needs to be carefully merged back but I'm not 100% confident the problem is
solved by this commit.
---
 hw/pci.c              |    1 +
 hw/qdev.c             |    1 +
 include/qemu/object.h |    4 +++-
 qom/object.c          |   13 ++++++++++---
 4 files changed, 15 insertions(+), 4 deletions(-)
diff mbox

Patch

diff --git a/hw/pci.c b/hw/pci.c
index 1df05ae..5f4f80e 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -1517,6 +1517,7 @@  static int pci_unplug_device(DeviceState *qdev)
         qerror_report(QERR_DEVICE_NO_HOTPLUG, object_get_typename(OBJECT(dev)));
         return -1;
     }
+    object_unparent(OBJECT(dev));
     return dev->bus->hotplug(dev->bus->hotplug_qdev, dev,
                              PCI_HOTPLUG_DISABLED);
 }
diff --git a/hw/qdev.c b/hw/qdev.c
index f04f0fa..e3b53b7 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -222,6 +222,7 @@  void qbus_reset_all_fn(void *opaque)
 int qdev_simple_unplug_cb(DeviceState *dev)
 {
     /* just zap it */
+    object_unparent(OBJECT(dev));
     qdev_free(dev);
     return 0;
 }
diff --git a/include/qemu/object.h b/include/qemu/object.h
index b77584c..947cf29 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -524,7 +524,9 @@  void object_property_add(Object *obj, const char *name, const char *type,
                          ObjectPropertyRelease *release,
                          void *opaque, struct Error **errp);
 
-void object_property_del(Object *obj, const char *name, Error **errp);
+void object_property_del(Object *obj, const char *name, struct Error **errp);
+
+void object_unparent(Object *obj);
 
 /**
  * object_property_get:
diff --git a/qom/object.c b/qom/object.c
index 3c3c8f9..cd517f6 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -304,6 +304,13 @@  static void object_property_del_child(Object *obj, Object *child, Error **errp)
     }
 }
 
+void object_unparent(Object *obj)
+{
+    if (obj->parent) {
+        object_property_del_child(obj->parent, obj, NULL);
+    }
+}
+
 static void object_deinit(Object *obj, TypeImpl *type)
 {
     if (type->instance_finalize) {
@@ -319,9 +326,8 @@  static void object_deinit(Object *obj, TypeImpl *type)
     if (type_has_parent(type)) {
         object_deinit(obj, type_get_parent(type));
     }
-    if (obj->parent) {
-        object_property_del_child(obj->parent, obj, NULL);
-    }
+
+    object_unparent(obj);
 }
 
 void object_finalize(void *data)
@@ -557,6 +563,7 @@  void object_unref(Object *obj)
     g_assert(obj->ref > 0);
     obj->ref--;
 
+    /* parent always holds a reference to its children */
     if (obj->ref == 0) {
         object_finalize(obj);
     }