From: Greg Kurz <groug@kaod.org>
To: qemu-devel@nongnu.org
Cc: Daniel Henrique Barboza <danielhb@linux.ibm.com>,
qemu-ppc@nongnu.org, Greg Kurz <groug@kaod.org>,
David Gibson <david@gibson.dropbear.id.au>
Subject: [PATCH 2/6] spapr: Fix reset of transient DR connectors
Date: Fri, 18 Dec 2020 11:33:56 +0100 [thread overview]
Message-ID: <20201218103400.689660-3-groug@kaod.org> (raw)
In-Reply-To: <20201218103400.689660-1-groug@kaod.org>
Documentation of object_property_iter_init() clearly stipulates that
"it is forbidden to modify the property list while iterating". But this
is exactly what we do when resetting transient DR connectors during CAS.
The call to spapr_drc_reset() can finalize the hot-unplug sequence of a
PHB or a PCI bridge, both of which will then in turn destroy their PCI
DRCs. This could potentially invalidate the iterator. It is pure luck
that this haven't caused any issues so far.
Change spapr_drc_reset() to return true if it caused a device to be
removed. Restart from scratch in this case. This can potentially
increase the overall DRC reset time, especially with a high maxmem
which generates a lot of LMB DRCs. But this kind of setup is rare,
and so is the use case of rebooting a guest while doing hot-unplug.
Signed-off-by: Greg Kurz <groug@kaod.org>
---
include/hw/ppc/spapr_drc.h | 3 ++-
hw/ppc/spapr_drc.c | 6 +++++-
hw/ppc/spapr_hcall.c | 8 +++++++-
3 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h
index cff5e707d0d9..5d80019f82e2 100644
--- a/include/hw/ppc/spapr_drc.h
+++ b/include/hw/ppc/spapr_drc.h
@@ -224,7 +224,8 @@ static inline bool spapr_drc_hotplugged(DeviceState *dev)
return dev->hotplugged && !runstate_check(RUN_STATE_INMIGRATE);
}
-void spapr_drc_reset(SpaprDrc *drc);
+/* Returns true if an unplug request completed */
+bool spapr_drc_reset(SpaprDrc *drc);
uint32_t spapr_drc_index(SpaprDrc *drc);
SpaprDrcType spapr_drc_type(SpaprDrc *drc);
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 8d62f55066b6..5b5e2ac58a7e 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -417,9 +417,10 @@ void spapr_drc_detach(SpaprDrc *drc)
spapr_drc_release(drc);
}
-void spapr_drc_reset(SpaprDrc *drc)
+bool spapr_drc_reset(SpaprDrc *drc)
{
SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+ bool unplug_completed = false;
trace_spapr_drc_reset(spapr_drc_index(drc));
@@ -428,6 +429,7 @@ void spapr_drc_reset(SpaprDrc *drc)
*/
if (drc->unplug_requested) {
spapr_drc_release(drc);
+ unplug_completed = true;
}
if (drc->dev) {
@@ -444,6 +446,8 @@ void spapr_drc_reset(SpaprDrc *drc)
drc->ccs_offset = -1;
drc->ccs_depth = -1;
}
+
+ return unplug_completed;
}
static bool spapr_drc_unplug_requested_needed(void *opaque)
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 4e9d50c254f0..aa22830ac4bd 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1639,6 +1639,7 @@ static void spapr_handle_transient_dev_before_cas(SpaprMachineState *spapr)
ObjectPropertyIterator iter;
drc_container = container_get(object_get_root(), "/dr-connector");
+restart:
object_property_iter_init(&iter, drc_container);
while ((prop = object_property_iter_next(&iter))) {
SpaprDrc *drc;
@@ -1652,8 +1653,13 @@ static void spapr_handle_transient_dev_before_cas(SpaprMachineState *spapr)
/*
* This will complete any pending plug/unplug requests.
+ * In case of a unplugged PHB or PCI bridge, this will
+ * cause some DRCs to be destroyed and thus potentially
+ * invalidate the iterator.
*/
- spapr_drc_reset(drc);
+ if (spapr_drc_reset(drc)) {
+ goto restart;
+ }
}
spapr_clear_pending_hotplug_events(spapr);
--
2.26.2
next prev parent reply other threads:[~2020-12-18 10:36 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-18 10:33 [PATCH 0/6] spapr: Fix visibility and traversal of DR connectors Greg Kurz
2020-12-18 10:33 ` [PATCH 1/6] spapr: Call spapr_drc_reset() for all DRCs at CAS Greg Kurz
2020-12-21 18:24 ` Daniel Henrique Barboza
2020-12-28 7:20 ` David Gibson
2020-12-18 10:33 ` Greg Kurz [this message]
2020-12-21 20:34 ` [PATCH 2/6] spapr: Fix reset of transient DR connectors Daniel Henrique Barboza
2020-12-28 7:24 ` David Gibson
2020-12-18 10:33 ` [PATCH 3/6] spapr: Introduce spapr_drc_reset_all() Greg Kurz
2020-12-21 20:35 ` Daniel Henrique Barboza
2020-12-28 7:26 ` David Gibson
2020-12-18 10:33 ` [PATCH 4/6] spapr: Use spapr_drc_reset_all() at machine reset Greg Kurz
2020-12-21 20:36 ` Daniel Henrique Barboza
2020-12-28 7:29 ` David Gibson
2020-12-18 10:33 ` [PATCH 5/6] spapr: Add drc_ prefix to the DRC realize and unrealize functions Greg Kurz
2020-12-21 20:37 ` Daniel Henrique Barboza
2020-12-28 7:31 ` David Gibson
2020-12-18 10:34 ` [PATCH 6/6] spapr: Model DR connectors as simple objects Greg Kurz
2020-12-21 20:45 ` Daniel Henrique Barboza
2020-12-28 8:28 ` David Gibson
2021-01-06 18:15 ` Greg Kurz
2021-02-08 6:30 ` David Gibson
2020-12-22 10:14 ` [PATCH 0/6] spapr: Fix visibility and traversal of DR connectors Daniel Henrique Barboza
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201218103400.689660-3-groug@kaod.org \
--to=groug@kaod.org \
--cc=danielhb@linux.ibm.com \
--cc=david@gibson.dropbear.id.au \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).