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

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