vl.c: Add -smp, dies=* command line support and update doc

For PC target, users could configure the number of dies per one package
via command line with this patch, such as "-smp dies=2,cores=4".

The parsing rules of new cpu-topology model obey the same restrictions/logic
as the legacy socket/core/thread model especially on missing values computing.

Signed-off-by: Like Xu <like.xu@linux.intel.com>
Message-Id: <20190620054525.37188-4-like.xu@linux.intel.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
This commit is contained in:
Like Xu 2019-06-20 13:45:25 +08:00 committed by Eduardo Habkost
parent 6f479566a8
commit 1b45842203
3 changed files with 29 additions and 21 deletions

View File

@ -1540,9 +1540,12 @@ static void pc_new_cpu(PCMachineState *pcms, int64_t apic_id, Error **errp)
*/ */
void pc_smp_parse(MachineState *ms, QemuOpts *opts) void pc_smp_parse(MachineState *ms, QemuOpts *opts)
{ {
PCMachineState *pcms = PC_MACHINE(ms);
if (opts) { if (opts) {
unsigned cpus = qemu_opt_get_number(opts, "cpus", 0); unsigned cpus = qemu_opt_get_number(opts, "cpus", 0);
unsigned sockets = qemu_opt_get_number(opts, "sockets", 0); unsigned sockets = qemu_opt_get_number(opts, "sockets", 0);
unsigned dies = qemu_opt_get_number(opts, "dies", 1);
unsigned cores = qemu_opt_get_number(opts, "cores", 0); unsigned cores = qemu_opt_get_number(opts, "cores", 0);
unsigned threads = qemu_opt_get_number(opts, "threads", 0); unsigned threads = qemu_opt_get_number(opts, "threads", 0);
@ -1552,24 +1555,24 @@ void pc_smp_parse(MachineState *ms, QemuOpts *opts)
threads = threads > 0 ? threads : 1; threads = threads > 0 ? threads : 1;
if (cpus == 0) { if (cpus == 0) {
sockets = sockets > 0 ? sockets : 1; sockets = sockets > 0 ? sockets : 1;
cpus = cores * threads * sockets; cpus = cores * threads * dies * sockets;
} else { } else {
ms->smp.max_cpus = ms->smp.max_cpus =
qemu_opt_get_number(opts, "maxcpus", cpus); qemu_opt_get_number(opts, "maxcpus", cpus);
sockets = ms->smp.max_cpus / (cores * threads); sockets = ms->smp.max_cpus / (cores * threads * dies);
} }
} else if (cores == 0) { } else if (cores == 0) {
threads = threads > 0 ? threads : 1; threads = threads > 0 ? threads : 1;
cores = cpus / (sockets * threads); cores = cpus / (sockets * dies * threads);
cores = cores > 0 ? cores : 1; cores = cores > 0 ? cores : 1;
} else if (threads == 0) { } else if (threads == 0) {
threads = cpus / (cores * sockets); threads = cpus / (cores * dies * sockets);
threads = threads > 0 ? threads : 1; threads = threads > 0 ? threads : 1;
} else if (sockets * cores * threads < cpus) { } else if (sockets * dies * cores * threads < cpus) {
error_report("cpu topology: " error_report("cpu topology: "
"sockets (%u) * cores (%u) * threads (%u) < " "sockets (%u) * dies (%u) * cores (%u) * threads (%u) < "
"smp_cpus (%u)", "smp_cpus (%u)",
sockets, cores, threads, cpus); sockets, dies, cores, threads, cpus);
exit(1); exit(1);
} }
@ -1581,26 +1584,27 @@ void pc_smp_parse(MachineState *ms, QemuOpts *opts)
exit(1); exit(1);
} }
if (sockets * cores * threads > ms->smp.max_cpus) { if (sockets * dies * cores * threads > ms->smp.max_cpus) {
error_report("cpu topology: " error_report("cpu topology: "
"sockets (%u) * cores (%u) * threads (%u) > " "sockets (%u) * dies (%u) * cores (%u) * threads (%u) > "
"maxcpus (%u)", "maxcpus (%u)",
sockets, cores, threads, sockets, dies, cores, threads,
ms->smp.max_cpus); ms->smp.max_cpus);
exit(1); exit(1);
} }
if (sockets * cores * threads != ms->smp.max_cpus) { if (sockets * dies * cores * threads != ms->smp.max_cpus) {
warn_report("Invalid CPU topology deprecated: " warn_report("Invalid CPU topology deprecated: "
"sockets (%u) * cores (%u) * threads (%u) " "sockets (%u) * dies (%u) * cores (%u) * threads (%u) "
"!= maxcpus (%u)", "!= maxcpus (%u)",
sockets, cores, threads, sockets, dies, cores, threads,
ms->smp.max_cpus); ms->smp.max_cpus);
} }
ms->smp.cpus = cpus; ms->smp.cpus = cpus;
ms->smp.cores = cores; ms->smp.cores = cores;
ms->smp.threads = threads; ms->smp.threads = threads;
pcms->smp_dies = dies;
} }
if (ms->smp.cpus > 1) { if (ms->smp.cpus > 1) {

View File

@ -138,25 +138,26 @@ no incompatible TCG features have been enabled (e.g. icount/replay).
ETEXI ETEXI
DEF("smp", HAS_ARG, QEMU_OPTION_smp, DEF("smp", HAS_ARG, QEMU_OPTION_smp,
"-smp [cpus=]n[,maxcpus=cpus][,cores=cores][,threads=threads][,sockets=sockets]\n" "-smp [cpus=]n[,maxcpus=cpus][,cores=cores][,threads=threads][,dies=dies][,sockets=sockets]\n"
" set the number of CPUs to 'n' [default=1]\n" " set the number of CPUs to 'n' [default=1]\n"
" maxcpus= maximum number of total cpus, including\n" " maxcpus= maximum number of total cpus, including\n"
" offline CPUs for hotplug, etc\n" " offline CPUs for hotplug, etc\n"
" cores= number of CPU cores on one socket\n" " cores= number of CPU cores on one socket (for PC, it's on one die)\n"
" threads= number of threads on one CPU core\n" " threads= number of threads on one CPU core\n"
" dies= number of CPU dies on one socket (for PC only)\n"
" sockets= number of discrete sockets in the system\n", " sockets= number of discrete sockets in the system\n",
QEMU_ARCH_ALL) QEMU_ARCH_ALL)
STEXI STEXI
@item -smp [cpus=]@var{n}[,cores=@var{cores}][,threads=@var{threads}][,sockets=@var{sockets}][,maxcpus=@var{maxcpus}] @item -smp [cpus=]@var{n}[,cores=@var{cores}][,threads=@var{threads}][,dies=dies][,sockets=@var{sockets}][,maxcpus=@var{maxcpus}]
@findex -smp @findex -smp
Simulate an SMP system with @var{n} CPUs. On the PC target, up to 255 Simulate an SMP system with @var{n} CPUs. On the PC target, up to 255
CPUs are supported. On Sparc32 target, Linux limits the number of usable CPUs CPUs are supported. On Sparc32 target, Linux limits the number of usable CPUs
to 4. to 4.
For the PC target, the number of @var{cores} per socket, the number For the PC target, the number of @var{cores} per die, the number of @var{threads}
of @var{threads} per cores and the total number of @var{sockets} can be per cores, the number of @var{dies} per packages and the total number of
specified. Missing values will be computed. If any on the three values is @var{sockets} can be specified. Missing values will be computed.
given, the total number of CPUs @var{n} can be omitted. @var{maxcpus} If any on the three values is given, the total number of CPUs @var{n} can be omitted.
specifies the maximum number of hotpluggable CPUs. @var{maxcpus} specifies the maximum number of hotpluggable CPUs.
ETEXI ETEXI
DEF("numa", HAS_ARG, QEMU_OPTION_numa, DEF("numa", HAS_ARG, QEMU_OPTION_numa,

3
vl.c
View File

@ -1231,6 +1231,9 @@ static QemuOptsList qemu_smp_opts = {
}, { }, {
.name = "sockets", .name = "sockets",
.type = QEMU_OPT_NUMBER, .type = QEMU_OPT_NUMBER,
}, {
.name = "dies",
.type = QEMU_OPT_NUMBER,
}, { }, {
.name = "cores", .name = "cores",
.type = QEMU_OPT_NUMBER, .type = QEMU_OPT_NUMBER,