diff mbox series

[RFC,4/6] hw/i386/pc: Parse cluster cpu topology for PC machines

Message ID 20210331095343.12172-5-wangyanan55@huawei.com
State New
Headers show
Series Introduce cluster cpu topology support | expand

Commit Message

wangyanan (Y) March 31, 2021, 9:53 a.m. UTC
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(-)
diff mbox series

Patch

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 8aa85dec54..f2906f9185 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -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;