|
|
9bac43 |
From a6dae62ef051773c0198f8ebd47a79d8f1157000 Mon Sep 17 00:00:00 2001
|
|
|
9bac43 |
From: Serhii Popovych <spopovyc@redhat.com>
|
|
|
9bac43 |
Date: Thu, 9 Nov 2017 15:30:03 +0100
|
|
|
9bac43 |
Subject: [PATCH 3/7] qdev: store DeviceState's canonical path to use when
|
|
|
9bac43 |
unparenting
|
|
|
9bac43 |
|
|
|
9bac43 |
RH-Author: Serhii Popovych <spopovyc@redhat.com>
|
|
|
9bac43 |
Message-id: <1510241405-20597-2-git-send-email-spopovyc@redhat.com>
|
|
|
9bac43 |
Patchwork-id: 77632
|
|
|
9bac43 |
O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/3] qdev: store DeviceState's canonical path to use when unparenting
|
|
|
9bac43 |
Bugzilla: 1445460
|
|
|
9bac43 |
RH-Acked-by: David Gibson <dgibson@redhat.com>
|
|
|
9bac43 |
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
|
|
9bac43 |
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
|
|
|
9bac43 |
|
|
|
9bac43 |
From: Michael Roth <mdroth@linux.vnet.ibm.com>
|
|
|
9bac43 |
|
|
|
9bac43 |
device_unparent(dev, ...) is called when a device is unparented,
|
|
|
9bac43 |
either directly, or as a result of a parent device being
|
|
|
9bac43 |
finalized, and handles some final cleanup for the device. Part
|
|
|
9bac43 |
of this includes emiting a DEVICE_DELETED QMP event to notify
|
|
|
9bac43 |
management, which includes the device's path in the composition
|
|
|
9bac43 |
tree as provided by object_get_canonical_path().
|
|
|
9bac43 |
|
|
|
9bac43 |
object_get_canonical_path() assumes the device is still connected
|
|
|
9bac43 |
to the machine/root container, and will assert otherwise, but
|
|
|
9bac43 |
in some situations this isn't the case:
|
|
|
9bac43 |
|
|
|
9bac43 |
If the parent is finalized as a result of object_unparent(), it
|
|
|
9bac43 |
will still be attached to the composition tree at the time any
|
|
|
9bac43 |
children are unparented as a result of that same call to
|
|
|
9bac43 |
object_unparent(). However, in some cases, object_unparent()
|
|
|
9bac43 |
will complete without finalizing the parent device, due to
|
|
|
9bac43 |
lingering references that won't be released till some time later.
|
|
|
9bac43 |
One such example is if the parent has MemoryRegion children (which
|
|
|
9bac43 |
take a ref on their parent), who in turn have AddressSpace's (which
|
|
|
9bac43 |
take a ref on their regions), since those AddressSpaces get cleaned
|
|
|
9bac43 |
up asynchronously by the RCU thread.
|
|
|
9bac43 |
|
|
|
9bac43 |
In this case qdev:device_unparent() may be called for a child Device
|
|
|
9bac43 |
that no longer has a path to the root/machine container, causing
|
|
|
9bac43 |
object_get_canonical_path() to assert.
|
|
|
9bac43 |
|
|
|
9bac43 |
Fix this by storing the canonical path during realize() so the
|
|
|
9bac43 |
information will still be available for device_unparent() in such
|
|
|
9bac43 |
cases.
|
|
|
9bac43 |
|
|
|
9bac43 |
Cc: Michael S. Tsirkin <mst@redhat.com>
|
|
|
9bac43 |
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
9bac43 |
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
|
|
9bac43 |
Signed-off-by: Greg Kurz <groug@kaod.org>
|
|
|
9bac43 |
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
|
|
9bac43 |
Tested-by: Eric Auger <eric.auger@redhat.com>
|
|
|
9bac43 |
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
|
|
|
9bac43 |
Message-Id: <20171016222315.407-2-mdroth@linux.vnet.ibm.com>
|
|
|
9bac43 |
[Clear dev->canonical_path at the post_realize_fail label, which is
|
|
|
9bac43 |
cleaner. Suggested by David Gibson. - Paolo]
|
|
|
9bac43 |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
9bac43 |
|
|
|
9bac43 |
(cherry picked from commit 04162f8f4bcf8c9ae2422def4357289b44208c8c)
|
|
|
9bac43 |
Signed-off-by: Serhii Popovych <spopovyc@redhat.com>
|
|
|
9bac43 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9bac43 |
---
|
|
|
9bac43 |
hw/core/qdev.c | 17 ++++++++++++++---
|
|
|
9bac43 |
include/hw/qdev-core.h | 1 +
|
|
|
9bac43 |
2 files changed, 15 insertions(+), 3 deletions(-)
|
|
|
9bac43 |
|
|
|
9bac43 |
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
|
|
|
9bac43 |
index 606ab53..0019a49 100644
|
|
|
9bac43 |
--- a/hw/core/qdev.c
|
|
|
9bac43 |
+++ b/hw/core/qdev.c
|
|
|
9bac43 |
@@ -928,6 +928,13 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
|
|
|
9bac43 |
goto post_realize_fail;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
+ /*
|
|
|
9bac43 |
+ * always free/re-initialize here since the value cannot be cleaned up
|
|
|
9bac43 |
+ * in device_unrealize due to its usage later on in the unplug path
|
|
|
9bac43 |
+ */
|
|
|
9bac43 |
+ g_free(dev->canonical_path);
|
|
|
9bac43 |
+ dev->canonical_path = object_get_canonical_path(OBJECT(dev));
|
|
|
9bac43 |
+
|
|
|
9bac43 |
if (qdev_get_vmsd(dev)) {
|
|
|
9bac43 |
if (vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
|
|
|
9bac43 |
dev->instance_id_alias,
|
|
|
9bac43 |
@@ -984,6 +991,8 @@ child_realize_fail:
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
post_realize_fail:
|
|
|
9bac43 |
+ g_free(dev->canonical_path);
|
|
|
9bac43 |
+ dev->canonical_path = NULL;
|
|
|
9bac43 |
if (dc->unrealize) {
|
|
|
9bac43 |
dc->unrealize(dev, NULL);
|
|
|
9bac43 |
}
|
|
|
9bac43 |
@@ -1102,10 +1111,12 @@ static void device_unparent(Object *obj)
|
|
|
9bac43 |
|
|
|
9bac43 |
/* Only send event if the device had been completely realized */
|
|
|
9bac43 |
if (dev->pending_deleted_event) {
|
|
|
9bac43 |
- gchar *path = object_get_canonical_path(OBJECT(dev));
|
|
|
9bac43 |
+ g_assert(dev->canonical_path);
|
|
|
9bac43 |
|
|
|
9bac43 |
- qapi_event_send_device_deleted(!!dev->id, dev->id, path, &error_abort);
|
|
|
9bac43 |
- g_free(path);
|
|
|
9bac43 |
+ qapi_event_send_device_deleted(!!dev->id, dev->id, dev->canonical_path,
|
|
|
9bac43 |
+ &error_abort);
|
|
|
9bac43 |
+ g_free(dev->canonical_path);
|
|
|
9bac43 |
+ dev->canonical_path = NULL;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
qemu_opts_del(dev->opts);
|
|
|
9bac43 |
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
|
|
|
9bac43 |
index ae31728..9237b68 100644
|
|
|
9bac43 |
--- a/include/hw/qdev-core.h
|
|
|
9bac43 |
+++ b/include/hw/qdev-core.h
|
|
|
9bac43 |
@@ -153,6 +153,7 @@ struct DeviceState {
|
|
|
9bac43 |
/*< public >*/
|
|
|
9bac43 |
|
|
|
9bac43 |
const char *id;
|
|
|
9bac43 |
+ char *canonical_path;
|
|
|
9bac43 |
bool realized;
|
|
|
9bac43 |
bool pending_deleted_event;
|
|
|
9bac43 |
QemuOpts *opts;
|
|
|
9bac43 |
--
|
|
|
9bac43 |
1.8.3.1
|
|
|
9bac43 |
|