summaryrefslogtreecommitdiff
path: root/hw/ppc/spapr_drc.c
diff options
context:
space:
mode:
authorLaurent Vivier <lvivier@redhat.com>2017-06-09 13:08:10 +0200
committerDavid Gibson <david@gibson.dropbear.id.au>2017-07-17 15:07:05 +1000
commit94fd9cbaa319049d43107fc2128fae803f8a6989 (patch)
tree1aa216a5ac1cb5f949bc6f65a4974d98460a74a0 /hw/ppc/spapr_drc.c
parent5341258e863e8e8503ca0e01306cfb0d8f4b8e63 (diff)
downloadqemu-94fd9cbaa319049d43107fc2128fae803f8a6989.zip
spapr: Treat devices added before inbound migration as coldplugged
When migrating a guest which has already had devices hotplugged, libvirt typically starts the destination qemu with -incoming defer, adds those hotplugged devices with qmp, then initiates the incoming migration. This causes problems for the management of spapr DRC state. Because the device is treated as hotplugged, it goes into a DRC state for a device immediately after it's plugged, but before the guest has acknowledged its presence. However, chances are the guest on the source machine *has* acknowledged the device's presence and configured it. If the source has fully configured the device, then DRC state won't be sent in the migration stream: for maximum migration compatibility with earlier versions we don't migrate DRCs in coldplug-equivalent state. That means that the DRC effectively changes state over the migrate, causing problems later on. In addition, logging hotplug events for these devices isn't what we want because a) those events should already have been issued on the source host and b) the event queue should get wiped out by the incoming state anyway. In short, what we really want is to treat devices added before an incoming migration as if they were coldplugged. To do this, we first add a spapr_drc_hotplugged() helper which determines if the device is hotplugged in the sense relevant for DRC state management. We only send hotplug events when this is true. Second, when we add a device which isn't hotplugged in this sense, we force a reset of the DRC state - this ensures the DRC is in a coldplug-equivalent state (there isn't usually a system reset between these device adds and the incoming migration). This is based on an earlier patch by Laurent Vivier, cleaned up and extended. Signed-off-by: Laurent Vivier <lvivier@redhat.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Greg Kurz <groug@kaod.org> Tested-by: Daniel Barboza <danielhb@linux.vnet.ibm.com>
Diffstat (limited to 'hw/ppc/spapr_drc.c')
-rw-r--r--hw/ppc/spapr_drc.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 7f71c77015..31181dab1d 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -412,10 +412,8 @@ static bool release_pending(sPAPRDRConnector *drc)
return drc->awaiting_release;
}
-static void drc_reset(void *opaque)
+void spapr_drc_reset(sPAPRDRConnector *drc)
{
- sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(opaque);
-
trace_spapr_drc_reset(spapr_drc_index(drc));
g_free(drc->ccs);
@@ -447,6 +445,11 @@ static void drc_reset(void *opaque)
}
}
+static void drc_reset(void *opaque)
+{
+ spapr_drc_reset(SPAPR_DR_CONNECTOR(opaque));
+}
+
static bool spapr_drc_needed(void *opaque)
{
sPAPRDRConnector *drc = (sPAPRDRConnector *)opaque;