* [Qemu-devel] [PATCH 0/2] spapr: fix migration of old guests
@ 2018-02-27 15:22 Greg Kurz
2018-02-27 15:22 ` [Qemu-devel] [PATCH 1/2] spapr: register dummy ICPs later Greg Kurz
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Greg Kurz @ 2018-02-27 15:22 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-ppc, David Gibson, Laurent Vivier, Lukas Doktor
Recent VSMT work broke migration of old guests as reported in this BZ:
https://bugzilla.redhat.com/show_bug.cgi?id=1549087
Patch 1 fixes the issue, while patch 2 is a tentative code reorg to
ensure VSMT is set before anyone tries to use spapr->vsmt.
--
Greg
---
Greg Kurz (2):
spapr: register dummy ICPs later
spapr: harden code that depends on VSMT
hw/ppc/spapr.c | 144 +++++++++++++++++++++++++++++---------------------------
1 file changed, 75 insertions(+), 69 deletions(-)
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH 1/2] spapr: register dummy ICPs later
2018-02-27 15:22 [Qemu-devel] [PATCH 0/2] spapr: fix migration of old guests Greg Kurz
@ 2018-02-27 15:22 ` Greg Kurz
2018-02-27 15:23 ` [Qemu-devel] [PATCH 2/2] spapr: harden code that depends on VSMT Greg Kurz
2018-02-28 0:42 ` [Qemu-devel] [PATCH 0/2] spapr: fix migration of old guests David Gibson
2 siblings, 0 replies; 4+ messages in thread
From: Greg Kurz @ 2018-02-27 15:22 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-ppc, David Gibson, Laurent Vivier, Lukas Doktor
Some older machine types create more ICPs than needed. We hence
need to register up to xics_max_server_number() dummy ICPs to
accomodate the migration of these machine types.
Recent VSMT rework changed xics_max_server_number() to return
DIV_ROUND_UP(max_cpus * spapr->vsmt, smp_threads)
instead of
DIV_ROUND_UP(max_cpus * kvmppc_smt_threads(), smp_threads);
The change is okay but it requires spapr->vsmt to be set, which
isn't the case with the current code. This causes the formula to
return zero and we don't create dummy ICPs. This breaks migration
of older guests as reported here:
https://bugzilla.redhat.com/show_bug.cgi?id=1549087
The dummy ICP workaround doesn't really have a dependency on XICS
itself. But it does depend on proper VCPU id numbering and it must
be applied before creating vCPUs (ie, creating real ICPs). So this
patch moves the workaround to spapr_init_cpus(), which already
assumes VSMT to be set.
Fixes: 72194664c8a1 ("spapr: use spapr->vsmt to compute VCPU ids")
Reported-by: Lukas Doktor <ldoktor@redhat.com>
Signed-off-by: Greg Kurz <groug@kaod.org>
---
hw/ppc/spapr.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 83c9d66dd56f..ae411057272f 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -183,7 +183,6 @@ static int xics_max_server_number(sPAPRMachineState *spapr)
static void xics_system_init(MachineState *machine, int nr_irqs, Error **errp)
{
sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
if (kvm_enabled()) {
if (machine_kernel_irqchip_allowed(machine) &&
@@ -205,17 +204,6 @@ static void xics_system_init(MachineState *machine, int nr_irqs, Error **errp)
return;
}
}
-
- if (smc->pre_2_10_has_unused_icps) {
- int i;
-
- for (i = 0; i < xics_max_server_number(spapr); i++) {
- /* Dummy entries get deregistered when real ICPState objects
- * are registered during CPU core hotplug.
- */
- pre_2_10_vmstate_register_dummy_icp(i);
- }
- }
}
static int spapr_fixup_cpu_smt_dt(void *fdt, int offset, PowerPCCPU *cpu,
@@ -2236,6 +2224,7 @@ static void spapr_init_cpus(sPAPRMachineState *spapr)
{
MachineState *machine = MACHINE(spapr);
MachineClass *mc = MACHINE_GET_CLASS(machine);
+ sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
const char *type = spapr_get_cpu_core_type(machine->cpu_type);
const CPUArchIdList *possible_cpus;
int boot_cores_nr = smp_cpus / smp_threads;
@@ -2261,6 +2250,17 @@ static void spapr_init_cpus(sPAPRMachineState *spapr)
boot_cores_nr = possible_cpus->len;
}
+ if (smc->pre_2_10_has_unused_icps) {
+ int i;
+
+ for (i = 0; i < xics_max_server_number(spapr); i++) {
+ /* Dummy entries get deregistered when real ICPState objects
+ * are registered during CPU core hotplug.
+ */
+ pre_2_10_vmstate_register_dummy_icp(i);
+ }
+ }
+
for (i = 0; i < possible_cpus->len; i++) {
int core_id = i * smp_threads;
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH 2/2] spapr: harden code that depends on VSMT
2018-02-27 15:22 [Qemu-devel] [PATCH 0/2] spapr: fix migration of old guests Greg Kurz
2018-02-27 15:22 ` [Qemu-devel] [PATCH 1/2] spapr: register dummy ICPs later Greg Kurz
@ 2018-02-27 15:23 ` Greg Kurz
2018-02-28 0:42 ` [Qemu-devel] [PATCH 0/2] spapr: fix migration of old guests David Gibson
2 siblings, 0 replies; 4+ messages in thread
From: Greg Kurz @ 2018-02-27 15:23 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-ppc, David Gibson, Laurent Vivier, Lukas Doktor
VSMT must be set in order to compute VCPU ids. This means that the
following functions must not be called before spapr_set_vsmt_mode()
was called:
- spapr_vcpu_id()
- spapr_is_thread0_in_vcore()
- xics_max_server_number()
We had a recent regression where the latter would be called before VSMT
was set, and broke migration of some old machine types. This patch
adds assert() in the above functions to avoid problems in the future.
Also, since VSMT is really a CPU related thing, spapr_set_vsmt_mode() is
now called from spapr_init_cpus(), just before the first VSMT user.
Signed-off-by: Greg Kurz <groug@kaod.org>
---
hw/ppc/spapr.c | 144 +++++++++++++++++++++++++++++---------------------------
1 file changed, 75 insertions(+), 69 deletions(-)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index ae411057272f..62081f68740e 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -105,12 +105,14 @@
*/
static int spapr_vcpu_id(sPAPRMachineState *spapr, int cpu_index)
{
+ assert(spapr->vsmt);
return
(cpu_index / smp_threads) * spapr->vsmt + cpu_index % smp_threads;
}
static bool spapr_is_thread0_in_vcore(sPAPRMachineState *spapr,
PowerPCCPU *cpu)
{
+ assert(spapr->vsmt);
return spapr_get_vcpu_id(cpu) % spapr->vsmt == 0;
}
@@ -177,6 +179,7 @@ static void pre_2_10_vmstate_unregister_dummy_icp(int i)
static int xics_max_server_number(sPAPRMachineState *spapr)
{
+ assert(spapr->vsmt);
return DIV_ROUND_UP(max_cpus * spapr->vsmt, smp_threads);
}
@@ -2220,73 +2223,6 @@ static CPUArchId *spapr_find_cpu_slot(MachineState *ms, uint32_t id, int *idx)
return &ms->possible_cpus->cpus[index];
}
-static void spapr_init_cpus(sPAPRMachineState *spapr)
-{
- MachineState *machine = MACHINE(spapr);
- MachineClass *mc = MACHINE_GET_CLASS(machine);
- sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
- const char *type = spapr_get_cpu_core_type(machine->cpu_type);
- const CPUArchIdList *possible_cpus;
- int boot_cores_nr = smp_cpus / smp_threads;
- int i;
-
- possible_cpus = mc->possible_cpu_arch_ids(machine);
- if (mc->has_hotpluggable_cpus) {
- if (smp_cpus % smp_threads) {
- error_report("smp_cpus (%u) must be multiple of threads (%u)",
- smp_cpus, smp_threads);
- exit(1);
- }
- if (max_cpus % smp_threads) {
- error_report("max_cpus (%u) must be multiple of threads (%u)",
- max_cpus, smp_threads);
- exit(1);
- }
- } else {
- if (max_cpus != smp_cpus) {
- error_report("This machine version does not support CPU hotplug");
- exit(1);
- }
- boot_cores_nr = possible_cpus->len;
- }
-
- if (smc->pre_2_10_has_unused_icps) {
- int i;
-
- for (i = 0; i < xics_max_server_number(spapr); i++) {
- /* Dummy entries get deregistered when real ICPState objects
- * are registered during CPU core hotplug.
- */
- pre_2_10_vmstate_register_dummy_icp(i);
- }
- }
-
- for (i = 0; i < possible_cpus->len; i++) {
- int core_id = i * smp_threads;
-
- if (mc->has_hotpluggable_cpus) {
- spapr_dr_connector_new(OBJECT(spapr), TYPE_SPAPR_DRC_CPU,
- spapr_vcpu_id(spapr, core_id));
- }
-
- if (i < boot_cores_nr) {
- Object *core = object_new(type);
- int nr_threads = smp_threads;
-
- /* Handle the partially filled core for older machine types */
- if ((i + 1) * smp_threads >= smp_cpus) {
- nr_threads = smp_cpus - i * smp_threads;
- }
-
- object_property_set_int(core, nr_threads, "nr-threads",
- &error_fatal);
- object_property_set_int(core, core_id, CPU_CORE_PROP_CORE_ID,
- &error_fatal);
- object_property_set_bool(core, true, "realized", &error_fatal);
- }
- }
-}
-
static void spapr_set_vsmt_mode(sPAPRMachineState *spapr, Error **errp)
{
Error *local_err = NULL;
@@ -2359,6 +2295,78 @@ out:
error_propagate(errp, local_err);
}
+static void spapr_init_cpus(sPAPRMachineState *spapr)
+{
+ MachineState *machine = MACHINE(spapr);
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
+ sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
+ const char *type = spapr_get_cpu_core_type(machine->cpu_type);
+ const CPUArchIdList *possible_cpus;
+ int boot_cores_nr = smp_cpus / smp_threads;
+ int i;
+
+ possible_cpus = mc->possible_cpu_arch_ids(machine);
+ if (mc->has_hotpluggable_cpus) {
+ if (smp_cpus % smp_threads) {
+ error_report("smp_cpus (%u) must be multiple of threads (%u)",
+ smp_cpus, smp_threads);
+ exit(1);
+ }
+ if (max_cpus % smp_threads) {
+ error_report("max_cpus (%u) must be multiple of threads (%u)",
+ max_cpus, smp_threads);
+ exit(1);
+ }
+ } else {
+ if (max_cpus != smp_cpus) {
+ error_report("This machine version does not support CPU hotplug");
+ exit(1);
+ }
+ boot_cores_nr = possible_cpus->len;
+ }
+
+ /* VSMT must be set in order to be able to compute VCPU ids, ie to
+ * call xics_max_server_number() or spapr_vcpu_id().
+ */
+ spapr_set_vsmt_mode(spapr, &error_fatal);
+
+ if (smc->pre_2_10_has_unused_icps) {
+ int i;
+
+ for (i = 0; i < xics_max_server_number(spapr); i++) {
+ /* Dummy entries get deregistered when real ICPState objects
+ * are registered during CPU core hotplug.
+ */
+ pre_2_10_vmstate_register_dummy_icp(i);
+ }
+ }
+
+ for (i = 0; i < possible_cpus->len; i++) {
+ int core_id = i * smp_threads;
+
+ if (mc->has_hotpluggable_cpus) {
+ spapr_dr_connector_new(OBJECT(spapr), TYPE_SPAPR_DRC_CPU,
+ spapr_vcpu_id(spapr, core_id));
+ }
+
+ if (i < boot_cores_nr) {
+ Object *core = object_new(type);
+ int nr_threads = smp_threads;
+
+ /* Handle the partially filled core for older machine types */
+ if ((i + 1) * smp_threads >= smp_cpus) {
+ nr_threads = smp_cpus - i * smp_threads;
+ }
+
+ object_property_set_int(core, nr_threads, "nr-threads",
+ &error_fatal);
+ object_property_set_int(core, core_id, CPU_CORE_PROP_CORE_ID,
+ &error_fatal);
+ object_property_set_bool(core, true, "realized", &error_fatal);
+ }
+ }
+}
+
/* pSeries LPAR / sPAPR hardware init */
static void spapr_machine_init(MachineState *machine)
{
@@ -2486,8 +2494,6 @@ static void spapr_machine_init(MachineState *machine)
}
/* init CPUs */
- spapr_set_vsmt_mode(spapr, &error_fatal);
-
spapr_init_cpus(spapr);
if (kvm_enabled()) {
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] spapr: fix migration of old guests
2018-02-27 15:22 [Qemu-devel] [PATCH 0/2] spapr: fix migration of old guests Greg Kurz
2018-02-27 15:22 ` [Qemu-devel] [PATCH 1/2] spapr: register dummy ICPs later Greg Kurz
2018-02-27 15:23 ` [Qemu-devel] [PATCH 2/2] spapr: harden code that depends on VSMT Greg Kurz
@ 2018-02-28 0:42 ` David Gibson
2 siblings, 0 replies; 4+ messages in thread
From: David Gibson @ 2018-02-28 0:42 UTC (permalink / raw)
To: Greg Kurz; +Cc: qemu-devel, qemu-ppc, Laurent Vivier, Lukas Doktor
[-- Attachment #1: Type: text/plain, Size: 584 bytes --]
On Tue, Feb 27, 2018 at 04:22:40PM +0100, Greg Kurz wrote:
> Recent VSMT work broke migration of old guests as reported in this BZ:
>
> https://bugzilla.redhat.com/show_bug.cgi?id=1549087
>
> Patch 1 fixes the issue, while patch 2 is a tentative code reorg to
> ensure VSMT is set before anyone tries to use spapr->vsmt.
Nice job tracking this down. Applied to ppc-for-2.12.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2018-02-28 1:06 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-02-27 15:22 [Qemu-devel] [PATCH 0/2] spapr: fix migration of old guests Greg Kurz
2018-02-27 15:22 ` [Qemu-devel] [PATCH 1/2] spapr: register dummy ICPs later Greg Kurz
2018-02-27 15:23 ` [Qemu-devel] [PATCH 2/2] spapr: harden code that depends on VSMT Greg Kurz
2018-02-28 0:42 ` [Qemu-devel] [PATCH 0/2] spapr: fix migration of old guests David Gibson
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).