qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC PATCH v2] PPC: smp: autodetect numbers of threads per core
@ 2014-01-09  5:34 Alexey Kardashevskiy
  2014-01-09 21:00 ` Mike Day
  2014-01-09 22:50 ` Scott Wood
  0 siblings, 2 replies; 17+ messages in thread
From: Alexey Kardashevskiy @ 2014-01-09  5:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alexey Kardashevskiy, qemu-ppc, Paul Mackerras, Alexander Graf

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 <aik@ozlabs.ru>
---
 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
-@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}][,threads_max=@var{threads_max}][,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
@@ -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

^ permalink raw reply related	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2014-01-10 14:35 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-01-09  5:34 [Qemu-devel] [RFC PATCH v2] PPC: smp: autodetect numbers of threads per core Alexey Kardashevskiy
2014-01-09 21:00 ` Mike Day
2014-01-09 22:12   ` Alexey Kardashevskiy
2014-01-09 23:40     ` Alexander Graf
2014-01-10  1:39       ` Alexey Kardashevskiy
2014-01-10 13:03         ` Mike Day
2014-01-10 13:28           ` Alexander Graf
2014-01-10 13:42             ` Alexey Kardashevskiy
2014-01-10 14:00               ` Alexander Graf
2014-01-10 14:13                 ` Alexey Kardashevskiy
2014-01-10 14:20                   ` Alexander Graf
2014-01-10 14:21                   ` Mike Day
2014-01-10 14:25                     ` Alexander Graf
2014-01-10 14:29                       ` Mike Day
2014-01-10 14:35                       ` Alexey Kardashevskiy
2014-01-10 14:12             ` Mike Day
2014-01-09 22:50 ` Scott Wood

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).