qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-ppc] [RFC PATCH v2] PPC: smp: autodetect numbers of threads per co


From: Alexey Kardashevskiy
Subject: [Qemu-ppc] [RFC PATCH v2] PPC: smp: autodetect numbers of threads per core
Date: Thu, 9 Jan 2014 16:34:08 +1100

On POWERPC, only a whole CPU core can be assigned to a KVM. Since
POWER7/8 support several threads per core, we want all threads of a core
to go to the same KVM so every time we run QEMU with -enable-kvm,
we have to add -smp X,threads=(4|8)" (4 for POWER7 and 8 for POWER8).

The user rather wants the maximum number of threads enabled, and
there is no easy way to know the maximum number supported by the hardware.
However the accelerator (KVM) knows this number and we can use it to
set the threads number to the maximum.

This adds a "threads_max" boolean switch to the "-smp" parameter which
tells QEMU to use the smp_threads value. The existing "threads" is not
changed to support a "max" string value in order to avoid duplicating
the parsing errors handling.

This adds smp_threads tweaking into POWERPC's kvm_arch_init().

This moves smp_parse() call in vl.c later to let the accelerator alter
the smp_threads value before actual "-smp" option parsing happens.

This does not change the default value of smp_threads which remains 1.

Signed-off-by: Alexey Kardashevskiy <address@hidden>
---
 qemu-options.hx  |  7 +++++--
 target-ppc/kvm.c |  2 ++
 vl.c             | 34 +++++++++++++++++++++++-----------
 3 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index bcfe9ea..8d582fa 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -73,16 +73,17 @@ Select CPU model (@code{-cpu help} for list and additional 
feature selection)
 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][,threads_max=on|off][,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"
     "                threads= number of threads on one CPU core\n"
+    "                threads_max= set number of threads on one CPU core to 
maximum supported by accelerator\n"
     "                sockets= number of discrete sockets in the system\n",
         QEMU_ARCH_ALL)
 STEXI
address@hidden -smp 
address@hidden,address@hidden,address@hidden,address@hidden,address@hidden
address@hidden -smp 
address@hidden,address@hidden,address@hidden,address@hidden,address@hidden,address@hidden
 @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
@@ -92,6 +93,8 @@ 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.
+If the accelerator has a knowledge about the maximum number of threads per
+core supported, @var{threads_max} will use the maximum value.
 ETEXI
 
 DEF("numa", HAS_ARG, QEMU_OPTION_numa,
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 781b72f..fa845fa 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -109,6 +109,8 @@ int kvm_arch_init(KVMState *s)
                         "VM to stall at times!\n");
     }
 
+    smp_threads = kvmppc_smt_threads();
+
     kvm_ppc_register_host_cpu_type();
 
     return 0;
diff --git a/vl.c b/vl.c
index c268949..57589aa 100644
--- a/vl.c
+++ b/vl.c
@@ -1381,6 +1381,9 @@ static QemuOptsList qemu_smp_opts = {
             .name = "threads",
             .type = QEMU_OPT_NUMBER,
         }, {
+            .name = "threads_max",
+            .type = QEMU_OPT_BOOL,
+        }, {
             .name = "maxcpus",
             .type = QEMU_OPT_NUMBER,
         },
@@ -1396,12 +1399,21 @@ static void smp_parse(QemuOpts *opts)
         unsigned sockets = qemu_opt_get_number(opts, "sockets", 0);
         unsigned cores   = qemu_opt_get_number(opts, "cores", 0);
         unsigned threads = qemu_opt_get_number(opts, "threads", 0);
+        bool threads_max = qemu_opt_get_bool(opts, "threads_max", false);
 
         /* compute missing values, prefer sockets over cores over threads */
         if (cpus == 0 || sockets == 0) {
             sockets = sockets > 0 ? sockets : 1;
             cores = cores > 0 ? cores : 1;
-            threads = threads > 0 ? threads : 1;
+            if (threads_max) {
+                if (threads > 0) {
+                    fprintf(stderr, "Use either threads or threads_max\n");
+                    exit(1);
+                }
+                threads = smp_threads > 0 ? smp_threads : 1;
+            } else {
+                threads = threads > 0 ? threads : 1;
+            }
             if (cpus == 0) {
                 cpus = cores * threads * sockets;
             }
@@ -3895,16 +3907,6 @@ int main(int argc, char **argv, char **envp)
         data_dir[data_dir_idx++] = CONFIG_QEMU_DATADIR;
     }
 
-    smp_parse(qemu_opts_find(qemu_find_opts("smp-opts"), NULL));
-
-    machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
-    if (smp_cpus > machine->max_cpus) {
-        fprintf(stderr, "Number of SMP cpus requested (%d), exceeds max cpus "
-                "supported by machine `%s' (%d)\n", smp_cpus,  machine->name,
-                machine->max_cpus);
-        exit(1);
-    }
-
     /*
      * Get the default machine options from the machine if it is not already
      * specified either by the configuration file or by the command line.
@@ -4058,6 +4060,16 @@ int main(int argc, char **argv, char **envp)
         qtest_init(qtest_chrdev, qtest_log);
     }
 
+    smp_parse(qemu_opts_find(qemu_find_opts("smp-opts"), NULL));
+
+    machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
+    if (smp_cpus > machine->max_cpus) {
+        fprintf(stderr, "Number of SMP cpus requested (%d), exceeds max cpus "
+                "supported by machine `%s' (%d)\n", smp_cpus,  machine->name,
+                machine->max_cpus);
+        exit(1);
+    }
+
     machine_opts = qemu_get_machine_opts();
     kernel_filename = qemu_opt_get(machine_opts, "kernel");
     initrd_filename = qemu_opt_get(machine_opts, "initrd");
-- 
1.8.4.rc4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]