Blame SOURCES/kvm-qdev-defer-DEVICE_DEL-event-until-instance_finalize.patch

4a2fec
From 13bceabad00d232b71f34bc62b6bbda3f7279601 Mon Sep 17 00:00:00 2001
4a2fec
From: Serhii Popovych <spopovyc@redhat.com>
4a2fec
Date: Thu, 9 Nov 2017 15:30:05 +0100
4a2fec
Subject: [PATCH 5/7] qdev: defer DEVICE_DEL event until instance_finalize()
4a2fec
4a2fec
RH-Author: Serhii Popovych <spopovyc@redhat.com>
4a2fec
Message-id: <1510241405-20597-4-git-send-email-spopovyc@redhat.com>
4a2fec
Patchwork-id: 77631
4a2fec
O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 3/3] qdev: defer DEVICE_DEL event until instance_finalize()
4a2fec
Bugzilla: 1445460
4a2fec
RH-Acked-by: David Gibson <dgibson@redhat.com>
4a2fec
RH-Acked-by: Thomas Huth <thuth@redhat.com>
4a2fec
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
4a2fec
4a2fec
From: Michael Roth <mdroth@linux.vnet.ibm.com>
4a2fec
4a2fec
DEVICE_DEL is currently emitted when a Device is unparented, as
4a2fec
opposed to when it is finalized. The main design motivation for this
4a2fec
seems to be that after unparent()/unrealize(), the Device is no
4a2fec
longer visible to the guest, and thus the operation is complete
4a2fec
from the perspective of management.
4a2fec
4a2fec
However, there are cases where remaining host-side cleanup is also
4a2fec
pertinent to management. The is generally handled by treating these
4a2fec
resources as aspects of the "backend", which can be managed via
4a2fec
separate interfaces/events, such as blockdev_add/del, netdev_add/del,
4a2fec
object_add/del, etc, but some devices do not have this level of
4a2fec
compartmentalization, namely vfio-pci, and possibly to lend themselves
4a2fec
well to it.
4a2fec
4a2fec
In the case of vfio-pci, the "backend" cleanup happens as part of
4a2fec
the finalization of the vfio-pci device itself, in particular the
4a2fec
cleanup of the VFIO group FD. Failing to wait for this cleanup can
4a2fec
result in tools like libvirt attempting to rebind the device to
4a2fec
the host while it's still being used by VFIO, which can result in
4a2fec
host crashes or other misbehavior depending on the host driver.
4a2fec
4a2fec
Deferring DEVICE_DEL still affords us the ability to manage backends
4a2fec
explicitly, while also addressing cases like vfio-pci's, so we
4a2fec
implement that approach here.
4a2fec
4a2fec
An alternative proposal involving having VFIO emit a separate event
4a2fec
to denote completion of host-side cleanup was discussed, but the
4a2fec
prevailing opinion seems to be that it is not worth the added
4a2fec
complexity, and leaves the issue open for other Device implementations
4a2fec
to solve in the future.
4a2fec
4a2fec
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
4a2fec
Reviewed-by: Greg Kurz <groug@kaod.org>
4a2fec
Tested-by: Eric Auger <eric.auger@redhat.com>
4a2fec
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
4a2fec
Message-Id: <20171016222315.407-4-mdroth@linux.vnet.ibm.com>
4a2fec
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
4a2fec
(cherry picked from commit f7b879e072ae6839b1b1d1312f48fa7f256397e2)
4a2fec
Signed-off-by: Serhii Popovych <spopovyc@redhat.com>
4a2fec
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
4a2fec
---
4a2fec
 hw/core/qdev.c | 23 ++++++++++++-----------
4a2fec
 1 file changed, 12 insertions(+), 11 deletions(-)
4a2fec
4a2fec
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
4a2fec
index 418cdac..1111295 100644
4a2fec
--- a/hw/core/qdev.c
4a2fec
+++ b/hw/core/qdev.c
4a2fec
@@ -1069,7 +1069,6 @@ static void device_finalize(Object *obj)
4a2fec
     NamedGPIOList *ngl, *next;
4a2fec
 
4a2fec
     DeviceState *dev = DEVICE(obj);
4a2fec
-    qemu_opts_del(dev->opts);
4a2fec
 
4a2fec
     QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
4a2fec
         QLIST_REMOVE(ngl, node);
4a2fec
@@ -1080,6 +1079,18 @@ static void device_finalize(Object *obj)
4a2fec
          * here
4a2fec
          */
4a2fec
     }
4a2fec
+
4a2fec
+    /* Only send event if the device had been completely realized */
4a2fec
+    if (dev->pending_deleted_event) {
4a2fec
+        g_assert(dev->canonical_path);
4a2fec
+
4a2fec
+        qapi_event_send_device_deleted(!!dev->id, dev->id, dev->canonical_path,
4a2fec
+                                       &error_abort);
4a2fec
+        g_free(dev->canonical_path);
4a2fec
+        dev->canonical_path = NULL;
4a2fec
+    }
4a2fec
+
4a2fec
+    qemu_opts_del(dev->opts);
4a2fec
 }
4a2fec
 
4a2fec
 static void device_class_base_init(ObjectClass *class, void *data)
4a2fec
@@ -1109,16 +1120,6 @@ static void device_unparent(Object *obj)
4a2fec
         object_unref(OBJECT(dev->parent_bus));
4a2fec
         dev->parent_bus = NULL;
4a2fec
     }
4a2fec
-
4a2fec
-    /* Only send event if the device had been completely realized */
4a2fec
-    if (dev->pending_deleted_event) {
4a2fec
-        g_assert(dev->canonical_path);
4a2fec
-
4a2fec
-        qapi_event_send_device_deleted(!!dev->id, dev->id, dev->canonical_path,
4a2fec
-                                       &error_abort);
4a2fec
-        g_free(dev->canonical_path);
4a2fec
-        dev->canonical_path = NULL;
4a2fec
-    }
4a2fec
 }
4a2fec
 
4a2fec
 static void device_class_init(ObjectClass *class, void *data)
4a2fec
-- 
4a2fec
1.8.3.1
4a2fec