[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 26/29] qdev: store DeviceState's canonical path to us
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PULL 26/29] qdev: store DeviceState's canonical path to use when unparenting |
Date: |
Wed, 18 Oct 2017 18:12:18 +0200 |
From: Michael Roth <address@hidden>
device_unparent(dev, ...) is called when a device is unparented,
either directly, or as a result of a parent device being
finalized, and handles some final cleanup for the device. Part
of this includes emiting a DEVICE_DELETED QMP event to notify
management, which includes the device's path in the composition
tree as provided by object_get_canonical_path().
object_get_canonical_path() assumes the device is still connected
to the machine/root container, and will assert otherwise, but
in some situations this isn't the case:
If the parent is finalized as a result of object_unparent(), it
will still be attached to the composition tree at the time any
children are unparented as a result of that same call to
object_unparent(). However, in some cases, object_unparent()
will complete without finalizing the parent device, due to
lingering references that won't be released till some time later.
One such example is if the parent has MemoryRegion children (which
take a ref on their parent), who in turn have AddressSpace's (which
take a ref on their regions), since those AddressSpaces get cleaned
up asynchronously by the RCU thread.
In this case qdev:device_unparent() may be called for a child Device
that no longer has a path to the root/machine container, causing
object_get_canonical_path() to assert.
Fix this by storing the canonical path during realize() so the
information will still be available for device_unparent() in such
cases.
Cc: Michael S. Tsirkin <address@hidden>
Cc: Paolo Bonzini <address@hidden>
Signed-off-by: Michael Roth <address@hidden>
Signed-off-by: Greg Kurz <address@hidden>
Signed-off-by: Michael Roth <address@hidden>
Tested-by: Eric Auger <address@hidden>
Reviewed-by: David Gibson <address@hidden>
Message-Id: <address@hidden>
[Clear dev->canonical_path at the post_realize_fail label, which is
cleaner. Suggested by David Gibson. - Paolo]
Signed-off-by: Paolo Bonzini <address@hidden>
---
hw/core/qdev.c | 17 ++++++++++++++---
include/hw/qdev-core.h | 1 +
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 606ab53..0019a49 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -928,6 +928,13 @@ static void device_set_realized(Object *obj, bool value,
Error **errp)
goto post_realize_fail;
}
+ /*
+ * always free/re-initialize here since the value cannot be cleaned up
+ * in device_unrealize due to its usage later on in the unplug path
+ */
+ g_free(dev->canonical_path);
+ dev->canonical_path = object_get_canonical_path(OBJECT(dev));
+
if (qdev_get_vmsd(dev)) {
if (vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev),
dev,
dev->instance_id_alias,
@@ -984,6 +991,8 @@ child_realize_fail:
}
post_realize_fail:
+ g_free(dev->canonical_path);
+ dev->canonical_path = NULL;
if (dc->unrealize) {
dc->unrealize(dev, NULL);
}
@@ -1102,10 +1111,12 @@ static void device_unparent(Object *obj)
/* Only send event if the device had been completely realized */
if (dev->pending_deleted_event) {
- gchar *path = object_get_canonical_path(OBJECT(dev));
+ g_assert(dev->canonical_path);
- qapi_event_send_device_deleted(!!dev->id, dev->id, path, &error_abort);
- g_free(path);
+ qapi_event_send_device_deleted(!!dev->id, dev->id, dev->canonical_path,
+ &error_abort);
+ g_free(dev->canonical_path);
+ dev->canonical_path = NULL;
}
qemu_opts_del(dev->opts);
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 0891461..0a71bf8 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -153,6 +153,7 @@ struct DeviceState {
/*< public >*/
const char *id;
+ char *canonical_path;
bool realized;
bool pending_deleted_event;
QemuOpts *opts;
--
1.8.3.1
- [Qemu-devel] [PULL 19/29] kvm: fix error message when failing to unregister slot, (continued)
- [Qemu-devel] [PULL 19/29] kvm: fix error message when failing to unregister slot, Paolo Bonzini, 2017/10/18
- [Qemu-devel] [PULL 16/29] memory: call log_start after region_add, Paolo Bonzini, 2017/10/18
- [Qemu-devel] [PULL 18/29] kvm: tolerate non-existing slot for log_start/log_stop/log_sync, Paolo Bonzini, 2017/10/18
- [Qemu-devel] [PULL 22/29] memory: reuse section_from_flat_range(), Paolo Bonzini, 2017/10/18
- [Qemu-devel] [PULL 21/29] kvm: simplify kvm_align_section(), Paolo Bonzini, 2017/10/18
- [Qemu-devel] [PULL 20/29] kvm: region_add and region_del is not called on updates, Paolo Bonzini, 2017/10/18
- [Qemu-devel] [PULL 24/29] watch_mem_write: implement 8-byte accesses, Paolo Bonzini, 2017/10/18
- [Qemu-devel] [PULL 25/29] qemu-pr-helper: use new libmultipath API, Paolo Bonzini, 2017/10/18
- [Qemu-devel] [PULL 27/29] Revert "qdev: Free QemuOpts when the QOM path goes away", Paolo Bonzini, 2017/10/18
- [Qemu-devel] [PULL 29/29] scsi: reject configurations with logical block size > physical block size, Paolo Bonzini, 2017/10/18
- [Qemu-devel] [PULL 26/29] qdev: store DeviceState's canonical path to use when unparenting,
Paolo Bonzini <=
- [Qemu-devel] [PULL 23/29] notdirty_mem_write: implement 8-byte accesses, Paolo Bonzini, 2017/10/18
- [Qemu-devel] [PULL 28/29] qdev: defer DEVICE_DEL event until instance_finalize(), Paolo Bonzini, 2017/10/18
- Re: [Qemu-devel] [PULL 00/29] Misc patches for 2017-10-18, no-reply, 2017/10/18
- Re: [Qemu-devel] [PULL 00/29] Misc patches for 2017-10-18, Peter Maydell, 2017/10/19