[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [qemu-xen stable-4.10] spapr: reset DRCs after devices



commit a77c5873fe27c3ca4a4120cb9547b6a264c9b5da
Author:     Greg Kurz <groug@xxxxxxxx>
AuthorDate: Fri Nov 17 13:56:48 2017 +0100
Commit:     Michael Roth <mdroth@xxxxxxxxxxxxxxxxxx>
CommitDate: Wed Dec 6 11:00:58 2017 -0600

    spapr: reset DRCs after devices
    
    A DRC with a pending unplug request releases its associated device at
    machine reset time.
    
    In the case of LMB, when all DRCs for a DIMM device have been reset,
    the DIMM gets unplugged, causing guest memory to disappear. This may
    be very confusing for anything still using this memory.
    
    This is exactly what happens with vhost backends, and QEMU aborts
    with:
    
    qemu-system-ppc64: used ring relocated for ring 2
    qemu-system-ppc64: qemu/hw/virtio/vhost.c:649: vhost_commit: Assertion
     `r >= 0' failed.
    
    The issue is that each DRC registers a QEMU reset handler, and we
    don't control the order in which these handlers are called (ie,
    a LMB DRC will unplug a DIMM before the virtio device using the
    memory on this DIMM could stop its vhost backend).
    
    To avoid such situations, let's reset DRCs after all devices
    have been reset.
    
    Reported-by: Mallesh N. Koti <mallesh@xxxxxxxxxxxxxxxxxx>
    Signed-off-by: Greg Kurz <groug@xxxxxxxx>
    Reviewed-by: Daniel Henrique Barboza <danielhb@xxxxxxxxxxxxxxxxxx>
    Reviewed-by: Michael Roth <mdroth@xxxxxxxxxxxxxxxxxx>
    Signed-off-by: David Gibson <david@xxxxxxxxxxxxxxxxxxxxx>
    (cherry picked from commit 82512483940c756e2db1bd67ea91b02bc29c5e01)
    Signed-off-by: Michael Roth <mdroth@xxxxxxxxxxxxxxxxxx>
---
 hw/ppc/spapr.c     | 21 +++++++++++++++++++++
 hw/ppc/spapr_drc.c |  7 -------
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 954fd1a..8630281 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1393,6 +1393,19 @@ static void find_unknown_sysbus_device(SysBusDevice 
*sbdev, void *opaque)
     }
 }
 
+static int spapr_reset_drcs(Object *child, void *opaque)
+{
+    sPAPRDRConnector *drc =
+        (sPAPRDRConnector *) object_dynamic_cast(child,
+                                                 TYPE_SPAPR_DR_CONNECTOR);
+
+    if (drc) {
+        spapr_drc_reset(drc);
+    }
+
+    return 0;
+}
+
 static void ppc_spapr_reset(void)
 {
     MachineState *machine = MACHINE(qdev_get_machine());
@@ -1416,6 +1429,14 @@ static void ppc_spapr_reset(void)
     }
 
     qemu_devices_reset();
+
+    /* DRC reset may cause a device to be unplugged. This will cause troubles
+     * if this device is used by another device (eg, a running vhost backend
+     * will crash QEMU if the DIMM holding the vring goes away). To avoid such
+     * situations, we reset DRCs after all devices have been reset.
+     */
+    object_child_foreach_recursive(object_get_root(), spapr_reset_drcs, NULL);
+
     spapr_clear_pending_events(spapr);
 
     /*
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 50df361..85f4e7d 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -455,11 +455,6 @@ void spapr_drc_reset(sPAPRDRConnector *drc)
     }
 }
 
-static void drc_reset(void *opaque)
-{
-    spapr_drc_reset(SPAPR_DR_CONNECTOR(opaque));
-}
-
 bool spapr_drc_needed(void *opaque)
 {
     sPAPRDRConnector *drc = (sPAPRDRConnector *)opaque;
@@ -518,7 +513,6 @@ static void realize(DeviceState *d, Error **errp)
     }
     vmstate_register(DEVICE(drc), spapr_drc_index(drc), &vmstate_spapr_drc,
                      drc);
-    qemu_register_reset(drc_reset, drc);
     trace_spapr_drc_realize_complete(spapr_drc_index(drc));
 }
 
@@ -529,7 +523,6 @@ static void unrealize(DeviceState *d, Error **errp)
     char name[256];
 
     trace_spapr_drc_unrealize(spapr_drc_index(drc));
-    qemu_unregister_reset(drc_reset, drc);
     vmstate_unregister(DEVICE(drc), &vmstate_spapr_drc, drc);
     root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
     snprintf(name, sizeof(name), "%x", spapr_drc_index(drc));
--
generated by git-patchbot for /home/xen/git/qemu-xen.git#stable-4.10

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.