In the SMP configuration, we should either specify a topology
parameter with a reasonable value (equal to or greater than 1)
or just leave it omitted and QEMU will calculate its value.
Configurations which explicitly specify the topology parameters
as zero like "sockets=0" are meaningless, so disallow them.
Suggested-by: Andrew Jones <drjo...@redhat.com>
Signed-off-by: Yanan Wang <wangyana...@huawei.com>
---
hw/core/machine.c | 31 +++++++++++++++++++++++--------
hw/i386/pc.c | 29 +++++++++++++++++++++--------
qapi/machine.json | 4 ++--
3 files changed, 46 insertions(+), 18 deletions(-)
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 775add0795..d73daa10f4 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -745,11 +745,25 @@ static void smp_parse(MachineState *ms, SMPConfiguration
*config, Error **errp)
{
unsigned cpus = config->has_cpus ? config->cpus : 0;
unsigned sockets = config->has_sockets ? config->sockets : 0;
+ unsigned dies = config->has_dies ? config->dies : 1;
unsigned cores = config->has_cores ? config->cores : 0;
unsigned threads = config->has_threads ? config->threads : 0;
+ unsigned maxcpus = config->has_maxcpus ? config->maxcpus : 0;
+
+ if ((config->has_cpus && config->cpus == 0) ||
+ (config->has_sockets && config->sockets == 0) ||
+ (config->has_dies && config->dies == 0) ||
+ (config->has_cores && config->cores == 0) ||
+ (config->has_threads && config->threads == 0) ||
+ (config->has_maxcpus && config->maxcpus == 0)) {
+ error_setg(errp, "parameters must be equal to or greater than one"
+ "if provided");
+ return;
+ }
- if (config->has_dies && config->dies != 0 && config->dies != 1) {
+ if (dies > 1) {
error_setg(errp, "dies not supported by this machine's CPU topology");
+ return;
}
/* compute missing values, prefer sockets over cores over threads */
@@ -760,8 +774,8 @@ static void smp_parse(MachineState *ms, SMPConfiguration
*config, Error **errp)
sockets = sockets > 0 ? sockets : 1;
cpus = cores * threads * sockets;
} else {
- ms->smp.max_cpus = config->has_maxcpus ? config->maxcpus : cpus;
- sockets = ms->smp.max_cpus / (cores * threads);
+ maxcpus = maxcpus > 0 ? maxcpus : cpus;
+ sockets = maxcpus / (cores * threads);
}
} else if (cores == 0) {
threads = threads > 0 ? threads : 1;
@@ -778,26 +792,27 @@ static void smp_parse(MachineState *ms, SMPConfiguration
*config, Error **errp)
return;
}
- ms->smp.max_cpus = config->has_maxcpus ? config->maxcpus : cpus;
+ maxcpus = maxcpus > 0 ? maxcpus : cpus;
- if (ms->smp.max_cpus < cpus) {
+ if (maxcpus < cpus) {
error_setg(errp, "maxcpus must be equal to or greater than smp");
return;
}
- if (sockets * cores * threads != ms->smp.max_cpus) {
+ if (sockets * cores * threads != maxcpus) {
error_setg(errp, "Invalid CPU topology: "
"sockets (%u) * cores (%u) * threads (%u) "
"!= maxcpus (%u)",
sockets, cores, threads,
- ms->smp.max_cpus);
+ maxcpus);
return;
}
ms->smp.cpus = cpus;
+ ms->smp.sockets = sockets;
ms->smp.cores = cores;
ms->smp.threads = threads;
- ms->smp.sockets = sockets;
+ ms->smp.max_cpus = maxcpus;
}
static void machine_get_smp(Object *obj, Visitor *v, const char *name,
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index c2b9d62a35..c6b63c00a5 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -719,6 +719,18 @@ static void pc_smp_parse(MachineState *ms,
SMPConfiguration *config, Error **err
unsigned dies = config->has_dies ? config->dies : 1;
unsigned cores = config->has_cores ? config->cores : 0;
unsigned threads = config->has_threads ? config->threads : 0;
+ unsigned maxcpus = config->has_maxcpus ? config->maxcpus : 0;
+
+ if ((config->has_cpus && config->cpus == 0) ||
+ (config->has_sockets && config->sockets == 0) ||
+ (config->has_dies && config->dies == 0) ||
+ (config->has_cores && config->cores == 0) ||
+ (config->has_threads && config->threads == 0) ||
+ (config->has_maxcpus && config->maxcpus == 0)) {
+ error_setg(errp, "parameters must be equal to or greater than one"
+ "if provided");