Skip to content

Commit

Permalink
vl.c: Add -smp, dies=* command line support and update doc
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Like Xu authored and ehabkost committed Jul 5, 2019
1 parent 6f47956 commit 1b45842
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 21 deletions.
30 changes: 17 additions & 13 deletions hw/i386/pc.c
Expand Up @@ -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)
{
PCMachineState *pcms = PC_MACHINE(ms);

if (opts) {
unsigned cpus = qemu_opt_get_number(opts, "cpus", 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 threads = qemu_opt_get_number(opts, "threads", 0);

Expand All @@ -1552,24 +1555,24 @@ void pc_smp_parse(MachineState *ms, QemuOpts *opts)
threads = threads > 0 ? threads : 1;
if (cpus == 0) {
sockets = sockets > 0 ? sockets : 1;
cpus = cores * threads * sockets;
cpus = cores * threads * dies * sockets;
} else {
ms->smp.max_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) {
threads = threads > 0 ? threads : 1;
cores = cpus / (sockets * threads);
cores = cpus / (sockets * dies * threads);
cores = cores > 0 ? cores : 1;
} else if (threads == 0) {
threads = cpus / (cores * sockets);
threads = cpus / (cores * dies * sockets);
threads = threads > 0 ? threads : 1;
} else if (sockets * cores * threads < cpus) {
} else if (sockets * dies * cores * threads < cpus) {
error_report("cpu topology: "
"sockets (%u) * cores (%u) * threads (%u) < "
"sockets (%u) * dies (%u) * cores (%u) * threads (%u) < "
"smp_cpus (%u)",
sockets, cores, threads, cpus);
sockets, dies, cores, threads, cpus);
exit(1);
}

Expand All @@ -1581,26 +1584,27 @@ void pc_smp_parse(MachineState *ms, QemuOpts *opts)
exit(1);
}

if (sockets * cores * threads > ms->smp.max_cpus) {
if (sockets * dies * cores * threads > ms->smp.max_cpus) {
error_report("cpu topology: "
"sockets (%u) * cores (%u) * threads (%u) > "
"sockets (%u) * dies (%u) * cores (%u) * threads (%u) > "
"maxcpus (%u)",
sockets, cores, threads,
sockets, dies, cores, threads,
ms->smp.max_cpus);
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: "
"sockets (%u) * cores (%u) * threads (%u) "
"sockets (%u) * dies (%u) * cores (%u) * threads (%u) "
"!= maxcpus (%u)",
sockets, cores, threads,
sockets, dies, cores, threads,
ms->smp.max_cpus);
}

ms->smp.cpus = cpus;
ms->smp.cores = cores;
ms->smp.threads = threads;
pcms->smp_dies = dies;
}

if (ms->smp.cpus > 1) {
Expand Down
17 changes: 9 additions & 8 deletions qemu-options.hx
Expand Up @@ -138,25 +138,26 @@ no incompatible TCG features have been enabled (e.g. icount/replay).
ETEXI
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"
" maxcpus= maximum number of total cpus, including\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"
" dies= number of CPU dies on one socket (for PC only)\n"
" sockets= number of discrete sockets in the system\n",
QEMU_ARCH_ALL)
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
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
to 4.
For the PC target, the number of @var{cores} per socket, the number
of @var{threads} per cores and the total number of @var{sockets} can be
specified. Missing values will be computed. If any on the three values is
given, the total number of CPUs @var{n} can be omitted. @var{maxcpus}
specifies the maximum number of hotpluggable CPUs.
For the PC target, the number of @var{cores} per die, the number of @var{threads}
per cores, the number of @var{dies} per packages and the total number of
@var{sockets} can be specified. Missing values will be computed.
If any on the three values is given, the total number of CPUs @var{n} can be omitted.
@var{maxcpus} specifies the maximum number of hotpluggable CPUs.
ETEXI

DEF("numa", HAS_ARG, QEMU_OPTION_numa,
Expand Down
3 changes: 3 additions & 0 deletions vl.c
Expand Up @@ -1231,6 +1231,9 @@ static QemuOptsList qemu_smp_opts = {
}, {
.name = "sockets",
.type = QEMU_OPT_NUMBER,
}, {
.name = "dies",
.type = QEMU_OPT_NUMBER,
}, {
.name = "cores",
.type = QEMU_OPT_NUMBER,
Expand Down

0 comments on commit 1b45842

Please sign in to comment.