@@ -716,33 +716,39 @@ void pc_smp_parse(MachineState *ms, QemuOpts *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 clusters = qemu_opt_get_number(opts, "clusters", 1);
unsigned cores = qemu_opt_get_number(opts, "cores", 0);
unsigned threads = qemu_opt_get_number(opts, "threads", 0);
- /* compute missing values, prefer sockets over cores over threads */
+ /*
+ * Compute missing values, prefer sockets over cores
+ * over threads. And the value of dies or clusters has
+ * been set as default 1 if not explicitly specified.
+ */
if (cpus == 0 || sockets == 0) {
cores = cores > 0 ? cores : 1;
threads = threads > 0 ? threads : 1;
if (cpus == 0) {
sockets = sockets > 0 ? sockets : 1;
- cpus = cores * threads * dies * sockets;
+ cpus = sockets * dies * clusters * cores * threads;
} else {
ms->smp.max_cpus =
qemu_opt_get_number(opts, "maxcpus", cpus);
- sockets = ms->smp.max_cpus / (cores * threads * dies);
+ sockets = ms->smp.max_cpus /
+ (dies * clusters * cores * threads);
}
} else if (cores == 0) {
threads = threads > 0 ? threads : 1;
- cores = cpus / (sockets * dies * threads);
+ cores = cpus / (sockets * dies * clusters * threads);
cores = cores > 0 ? cores : 1;
} else if (threads == 0) {
- threads = cpus / (cores * dies * sockets);
+ threads = cpus / (sockets * dies * clusters * cores);
threads = threads > 0 ? threads : 1;
- } else if (sockets * dies * cores * threads < cpus) {
+ } else if (sockets * dies * clusters * cores * threads < cpus) {
error_report("cpu topology: "
- "sockets (%u) * dies (%u) * cores (%u) * threads (%u) < "
- "smp_cpus (%u)",
- sockets, dies, cores, threads, cpus);
+ "sockets (%u) * dies (%u) * clusters (%u) * "
+ "cores (%u) * threads (%u) < smp_cpus (%u)",
+ sockets, dies, clusters, cores, threads, cpus);
exit(1);
}
@@ -756,14 +762,15 @@ void pc_smp_parse(MachineState *ms, QemuOpts *opts)
if (sockets * dies * cores * threads != ms->smp.max_cpus) {
error_report("Invalid CPU topology deprecated: "
- "sockets (%u) * dies (%u) * cores (%u) * threads (%u) "
- "!= maxcpus (%u)",
- sockets, dies, cores, threads,
+ "sockets (%u) * dies (%u) * clusters (%u) * "
+ "cores (%u) * threads (%u) != maxcpus (%u)",
+ sockets, dies, clusters, cores, threads,
ms->smp.max_cpus);
exit(1);
}
ms->smp.cpus = cpus;
+ ms->smp.clusters = clusters;
ms->smp.cores = cores;
ms->smp.threads = threads;
ms->smp.sockets = sockets;
There is a separate function pc_smp_parse() in hw/i386/pc.c used to parse cpu topology for the PC machines. And there are some x86 implementations that have a similar concept of cluster, for example, on Jacobsville there are 6 clusters of 4 Atom cores, each cluster sharing a separate L2 cache, and 24 cores sharing L3 cache. So parse cluster cpu topology the for PC machines, then guest kernel will take advantages of it for better scheduling performance. In pc_smp_parse(), the computing logic of missing values prefers sockets over cores over threads. And the value of clusters will be set as default 1 if not explictly specified, so that it will not impact the parsing results of machines that won't specify "clusters=" in -smp command line because they just don't support it. Signed-off-by: Yanan Wang <wangyanan55@huawei.com> --- hw/i386/pc.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-)