|
|
9bac43 |
From 351d24dd01468e63230c68aa27adfebbaf052f3e Mon Sep 17 00:00:00 2001
|
|
|
9bac43 |
From: Serhii Popovych <spopovyc@redhat.com>
|
|
|
9bac43 |
Date: Thu, 11 Jan 2018 10:37:46 +0100
|
|
|
9bac43 |
Subject: [PATCH 05/12] hw/ppc/spapr.c: abort unplug_request if previous unplug
|
|
|
9bac43 |
isn't done
|
|
|
9bac43 |
|
|
|
9bac43 |
RH-Author: Serhii Popovych <spopovyc@redhat.com>
|
|
|
9bac43 |
Message-id: <1515667066-41734-1-git-send-email-spopovyc@redhat.com>
|
|
|
9bac43 |
Patchwork-id: 78547
|
|
|
9bac43 |
O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] hw/ppc/spapr.c: abort unplug_request if previous unplug isn't done
|
|
|
9bac43 |
Bugzilla: 1528173
|
|
|
9bac43 |
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
|
|
|
9bac43 |
RH-Acked-by: David Gibson <dgibson@redhat.com>
|
|
|
9bac43 |
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
|
|
9bac43 |
|
|
|
9bac43 |
From: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
|
|
|
9bac43 |
|
|
|
9bac43 |
LMB removal is completed only when the spapr_lmb_release callback
|
|
|
9bac43 |
is called after all DRCs of the dimm are detached. During this
|
|
|
9bac43 |
time, it is possible that a unplug request for the same dimm
|
|
|
9bac43 |
arrives, trying to detach DRCs that were detached by the guest
|
|
|
9bac43 |
in the first unplug_request.
|
|
|
9bac43 |
|
|
|
9bac43 |
BQL doesn't help in this case - the lock will prevent any concurrent
|
|
|
9bac43 |
removal from happening until the end of spapr_memory_unplug_request
|
|
|
9bac43 |
only. What happens is that the second unplug_request ends up calling
|
|
|
9bac43 |
spapr_drc_detach in a DRC that were detached already, causing an
|
|
|
9bac43 |
assert error in spapr_drc_detach (e.g
|
|
|
9bac43 |
https://bugs.launchpad.net/qemu/+bug/1718118).
|
|
|
9bac43 |
|
|
|
9bac43 |
spapr_lmb_release uses a structure called sPAPRDIMMState, stored in the
|
|
|
9bac43 |
spapr->pending_dimm_unplugs QTAIL, to track how many LMB DRCs are left
|
|
|
9bac43 |
to be detached by the guest. When there are no more DRCs left, this
|
|
|
9bac43 |
structure is deleted and the pc-dimm unplug handler is called to
|
|
|
9bac43 |
finish the process.
|
|
|
9bac43 |
|
|
|
9bac43 |
This patch reuses the sPAPRDIMMState to allow unplug_request to know
|
|
|
9bac43 |
if there is an ongoing unplug process for a given dimm, aborting the
|
|
|
9bac43 |
unplug request in this case, by doing the following changes:
|
|
|
9bac43 |
|
|
|
9bac43 |
- in spapr_lmb_release callback, move the dimm state removal to the
|
|
|
9bac43 |
end, after pc-dimm unplug handler. With this change we can check for
|
|
|
9bac43 |
the existence of the dimm state to see if the unplug process is
|
|
|
9bac43 |
done.
|
|
|
9bac43 |
|
|
|
9bac43 |
- use spapr_pending_dimm_unplugs_find in spapr_memory_unplug_request
|
|
|
9bac43 |
to check if the dimm state exists. If positive, there is an unplug
|
|
|
9bac43 |
operation already in progress for this dimm, meaning that we should
|
|
|
9bac43 |
abort it and warn the user about it.
|
|
|
9bac43 |
|
|
|
9bac43 |
Fixes: https://bugs.launchpad.net/qemu/+bug/1718118
|
|
|
9bac43 |
Signed-off-by: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
|
|
|
9bac43 |
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
|
|
|
9bac43 |
(cherry picked from commit 2a129767ebb13ffc29dad6a8e8e6eec06dc38b25)
|
|
|
9bac43 |
Signed-off-by: Serhii Popovych <spopovyc@redhat.com>
|
|
|
9bac43 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9bac43 |
---
|
|
|
9bac43 |
hw/ppc/spapr.c | 16 ++++++++++++++--
|
|
|
9bac43 |
1 file changed, 14 insertions(+), 2 deletions(-)
|
|
|
9bac43 |
|
|
|
9bac43 |
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
|
|
|
9bac43 |
index d7fac62..e276632 100644
|
|
|
9bac43 |
--- a/hw/ppc/spapr.c
|
|
|
9bac43 |
+++ b/hw/ppc/spapr.c
|
|
|
9bac43 |
@@ -3070,14 +3070,13 @@ void spapr_lmb_release(DeviceState *dev)
|
|
|
9bac43 |
return;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
- spapr_pending_dimm_unplugs_remove(spapr, ds);
|
|
|
9bac43 |
-
|
|
|
9bac43 |
/*
|
|
|
9bac43 |
* Now that all the LMBs have been removed by the guest, call the
|
|
|
9bac43 |
* pc-dimm unplug handler to cleanup up the pc-dimm device.
|
|
|
9bac43 |
*/
|
|
|
9bac43 |
pc_dimm_memory_unplug(dev, &spapr->hotplug_memory, mr);
|
|
|
9bac43 |
object_unparent(OBJECT(dev));
|
|
|
9bac43 |
+ spapr_pending_dimm_unplugs_remove(spapr, ds);
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev,
|
|
|
9bac43 |
@@ -3106,6 +3105,19 @@ static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev,
|
|
|
9bac43 |
goto out;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
+ /*
|
|
|
9bac43 |
+ * An existing pending dimm state for this DIMM means that there is an
|
|
|
9bac43 |
+ * unplug operation in progress, waiting for the spapr_lmb_release
|
|
|
9bac43 |
+ * callback to complete the job (BQL can't cover that far). In this case,
|
|
|
9bac43 |
+ * bail out to avoid detaching DRCs that were already released.
|
|
|
9bac43 |
+ */
|
|
|
9bac43 |
+ if (spapr_pending_dimm_unplugs_find(spapr, dimm)) {
|
|
|
9bac43 |
+ error_setg(&local_err,
|
|
|
9bac43 |
+ "Memory unplug already in progress for device %s",
|
|
|
9bac43 |
+ dev->id);
|
|
|
9bac43 |
+ goto out;
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+
|
|
|
9bac43 |
spapr_pending_dimm_unplugs_add(spapr, nr_lmbs, dimm);
|
|
|
9bac43 |
|
|
|
9bac43 |
addr = addr_start;
|
|
|
9bac43 |
--
|
|
|
9bac43 |
1.8.3.1
|
|
|
9bac43 |
|