All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters
@ 2016-06-10 17:40 Andrew Jones
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 01/16] vl: smp_parse: cleanups Andrew Jones
                   ` (18 more replies)
  0 siblings, 19 replies; 74+ messages in thread
From: Andrew Jones @ 2016-06-10 17:40 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, qemu-arm
  Cc: imammedo, ehabkost, pbonzini, peter.maydell, david, dgibson, agraf

This series is a first step in eliminating smp_* global
variables (the last patch gets rid of two of them!) And, it's
a first step in deprecating '-smp' in favor of using machine
properties, e.g.
 qemu -machine pc,sockets=2,cores=2,threads=2,maxcpus=8,cpus=8 ...

It's also a first step in allowing machine types to override
the default parameter parsing, which makes assumptions that
not all machine types may agree with. (mach-virt is coming...)

So, three first steps, I guess that's 3 steps. And a forth
thing it does is some fixes for the smp parsing and also for
SMBIOS use of cpu topology.

Tested with kvm-unit-tests on all five arches supported
there, x86_64 both with KVM and TCG, and booting an x86_64
guest (KVM) to check SMBIOS before and after in order to make
sure it was the same. Also compile tested all targets.

Thanks,
drew


Andrew Jones (15):
  vl: smp_parse: cleanups
  vl: smp: add checks for maxcpus based topologies
  hw/smbios/smbios: fix number of sockets calculation
  hw/core/machine: add smp properites
  vl: move smp parsing to machine pre_init
  qom/cpu: make nr-cores,nr-threads real properties
  hw/core/machine: set cpu global nr_cores,nr_threads in pre_init
  hw/i386/pc: don't use smp_cores,smp_threads
  hw/ppc/spapr: don't use smp_cores,smp_threads
  target-ppc: don't use smp_threads
  hw/arm/virt: rename *.smp_cpus to *.cpus
  hw/arm/virt: don't use smp_cpus,max_cpus
  hw/arm/virt: stash cpu topo info in VirtGuestInfo
  smbios: don't use smp_cores,smp_threads
  sysemu/cpus: bye, bye smp_cores,smp_threads

Igor Mammedov (1):
  hw/core/machine: Introduce pre_init

 cpus.c                           |   2 -
 hw/arm/virt-acpi-build.c         |  14 +--
 hw/arm/virt.c                    |  41 +++++---
 hw/core/machine.c                | 210 +++++++++++++++++++++++++++++++++++++++
 hw/i386/pc.c                     |  39 +++++---
 hw/ppc/spapr.c                   |   9 +-
 hw/ppc/spapr_rtas.c              |   2 +-
 hw/smbios/smbios.c               |  20 ++--
 include/hw/arm/virt-acpi-build.h |   6 +-
 include/hw/boards.h              |   7 ++
 include/hw/smbios/smbios.h       |  10 ++
 include/sysemu/cpus.h            |  10 --
 qom/cpu.c                        |   8 ++
 target-ppc/translate_init.c      |  15 ++-
 vl.c                             | 101 +++++++------------
 15 files changed, 356 insertions(+), 138 deletions(-)

-- 
2.4.11

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

* [Qemu-devel] [PATCH RFC 01/16] vl: smp_parse: cleanups
  2016-06-10 17:40 [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Andrew Jones
@ 2016-06-10 17:40 ` Andrew Jones
  2016-06-14  1:15   ` David Gibson
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 02/16] vl: smp: add checks for maxcpus based topologies Andrew Jones
                   ` (17 subsequent siblings)
  18 siblings, 1 reply; 74+ messages in thread
From: Andrew Jones @ 2016-06-10 17:40 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, qemu-arm
  Cc: imammedo, ehabkost, pbonzini, peter.maydell, david, dgibson, agraf

No functional changes; only some code movement and removal of
dead code (impossible conditions). Also, max_cpus can be
initialized to 1, like smp_cpus, because it's either set by the
user or set to smp_cpus, when smp_cpus is set by the user, or
set to 1, when nothing is set.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 vl.c | 34 +++++++++++++++-------------------
 1 file changed, 15 insertions(+), 19 deletions(-)

diff --git a/vl.c b/vl.c
index b0bcc255ee9a5..7b96e787922f9 100644
--- a/vl.c
+++ b/vl.c
@@ -154,7 +154,7 @@ CharDriverState *sclp_hds[MAX_SCLP_CONSOLES];
 int win2k_install_hack = 0;
 int singlestep = 0;
 int smp_cpus = 1;
-int max_cpus = 0;
+int max_cpus = 1;
 int smp_cores = 1;
 int smp_threads = 1;
 int acpi_enabled = 1;
@@ -1223,7 +1223,6 @@ static QemuOptsList qemu_smp_opts = {
 static void smp_parse(QemuOpts *opts)
 {
     if (opts) {
-
         unsigned cpus    = qemu_opt_get_number(opts, "cpus", 0);
         unsigned sockets = qemu_opt_get_number(opts, "sockets", 0);
         unsigned cores   = qemu_opt_get_number(opts, "cores", 0);
@@ -1251,6 +1250,17 @@ static void smp_parse(QemuOpts *opts)
         }
 
         max_cpus = qemu_opt_get_number(opts, "maxcpus", cpus);
+
+        if (max_cpus > MAX_CPUMASK_BITS) {
+            error_report("unsupported number of maxcpus");
+            exit(1);
+        }
+
+        if (max_cpus < cpus) {
+            error_report("maxcpus must be equal to or greater than smp");
+            exit(1);
+        }
+
         if (sockets * cores * threads > max_cpus) {
             error_report("cpu topology: "
                          "sockets (%u) * cores (%u) * threads (%u) > "
@@ -1260,25 +1270,11 @@ static void smp_parse(QemuOpts *opts)
         }
 
         smp_cpus = cpus;
-        smp_cores = cores > 0 ? cores : 1;
-        smp_threads = threads > 0 ? threads : 1;
-
-    }
-
-    if (max_cpus == 0) {
-        max_cpus = smp_cpus;
-    }
-
-    if (max_cpus > MAX_CPUMASK_BITS) {
-        error_report("unsupported number of maxcpus");
-        exit(1);
-    }
-    if (max_cpus < smp_cpus) {
-        error_report("maxcpus must be equal to or greater than smp");
-        exit(1);
+        smp_cores = cores;
+        smp_threads = threads;
     }
 
-    if (smp_cpus > 1 || smp_cores > 1 || smp_threads > 1) {
+    if (smp_cpus > 1) {
         Error *blocker = NULL;
         error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, "smp");
         replay_add_blocker(blocker);
-- 
2.4.11

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

* [Qemu-devel] [PATCH RFC 02/16] vl: smp: add checks for maxcpus based topologies
  2016-06-10 17:40 [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Andrew Jones
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 01/16] vl: smp_parse: cleanups Andrew Jones
@ 2016-06-10 17:40 ` Andrew Jones
  2016-06-14  1:28   ` David Gibson
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 03/16] hw/smbios/smbios: fix number of sockets calculation Andrew Jones
                   ` (16 subsequent siblings)
  18 siblings, 1 reply; 74+ messages in thread
From: Andrew Jones @ 2016-06-10 17:40 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, qemu-arm
  Cc: imammedo, ehabkost, pbonzini, peter.maydell, david, dgibson, agraf

smp_parse computes missing smp options. Unfortunately cores and
threads are computed by dividing smp_cpus, instead of max_cpus.
This is incorrect because the topology doesn't leave room for
hotplug. More unfortunately, we can't change it easily, as doing
so would impact existing command lines. This patch adds a warning
when the topology doesn't add up, and then checks that the topology
at least computes when sockets are recalculated. If not, then it
does fail.

Adding the new failure is justified by the fact that we don't
store the number of input sockets, and thus all consumers of
cpu topology information recalculate it. If they choose to
(correctly) calculate it based on maxcpus, then we need to
guard them against building topologies which provide more cpu
slots than are the maximum allowed cpus.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 vl.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/vl.c b/vl.c
index 7b96e787922f9..8d482cb1bf020 100644
--- a/vl.c
+++ b/vl.c
@@ -1227,6 +1227,7 @@ 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 sockets_input = sockets > 0;
 
         /* compute missing values, prefer sockets over cores over threads */
         if (cpus == 0 || sockets == 0) {
@@ -1269,6 +1270,24 @@ static void smp_parse(QemuOpts *opts)
             exit(1);
         }
 
+        if (sockets_input && sockets * cores * threads != max_cpus) {
+            unsigned sockets_rounded = DIV_ROUND_UP(max_cpus, cores * threads);
+
+            error_report("warning: cpu topology: "
+                         "sockets (%u) * cores (%u) * threads (%u) != "
+                         "maxcpus (%u). Trying sockets=%u.",
+                         sockets, cores, threads, max_cpus, sockets_rounded);
+            sockets = sockets_rounded;
+
+            if (sockets * cores * threads > max_cpus) {
+                error_report("cpu topology: "
+                             "sockets (%u) * cores (%u) * threads (%u) > "
+                             "maxcpus (%u)",
+                             sockets, cores, threads, max_cpus);
+                exit(1);
+            }
+        }
+
         smp_cpus = cpus;
         smp_cores = cores;
         smp_threads = threads;
-- 
2.4.11

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

* [Qemu-devel] [PATCH RFC 03/16] hw/smbios/smbios: fix number of sockets calculation
  2016-06-10 17:40 [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Andrew Jones
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 01/16] vl: smp_parse: cleanups Andrew Jones
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 02/16] vl: smp: add checks for maxcpus based topologies Andrew Jones
@ 2016-06-10 17:40 ` Andrew Jones
  2016-07-11 14:23   ` Igor Mammedov
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 04/16] hw/core/machine: Introduce pre_init Andrew Jones
                   ` (15 subsequent siblings)
  18 siblings, 1 reply; 74+ messages in thread
From: Andrew Jones @ 2016-06-10 17:40 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, qemu-arm
  Cc: imammedo, ehabkost, pbonzini, peter.maydell, david, dgibson, agraf

The specification "sect. 7.5 Processor Information (Type 4)" says
 "NOTE One structure is provided for each processor instance in a
  system. For example, a system that supports up to two processors
  includes two Processor Information structures - even if only one
  processor is currently installed..."

We should use max_cpus in the calculation. The rounding is still
necessary, since smp_cores and smp_threads may have been calculated
based on smp_cpus, rather than max_cpus. The rounding is safe,
because smp_parse will fail when the result produces a topology
supporting more cpus than max_cpus.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 hw/smbios/smbios.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index cb8a1111029cf..cf18ecfd8599c 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -881,7 +881,7 @@ void smbios_get_tables(const struct smbios_phys_mem_area *mem_array,
         smbios_build_type_2_table();
         smbios_build_type_3_table();
 
-        smbios_smp_sockets = DIV_ROUND_UP(smp_cpus, smp_cores * smp_threads);
+        smbios_smp_sockets = DIV_ROUND_UP(max_cpus, smp_cores * smp_threads);
         assert(smbios_smp_sockets >= 1);
 
         for (i = 0; i < smbios_smp_sockets; i++) {
-- 
2.4.11

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

* [Qemu-devel] [PATCH RFC 04/16] hw/core/machine: Introduce pre_init
  2016-06-10 17:40 [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Andrew Jones
                   ` (2 preceding siblings ...)
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 03/16] hw/smbios/smbios: fix number of sockets calculation Andrew Jones
@ 2016-06-10 17:40 ` Andrew Jones
  2016-06-14  1:30   ` David Gibson
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 05/16] hw/core/machine: add smp properites Andrew Jones
                   ` (14 subsequent siblings)
  18 siblings, 1 reply; 74+ messages in thread
From: Andrew Jones @ 2016-06-10 17:40 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, qemu-arm
  Cc: imammedo, ehabkost, pbonzini, peter.maydell, david, dgibson, agraf

From: Igor Mammedov <imammedo@redhat.com>

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 hw/core/machine.c   | 6 ++++++
 include/hw/boards.h | 1 +
 vl.c                | 1 +
 3 files changed, 8 insertions(+)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index ccdd5fa3e7728..3dce9020e510a 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -368,10 +368,16 @@ static void machine_init_notify(Notifier *notifier, void *data)
     foreach_dynamic_sysbus_device(error_on_sysbus_device, NULL);
 }
 
+static void machine_pre_init(MachineState *ms)
+{
+}
+
 static void machine_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
 
+    mc->pre_init = machine_pre_init;
+
     /* Default 128 MB as guest ram size */
     mc->default_ram_size = 128 * M_BYTE;
     mc->rom_file_has_mr = true;
diff --git a/include/hw/boards.h b/include/hw/boards.h
index d268bd00a9f7d..4e8dc68b07a24 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -92,6 +92,7 @@ struct MachineClass {
     const char *alias;
     const char *desc;
 
+    void (*pre_init)(MachineState *state);
     void (*init)(MachineState *state);
     void (*reset)(void);
     void (*hot_add_cpu)(const int64_t id, Error **errp);
diff --git a/vl.c b/vl.c
index 8d482cb1bf020..4849dd465d667 100644
--- a/vl.c
+++ b/vl.c
@@ -4500,6 +4500,7 @@ int main(int argc, char **argv, char **envp)
     current_machine->boot_order = boot_order;
     current_machine->cpu_model = cpu_model;
 
+    machine_class->pre_init(current_machine);
     machine_class->init(current_machine);
 
     realtime_init();
-- 
2.4.11

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

* [Qemu-devel] [PATCH RFC 05/16] hw/core/machine: add smp properites
  2016-06-10 17:40 [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Andrew Jones
                   ` (3 preceding siblings ...)
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 04/16] hw/core/machine: Introduce pre_init Andrew Jones
@ 2016-06-10 17:40 ` Andrew Jones
  2016-06-14  2:00   ` David Gibson
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 06/16] vl: move smp parsing to machine pre_init Andrew Jones
                   ` (13 subsequent siblings)
  18 siblings, 1 reply; 74+ messages in thread
From: Andrew Jones @ 2016-06-10 17:40 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, qemu-arm
  Cc: imammedo, ehabkost, pbonzini, peter.maydell, david, dgibson, agraf

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 hw/core/machine.c   | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/boards.h |  6 ++++
 2 files changed, 87 insertions(+)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 3dce9020e510a..2625044002e57 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -172,6 +172,53 @@ static void machine_set_dumpdtb(Object *obj, const char *value, Error **errp)
     ms->dumpdtb = g_strdup(value);
 }
 
+static void machine_get_smp(Object *obj, Visitor *v, const char *name,
+                            void *opaque, Error **errp)
+{
+    MachineState *ms = MACHINE(obj);
+    int64_t value;
+
+    if (strncmp(name, "sockets", 7) == 0) {
+        value = ms->sockets;
+    } else if (strncmp(name, "cores", 5) == 0) {
+        value = ms->cores;
+    } else if (strncmp(name, "threads", 7) == 0) {
+        value = ms->threads;
+    } else if (strncmp(name, "maxcpus", 7) == 0) {
+        value = ms->maxcpus;
+    } else if (strncmp(name, "cpus", 4) == 0) {
+        value = ms->cpus;
+    }
+
+    visit_type_int(v, name, &value, errp);
+}
+
+static void machine_set_smp(Object *obj, Visitor *v, const char *name,
+                            void *opaque, Error **errp)
+{
+    MachineState *ms = MACHINE(obj);
+    Error *error = NULL;
+    int64_t value;
+
+    visit_type_int(v, name, &value, &error);
+    if (error) {
+        error_propagate(errp, error);
+        return;
+    }
+
+    if (strncmp(name, "sockets", 7) == 0) {
+        ms->sockets = value;
+    } else if (strncmp(name, "cores", 5) == 0) {
+        ms->cores = value;;
+    } else if (strncmp(name, "threads", 7) == 0) {
+        ms->threads = value;
+    } else if (strncmp(name, "maxcpus", 7) == 0) {
+        ms->maxcpus = value;
+    } else if (strncmp(name, "cpus", 4) == 0) {
+        ms->cpus = value;
+    }
+}
+
 static void machine_get_phandle_start(Object *obj, Visitor *v,
                                       const char *name, void *opaque,
                                       Error **errp)
@@ -368,8 +415,18 @@ static void machine_init_notify(Notifier *notifier, void *data)
     foreach_dynamic_sysbus_device(error_on_sysbus_device, NULL);
 }
 
+static void machine_set_smp_parameters(MachineState *ms)
+{
+    if (ms->sockets != -1 || ms->cores != -1 || ms->threads != -1 ||
+        ms->maxcpus != -1 || ms->cpus != -1) {
+        error_report("warning: cpu topology: "
+                     "machine properties currently ignored");
+    }
+}
+
 static void machine_pre_init(MachineState *ms)
 {
+    machine_set_smp_parameters(ms);
 }
 
 static void machine_class_init(ObjectClass *oc, void *data)
@@ -403,6 +460,11 @@ static void machine_initfn(Object *obj)
     ms->dump_guest_core = true;
     ms->mem_merge = true;
     ms->enable_graphics = true;
+    ms->sockets = -1;
+    ms->cores = -1;
+    ms->threads = -1;
+    ms->maxcpus = -1;
+    ms->cpus = -1;
 
     object_property_add_str(obj, "accel",
                             machine_get_accel, machine_set_accel, NULL);
@@ -462,6 +524,25 @@ static void machine_initfn(Object *obj)
     object_property_set_description(obj, "dt-compatible",
                                     "Overrides the \"compatible\" property of the dt root node",
                                     NULL);
+    object_property_add(obj, "sockets", "int", machine_get_smp,
+                        machine_set_smp, NULL, NULL, NULL);
+    object_property_set_description(obj, "sockets", "Number of sockets", NULL);
+    object_property_add(obj, "cores", "int", machine_get_smp,
+                        machine_set_smp, NULL, NULL, NULL);
+    object_property_set_description(obj, "cores",
+                                    "Number of cores per socket", NULL);
+    object_property_add(obj, "threads", "int", machine_get_smp,
+                        machine_set_smp, NULL, NULL, NULL);
+    object_property_set_description(obj, "threads",
+                                    "Number of threads per core", NULL);
+    object_property_add(obj, "maxcpus", "int", machine_get_smp,
+                        machine_set_smp, NULL, NULL, NULL);
+    object_property_set_description(obj, "maxcpus", "Maximum number of cpus",
+                                    NULL);
+    object_property_add(obj, "cpus", "int", machine_get_smp,
+                        machine_set_smp, NULL, NULL, NULL);
+    object_property_set_description(obj, "cpus", "Number of online cpus",
+                                    NULL);
     object_property_add_bool(obj, "dump-guest-core",
                              machine_get_dump_guest_core,
                              machine_set_dump_guest_core,
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 4e8dc68b07a24..53adbfe2a3099 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -166,6 +166,12 @@ struct MachineState {
     char *initrd_filename;
     const char *cpu_model;
     AccelState *accelerator;
+
+    int sockets;
+    int cores;
+    int threads;
+    int maxcpus;
+    int cpus;
 };
 
 #define DEFINE_MACHINE(namestr, machine_initfn) \
-- 
2.4.11

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

* [Qemu-devel] [PATCH RFC 06/16] vl: move smp parsing to machine pre_init
  2016-06-10 17:40 [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Andrew Jones
                   ` (4 preceding siblings ...)
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 05/16] hw/core/machine: add smp properites Andrew Jones
@ 2016-06-10 17:40 ` Andrew Jones
  2016-06-13 17:04   ` Paolo Bonzini
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties Andrew Jones
                   ` (12 subsequent siblings)
  18 siblings, 1 reply; 74+ messages in thread
From: Andrew Jones @ 2016-06-10 17:40 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, qemu-arm
  Cc: imammedo, ehabkost, pbonzini, peter.maydell, david, dgibson, agraf

Move the guts of smp_parse() into hw/core/machine.c to operate on
smp machine properties, and to eventually allow it to be overridden
by machines. We leave the smp_parse function behind to handle the
(now deprecated) -smp option, but now it only needs to set the
machine properties.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 hw/core/machine.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 vl.c              | 111 ++++++++++++++++-------------------------------------
 2 files changed, 142 insertions(+), 82 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 2625044002e57..75c5a1fdd7de1 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -17,6 +17,7 @@
 #include "qapi/visitor.h"
 #include "hw/sysbus.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/replay.h"
 #include "qemu/error-report.h"
 #include "qemu/cutils.h"
 
@@ -417,16 +418,122 @@ static void machine_init_notify(Notifier *notifier, void *data)
 
 static void machine_set_smp_parameters(MachineState *ms)
 {
-    if (ms->sockets != -1 || ms->cores != -1 || ms->threads != -1 ||
-        ms->maxcpus != -1 || ms->cpus != -1) {
+    int sockets = ms->sockets;
+    int cores   = ms->cores;
+    int threads = ms->threads;
+    int maxcpus = ms->maxcpus;
+    int cpus    = ms->cpus;
+    bool sockets_input = sockets > 0;
+
+    if (sockets == -1 && cores == -1 && threads == -1 &&
+        maxcpus == -1 && cpus == -1) {
+        ms->sockets = 1;
+        ms->cores   = 1;
+        ms->threads = 1;
+        ms->maxcpus = 1;
+        ms->cpus    = 1;
+        return;
+    }
+
+    if (sockets == -1 || cores == -1 || threads == -1 ||
+        maxcpus == -1 || cpus == -1) {
+        error_report("cpu topology: "
+                     "all machine properties must be specified");
+        exit(1);
+    }
+
+    /* If the deprecated -smp option was used without complete input,
+     * or a user input zeros (why would they do that?), then we compute
+     * missing values, preferring 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 (cpus == 0) {
+            cpus = cores * threads * sockets;
+        }
+    } else if (cores == 0) {
+        threads = threads > 0 ? threads : 1;
+        cores = cpus / (sockets * threads);
+    } else if (threads == 0) {
+        threads = cpus / (cores * sockets);
+    } else if (sockets * cores * threads < cpus) {
+        error_report("cpu topology: "
+                     "sockets (%u) * cores (%u) * threads (%u) < "
+                     "smp_cpus (%u)",
+                     sockets, cores, threads, cpus);
+        exit(1);
+    }
+
+    maxcpus = maxcpus > 0 ? maxcpus : cpus;
+
+    if (maxcpus > MAX_CPUMASK_BITS) {
+        error_report("unsupported number of maxcpus");
+        exit(1);
+    }
+
+    if (maxcpus < cpus) {
+        error_report("maxcpus must be equal to or greater than smp");
+        exit(1);
+    }
+
+    if (sockets * cores * threads > maxcpus) {
+        error_report("cpu topology: "
+                     "sockets (%u) * cores (%u) * threads (%u) > "
+                     "maxcpus (%u)",
+                     sockets, cores, threads, maxcpus);
+        exit(1);
+    }
+
+    if (sockets_input && sockets * cores * threads != maxcpus) {
+        unsigned sockets_rounded = DIV_ROUND_UP(maxcpus, cores * threads);
+
         error_report("warning: cpu topology: "
-                     "machine properties currently ignored");
+                     "sockets (%u) * cores (%u) * threads (%u) != "
+                     "maxcpus (%u). Trying sockets=%u.",
+                     sockets, cores, threads, maxcpus, sockets_rounded);
+        sockets = sockets_rounded;
+
+        if (sockets * cores * threads > maxcpus) {
+            error_report("cpu topology: "
+                         "sockets (%u) * cores (%u) * threads (%u) > "
+                         "maxcpus (%u)",
+                         sockets, cores, threads, maxcpus);
+            exit(1);
+        }
     }
+
+    ms->sockets = sockets;
+    ms->cores   = cores;
+    ms->threads = threads;
+    ms->maxcpus = maxcpus;
+    ms->cpus    = cpus;
 }
 
 static void machine_pre_init(MachineState *ms)
 {
+    MachineClass *mc = MACHINE_CLASS(object_get_class(OBJECT(ms)));
+
     machine_set_smp_parameters(ms);
+    smp_cores   = ms->cores;
+    smp_threads = ms->threads;
+    max_cpus    = ms->maxcpus;
+    smp_cpus    = ms->cpus;
+
+    mc->max_cpus = mc->max_cpus ?: 1; /* Default to UP */
+    if (ms->maxcpus > mc->max_cpus) {
+        error_report("Number of SMP CPUs requested (%d) exceeds max CPUs "
+                     "supported by machine '%s' (%d)", ms->maxcpus, mc->name,
+                     mc->max_cpus);
+        exit(1);
+    }
+
+    if (ms->cpus > 1) {
+        Error *blocker = NULL;
+        error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, "smp");
+        replay_add_blocker(blocker);
+    }
 }
 
 static void machine_class_init(ObjectClass *oc, void *data)
diff --git a/vl.c b/vl.c
index 4849dd465d667..843b7a9dff753 100644
--- a/vl.c
+++ b/vl.c
@@ -1222,81 +1222,41 @@ static QemuOptsList qemu_smp_opts = {
 
 static void smp_parse(QemuOpts *opts)
 {
-    if (opts) {
-        unsigned cpus    = qemu_opt_get_number(opts, "cpus", 0);
-        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 sockets_input = sockets > 0;
-
-        /* 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 (cpus == 0) {
-                cpus = cores * threads * sockets;
-            }
-        } else if (cores == 0) {
-            threads = threads > 0 ? threads : 1;
-            cores = cpus / (sockets * threads);
-        } else if (threads == 0) {
-            threads = cpus / (cores * sockets);
-        } else if (sockets * cores * threads < cpus) {
-            error_report("cpu topology: "
-                         "sockets (%u) * cores (%u) * threads (%u) < "
-                         "smp_cpus (%u)",
-                         sockets, cores, threads, cpus);
-            exit(1);
-        }
-
-        max_cpus = qemu_opt_get_number(opts, "maxcpus", cpus);
-
-        if (max_cpus > MAX_CPUMASK_BITS) {
-            error_report("unsupported number of maxcpus");
-            exit(1);
-        }
-
-        if (max_cpus < cpus) {
-            error_report("maxcpus must be equal to or greater than smp");
-            exit(1);
-        }
+    Object *machine_obj = OBJECT(current_machine);
+    int sockets, cores, threads, maxcpus, cpus;
 
-        if (sockets * cores * threads > max_cpus) {
-            error_report("cpu topology: "
-                         "sockets (%u) * cores (%u) * threads (%u) > "
-                         "maxcpus (%u)",
-                         sockets, cores, threads, max_cpus);
-            exit(1);
-        }
+    if (!opts) {
+        return;
+    }
 
-        if (sockets_input && sockets * cores * threads != max_cpus) {
-            unsigned sockets_rounded = DIV_ROUND_UP(max_cpus, cores * threads);
+    sockets = object_property_get_int(machine_obj, "sockets", NULL);
+    cores   = object_property_get_int(machine_obj, "cores",   NULL);
+    threads = object_property_get_int(machine_obj, "threads", NULL);
+    maxcpus = object_property_get_int(machine_obj, "maxcpus", NULL);
+    cpus    = object_property_get_int(machine_obj, "cpus",    NULL);
 
-            error_report("warning: cpu topology: "
-                         "sockets (%u) * cores (%u) * threads (%u) != "
-                         "maxcpus (%u). Trying sockets=%u.",
-                         sockets, cores, threads, max_cpus, sockets_rounded);
-            sockets = sockets_rounded;
+    if (sockets == -1 && cores == -1 && threads == -1 &&
+        maxcpus == -1 && cpus == -1) {
 
-            if (sockets * cores * threads > max_cpus) {
-                error_report("cpu topology: "
-                             "sockets (%u) * cores (%u) * threads (%u) > "
-                             "maxcpus (%u)",
-                             sockets, cores, threads, max_cpus);
-                exit(1);
-            }
-        }
+        error_report("warning: cpu topology: "
+                     "using deprecated -smp option. "
+                     "Use machine properties instead");
 
-        smp_cpus = cpus;
-        smp_cores = cores;
-        smp_threads = threads;
-    }
+        cpus    = qemu_opt_get_number(opts, "cpus",    0);
+        sockets = qemu_opt_get_number(opts, "sockets", 0);
+        cores   = qemu_opt_get_number(opts, "cores",   0);
+        threads = qemu_opt_get_number(opts, "threads", 0);
+        maxcpus = qemu_opt_get_number(opts, "maxcpus", cpus);
 
-    if (smp_cpus > 1) {
-        Error *blocker = NULL;
-        error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, "smp");
-        replay_add_blocker(blocker);
+        object_property_set_int(machine_obj, sockets, "sockets", NULL);
+        object_property_set_int(machine_obj, cores,   "cores",   NULL);
+        object_property_set_int(machine_obj, threads, "threads", NULL);
+        object_property_set_int(machine_obj, maxcpus, "maxcpus", NULL);
+        object_property_set_int(machine_obj, cpus,    "cpus",    NULL);
+    } else {
+        error_report("warning: cpu topology: "
+                     "both machine properties and -smp option provided. "
+                     "Ignoring the deprecated -smp option");
     }
 }
 
@@ -4106,16 +4066,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_class->max_cpus = machine_class->max_cpus ?: 1; /* Default to UP */
-    if (max_cpus > machine_class->max_cpus) {
-        error_report("Number of SMP CPUs requested (%d) exceeds max CPUs "
-                     "supported by machine '%s' (%d)", max_cpus,
-                     machine_class->name, machine_class->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.
@@ -4308,6 +4258,9 @@ int main(int argc, char **argv, char **envp)
         qtest_init(qtest_chrdev, qtest_log, &error_fatal);
     }
 
+    /* smp_parse must come after qemu_opt_foreach(machine_opts, ...) */
+    smp_parse(qemu_opts_find(qemu_find_opts("smp-opts"), NULL));
+
     machine_opts = qemu_get_machine_opts();
     kernel_filename = qemu_opt_get(machine_opts, "kernel");
     initrd_filename = qemu_opt_get(machine_opts, "initrd");
-- 
2.4.11

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

* [Qemu-devel] [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties
  2016-06-10 17:40 [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Andrew Jones
                   ` (5 preceding siblings ...)
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 06/16] vl: move smp parsing to machine pre_init Andrew Jones
@ 2016-06-10 17:40 ` Andrew Jones
  2016-06-11  6:54   ` Thomas Huth
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 08/16] hw/core/machine: set cpu global nr_cores, nr_threads in pre_init Andrew Jones
                   ` (11 subsequent siblings)
  18 siblings, 1 reply; 74+ messages in thread
From: Andrew Jones @ 2016-06-10 17:40 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, qemu-arm
  Cc: imammedo, ehabkost, pbonzini, peter.maydell, david, dgibson, agraf

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 qom/cpu.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/qom/cpu.c b/qom/cpu.c
index 751e992de8823..024cda3eb98c8 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -28,6 +28,7 @@
 #include "exec/log.h"
 #include "qemu/error-report.h"
 #include "sysemu/sysemu.h"
+#include "hw/qdev-properties.h"
 
 bool cpu_exists(int64_t id)
 {
@@ -342,6 +343,12 @@ static int64_t cpu_common_get_arch_id(CPUState *cpu)
     return cpu->cpu_index;
 }
 
+static Property cpu_common_properties[] = {
+    DEFINE_PROP_INT32("nr-cores", CPUState, nr_cores, 1),
+    DEFINE_PROP_INT32("nr-threads", CPUState, nr_threads, 1),
+    DEFINE_PROP_END_OF_LIST()
+};
+
 static void cpu_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -367,6 +374,7 @@ static void cpu_class_init(ObjectClass *klass, void *data)
     k->cpu_exec_exit = cpu_common_noop;
     k->cpu_exec_interrupt = cpu_common_exec_interrupt;
     dc->realize = cpu_common_realizefn;
+    dc->props = cpu_common_properties;
     /*
      * Reason: CPUs still need special care by board code: wiring up
      * IRQs, adding reset handlers, halting non-first CPUs, ...
-- 
2.4.11

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

* [Qemu-devel] [PATCH RFC 08/16] hw/core/machine: set cpu global nr_cores, nr_threads in pre_init
  2016-06-10 17:40 [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Andrew Jones
                   ` (6 preceding siblings ...)
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties Andrew Jones
@ 2016-06-10 17:40 ` Andrew Jones
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 09/16] hw/i386/pc: don't use smp_cores, smp_threads Andrew Jones
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 74+ messages in thread
From: Andrew Jones @ 2016-06-10 17:40 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, qemu-arm
  Cc: imammedo, ehabkost, pbonzini, peter.maydell, david, dgibson, agraf

CPUState nr_cores and nr_threads are properties so we can set
them using the GlobalProperty API. Doing this in machine pre_init
allows us to easily propagate the values from the machine properties
to all cpus. An excellent bonus of this is that we can now remove
the references to the cpu topology globals smp_cores,smp_threads
from cpus.c.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 cpus.c            |  2 --
 hw/core/machine.c | 18 ++++++++++++++++++
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/cpus.c b/cpus.c
index 326742f445eef..36d8faa0091c8 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1427,8 +1427,6 @@ static void qemu_dummy_start_vcpu(CPUState *cpu)
 
 void qemu_init_vcpu(CPUState *cpu)
 {
-    cpu->nr_cores = smp_cores;
-    cpu->nr_threads = smp_threads;
     cpu->stopped = true;
 
     if (!cpu->as) {
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 75c5a1fdd7de1..5427924d4c911 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -511,9 +511,22 @@ static void machine_set_smp_parameters(MachineState *ms)
     ms->cpus    = cpus;
 }
 
+#define NR_CPUS_STRLEN sizeof(stringify(MAX_CPUMASK_BITS))
+
 static void machine_pre_init(MachineState *ms)
 {
     MachineClass *mc = MACHINE_CLASS(object_get_class(OBJECT(ms)));
+    static char nr_cores[NR_CPUS_STRLEN], nr_threads[NR_CPUS_STRLEN];
+    static GlobalProperty cpu_nr_cores = {
+        .driver   = "cpu",
+        .property = "nr-cores",
+        .value    = nr_cores,
+    };
+    static GlobalProperty cpu_nr_threads = {
+        .driver   = "cpu",
+        .property = "nr-threads",
+        .value    = nr_threads,
+    };
 
     machine_set_smp_parameters(ms);
     smp_cores   = ms->cores;
@@ -529,6 +542,11 @@ static void machine_pre_init(MachineState *ms)
         exit(1);
     }
 
+    snprintf(nr_cores, NR_CPUS_STRLEN, "%d", ms->cores);
+    snprintf(nr_threads, NR_CPUS_STRLEN, "%d", ms->threads);
+    qdev_prop_register_global(&cpu_nr_cores);
+    qdev_prop_register_global(&cpu_nr_threads);
+
     if (ms->cpus > 1) {
         Error *blocker = NULL;
         error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, "smp");
-- 
2.4.11

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

* [Qemu-devel] [PATCH RFC 09/16] hw/i386/pc: don't use smp_cores, smp_threads
  2016-06-10 17:40 [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Andrew Jones
                   ` (7 preceding siblings ...)
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 08/16] hw/core/machine: set cpu global nr_cores, nr_threads in pre_init Andrew Jones
@ 2016-06-10 17:40 ` Andrew Jones
  2016-07-14 20:33   ` Eduardo Habkost
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 10/16] hw/ppc/spapr: " Andrew Jones
                   ` (9 subsequent siblings)
  18 siblings, 1 reply; 74+ messages in thread
From: Andrew Jones @ 2016-06-10 17:40 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, qemu-arm
  Cc: imammedo, ehabkost, pbonzini, peter.maydell, david, dgibson, agraf

Use CPUState nr_cores,nr_threads and MachineState
cores,threads instead.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 hw/i386/pc.c | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 7198ed533cc47..4fa86d6387ce9 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -27,7 +27,6 @@
 #include "hw/char/serial.h"
 #include "hw/i386/apic.h"
 #include "hw/i386/topology.h"
-#include "sysemu/cpus.h"
 #include "hw/block/fdc.h"
 #include "hw/ide.h"
 #include "hw/pci/pci.h"
@@ -682,12 +681,14 @@ void enable_compat_apic_id_mode(void)
  * no concept of "CPU index", and the NUMA tables on fw_cfg need the APIC ID of
  * all CPUs up to max_cpus.
  */
-static uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index)
+static uint32_t x86_cpu_apic_id_from_index(MachineState *ms,
+                                           unsigned int cpu_index)
 {
     uint32_t correct_id;
     static bool warned;
 
-    correct_id = x86_apicid_from_cpu_idx(smp_cores, smp_threads, cpu_index);
+    correct_id = x86_apicid_from_cpu_idx(ms->cores, ms->threads,
+                                         cpu_index);
     if (compat_apic_id_mode) {
         if (cpu_index != correct_id && !warned && !qtest_enabled()) {
             error_report("APIC IDs set in compatibility mode, "
@@ -778,7 +779,7 @@ static FWCfgState *bochs_bios_init(AddressSpace *as, PCMachineState *pcms)
     numa_fw_cfg = g_new0(uint64_t, 1 + pcms->apic_id_limit + nb_numa_nodes);
     numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes);
     for (i = 0; i < max_cpus; i++) {
-        unsigned int apic_id = x86_cpu_apic_id_from_index(i);
+        unsigned int apic_id = x86_cpu_apic_id_from_index(MACHINE(pcms), i);
         assert(apic_id < pcms->apic_id_limit);
         for (j = 0; j < nb_numa_nodes; j++) {
             if (test_bit(i, numa_info[j].node_cpu)) {
@@ -1066,7 +1067,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp)
 {
     X86CPU *cpu;
     MachineState *machine = MACHINE(qdev_get_machine());
-    int64_t apic_id = x86_cpu_apic_id_from_index(id);
+    int64_t apic_id = x86_cpu_apic_id_from_index(machine, id);
     Error *local_err = NULL;
 
     if (id < 0) {
@@ -1123,7 +1124,7 @@ void pc_cpus_init(PCMachineState *pcms)
      *
      * This is used for FW_CFG_MAX_CPUS. See comments on bochs_bios_init().
      */
-    pcms->apic_id_limit = x86_cpu_apic_id_from_index(max_cpus - 1) + 1;
+    pcms->apic_id_limit = x86_cpu_apic_id_from_index(machine, max_cpus - 1) + 1;
     if (pcms->apic_id_limit > ACPI_CPU_HOTPLUG_ID_LIMIT) {
         error_report("max_cpus is too large. APIC ID of last CPU is %u",
                      pcms->apic_id_limit - 1);
@@ -1133,10 +1134,12 @@ void pc_cpus_init(PCMachineState *pcms)
     pcms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
                                     sizeof(CPUArchId) * max_cpus);
     for (i = 0; i < max_cpus; i++) {
-        pcms->possible_cpus->cpus[i].arch_id = x86_cpu_apic_id_from_index(i);
+        pcms->possible_cpus->cpus[i].arch_id =
+                x86_cpu_apic_id_from_index(machine, i);
         pcms->possible_cpus->len++;
         if (i < smp_cpus) {
-            cpu = pc_new_cpu(machine->cpu_model, x86_cpu_apic_id_from_index(i),
+            cpu = pc_new_cpu(machine->cpu_model,
+                             x86_cpu_apic_id_from_index(machine, i),
                              &error_fatal);
             pcms->possible_cpus->cpus[i].cpu = CPU(cpu);
             object_unref(OBJECT(cpu));
@@ -1193,7 +1196,7 @@ void pc_guest_info_init(PCMachineState *pcms)
                                      sizeof *pcms->node_cpu);
 
     for (i = 0; i < max_cpus; i++) {
-        unsigned int apic_id = x86_cpu_apic_id_from_index(i);
+        unsigned int apic_id = x86_cpu_apic_id_from_index(MACHINE(pcms), i);
         assert(apic_id < pcms->apic_id_limit);
         for (j = 0; j < nb_numa_nodes; j++) {
             if (test_bit(i, numa_info[j].node_cpu)) {
@@ -1940,9 +1943,10 @@ static void pc_machine_reset(void)
 
 static unsigned pc_cpu_index_to_socket_id(unsigned cpu_index)
 {
+    CPUState *cs = first_cpu;
     X86CPUTopoInfo topo;
-    x86_topo_ids_from_idx(smp_cores, smp_threads, cpu_index,
-                          &topo);
+
+    x86_topo_ids_from_idx(cs->nr_cores, cs->nr_threads, cpu_index, &topo);
     return topo.pkg_id;
 }
 
-- 
2.4.11

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

* [Qemu-devel] [PATCH RFC 10/16] hw/ppc/spapr: don't use smp_cores, smp_threads
  2016-06-10 17:40 [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Andrew Jones
                   ` (8 preceding siblings ...)
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 09/16] hw/i386/pc: don't use smp_cores, smp_threads Andrew Jones
@ 2016-06-10 17:40 ` Andrew Jones
  2016-06-14  3:03   ` David Gibson
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 11/16] target-ppc: don't use smp_threads Andrew Jones
                   ` (8 subsequent siblings)
  18 siblings, 1 reply; 74+ messages in thread
From: Andrew Jones @ 2016-06-10 17:40 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, qemu-arm
  Cc: imammedo, ehabkost, pbonzini, peter.maydell, david, dgibson, agraf

Use CPUState nr_cores,nr_threads and MachineState
cores,threads instead.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 hw/ppc/spapr.c      | 9 +++++----
 hw/ppc/spapr_rtas.c | 2 +-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 063664234106e..f78276bb4b164 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -35,7 +35,6 @@
 #include "net/net.h"
 #include "sysemu/device_tree.h"
 #include "sysemu/block-backend.h"
-#include "sysemu/cpus.h"
 #include "sysemu/kvm.h"
 #include "sysemu/device_tree.h"
 #include "kvm_ppc.h"
@@ -603,7 +602,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
     uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 1000000000;
     uint32_t page_sizes_prop[64];
     size_t page_sizes_prop_size;
-    uint32_t vcpus_per_socket = smp_threads * smp_cores;
+    uint32_t vcpus_per_socket = cs->nr_cores * cs->nr_threads;
     uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)};
 
     /* Note: we keep CI large pages off for now because a 64K capable guest
@@ -1774,7 +1773,7 @@ static void ppc_spapr_init(MachineState *machine)
     /* Set up Interrupt Controller before we create the VCPUs */
     spapr->icp = xics_system_init(machine,
                                   DIV_ROUND_UP(max_cpus * kvmppc_smt_threads(),
-                                               smp_threads),
+                                               machine->threads),
                                   XICS_IRQS, &error_fatal);
 
     if (smc->dr_lmb_enabled) {
@@ -2268,9 +2267,11 @@ static HotplugHandler *spapr_get_hotpug_handler(MachineState *machine,
 
 static unsigned spapr_cpu_index_to_socket_id(unsigned cpu_index)
 {
+    CPUState *cs = first_cpu;
+
     /* Allocate to NUMA nodes on a "socket" basis (not that concept of
      * socket means much for the paravirtualized PAPR platform) */
-    return cpu_index / smp_threads / smp_cores;
+    return cpu_index / cs->nr_cores / cs->nr_threads;
 }
 
 static void spapr_machine_class_init(ObjectClass *oc, void *data)
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 43e2c684fda8d..3fdfbb01a20dd 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -742,7 +742,7 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
     lrdr_capacity[1] = cpu_to_be32(max_hotplug_addr & 0xffffffff);
     lrdr_capacity[2] = 0;
     lrdr_capacity[3] = cpu_to_be32(SPAPR_MEMORY_BLOCK_SIZE);
-    lrdr_capacity[4] = cpu_to_be32(max_cpus/smp_threads);
+    lrdr_capacity[4] = cpu_to_be32(max_cpus / machine->threads);
     ret = qemu_fdt_setprop(fdt, "/rtas", "ibm,lrdr-capacity", lrdr_capacity,
                      sizeof(lrdr_capacity));
     if (ret < 0) {
-- 
2.4.11

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

* [Qemu-devel] [PATCH RFC 11/16] target-ppc: don't use smp_threads
  2016-06-10 17:40 [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Andrew Jones
                   ` (9 preceding siblings ...)
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 10/16] hw/ppc/spapr: " Andrew Jones
@ 2016-06-10 17:40 ` Andrew Jones
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 12/16] hw/arm/virt: rename *.smp_cpus to *.cpus Andrew Jones
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 74+ messages in thread
From: Andrew Jones @ 2016-06-10 17:40 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, qemu-arm
  Cc: imammedo, ehabkost, pbonzini, peter.maydell, david, dgibson, agraf

Use CPUState nr_threads instead.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 target-ppc/translate_init.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index a1db5009c4a83..f442b2fc934d1 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -24,7 +24,6 @@
 #include <sysemu/kvm.h>
 #include "kvm_ppc.h"
 #include "sysemu/arch_init.h"
-#include "sysemu/cpus.h"
 #include "cpu-models.h"
 #include "mmu-hash32.h"
 #include "mmu-hash64.h"
@@ -9228,15 +9227,15 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
 #endif
 
 #if !defined(CONFIG_USER_ONLY)
-    if (smp_threads > max_smt) {
+    if (cs->nr_threads > max_smt) {
         error_setg(errp, "Cannot support more than %d threads on PPC with %s",
                    max_smt, kvm_enabled() ? "KVM" : "TCG");
         return;
     }
-    if (!is_power_of_2(smp_threads)) {
+    if (!is_power_of_2(cs->nr_threads)) {
         error_setg(errp, "Cannot support %d threads on PPC with %s, "
                    "threads count must be a power of 2.",
-                   smp_threads, kvm_enabled() ? "KVM" : "TCG");
+                   cs->nr_threads, kvm_enabled() ? "KVM" : "TCG");
         return;
     }
 #endif
@@ -9248,14 +9247,14 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
     }
 
 #if !defined(CONFIG_USER_ONLY)
-    cpu->cpu_dt_id = (cs->cpu_index / smp_threads) * max_smt
-        + (cs->cpu_index % smp_threads);
+    cpu->cpu_dt_id = (cs->cpu_index / cs->nr_threads) * max_smt
+        + (cs->cpu_index % cs->nr_threads);
 
     if (kvm_enabled() && !kvm_vcpu_id_is_valid(cpu->cpu_dt_id)) {
         error_setg(errp, "Can't create CPU with id %d in KVM", cpu->cpu_dt_id);
         error_append_hint(errp, "Adjust the number of cpus to %d "
                           "or try to raise the number of threads per core\n",
-                          cpu->cpu_dt_id * smp_threads / max_smt);
+                          cpu->cpu_dt_id * cs->nr_threads / max_smt);
         return;
     }
 #endif
@@ -9496,7 +9495,7 @@ static void ppc_cpu_unrealizefn(DeviceState *dev, Error **errp)
 
 int ppc_get_compat_smt_threads(PowerPCCPU *cpu)
 {
-    int ret = MIN(smp_threads, kvmppc_smt_threads());
+    int ret = MIN(CPU(cpu)->nr_threads, kvmppc_smt_threads());
 
     switch (cpu->cpu_version) {
     case CPU_POWERPC_LOGICAL_2_05:
-- 
2.4.11

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

* [Qemu-devel] [PATCH RFC 12/16] hw/arm/virt: rename *.smp_cpus to *.cpus
  2016-06-10 17:40 [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Andrew Jones
                   ` (10 preceding siblings ...)
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 11/16] target-ppc: don't use smp_threads Andrew Jones
@ 2016-06-10 17:40 ` Andrew Jones
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 13/16] hw/arm/virt: don't use smp_cpus, max_cpus Andrew Jones
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 74+ messages in thread
From: Andrew Jones @ 2016-06-10 17:40 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, qemu-arm
  Cc: imammedo, ehabkost, pbonzini, peter.maydell, david, dgibson, agraf

Use the name 'cpus' instead of 'smp_cpus' to be consistent with
MachineState.cpus. This also makes grepping for the global
smp_cpus easier.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 hw/arm/virt-acpi-build.c         | 14 +++++++-------
 hw/arm/virt.c                    | 14 +++++++-------
 include/hw/arm/virt-acpi-build.h |  2 +-
 3 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 735ab864a03dd..95dccb2e0c3fa 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -48,11 +48,11 @@
 #define ARM_SPI_BASE 32
 #define ACPI_POWER_BUTTON_DEVICE "PWRB"
 
-static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus)
+static void acpi_dsdt_add_cpus(Aml *scope, int nr_cpus)
 {
     uint16_t i;
 
-    for (i = 0; i < smp_cpus; i++) {
+    for (i = 0; i < nr_cpus; i++) {
         Aml *dev = aml_device("C%03x", i);
         aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0007")));
         aml_append(dev, aml_name_decl("_UID", aml_int(i)));
@@ -423,9 +423,9 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
     AcpiSratMemoryAffinity *numamem;
     int i, j, srat_start;
     uint64_t mem_base;
-    uint32_t *cpu_node = g_malloc0(guest_info->smp_cpus * sizeof(uint32_t));
+    uint32_t *cpu_node = g_malloc0(guest_info->cpus * sizeof(uint32_t));
 
-    for (i = 0; i < guest_info->smp_cpus; i++) {
+    for (i = 0; i < guest_info->cpus; i++) {
         for (j = 0; j < nb_numa_nodes; j++) {
             if (test_bit(i, numa_info[j].node_cpu)) {
                 cpu_node[i] = j;
@@ -438,7 +438,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
     srat = acpi_data_push(table_data, sizeof(*srat));
     srat->reserved1 = cpu_to_le32(1);
 
-    for (i = 0; i < guest_info->smp_cpus; ++i) {
+    for (i = 0; i < guest_info->cpus; ++i) {
         core = acpi_data_push(table_data, sizeof(*core));
         core->type = ACPI_SRAT_PROCESSOR_GICC;
         core->length = sizeof(*core);
@@ -524,7 +524,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
     gicd->length = sizeof(*gicd);
     gicd->base_address = memmap[VIRT_GIC_DIST].base;
 
-    for (i = 0; i < guest_info->smp_cpus; i++) {
+    for (i = 0; i < guest_info->cpus; i++) {
         AcpiMadtGenericInterrupt *gicc = acpi_data_push(table_data,
                                                      sizeof *gicc);
         ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i));
@@ -606,7 +606,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
      * the RTC ACPI device at all when using UEFI.
      */
     scope = aml_scope("\\_SB");
-    acpi_dsdt_add_cpus(scope, guest_info->smp_cpus);
+    acpi_dsdt_add_cpus(scope, guest_info->cpus);
     acpi_dsdt_add_uart(scope, &memmap[VIRT_UART],
                        (irqmap[VIRT_UART] + ARM_SPI_BASE));
     acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 73113cfc4d9c9..78d9aa996bafc 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -69,7 +69,7 @@ typedef struct VirtBoardInfo {
     const char *cpu_model;
     const MemMapEntry *memmap;
     const int *irqmap;
-    int smp_cpus;
+    int cpus;
     void *fdt;
     int fdt_size;
     uint32_t clock_phandle;
@@ -304,7 +304,7 @@ static void fdt_add_timer_nodes(const VirtBoardInfo *vbi, int gictype)
     if (gictype == 2) {
         irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
                              GIC_FDT_IRQ_PPI_CPU_WIDTH,
-                             (1 << vbi->smp_cpus) - 1);
+                             (1 << vbi->cpus) - 1);
     }
 
     qemu_fdt_add_subnode(vbi->fdt, "/timer");
@@ -345,7 +345,7 @@ static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
      *  The simplest way to go is to examine affinity IDs of all our CPUs. If
      *  at least one of them has Aff3 populated, we set #address-cells to 2.
      */
-    for (cpu = 0; cpu < vbi->smp_cpus; cpu++) {
+    for (cpu = 0; cpu < vbi->cpus; cpu++) {
         ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
 
         if (armcpu->mp_affinity & ARM_AFF3_MASK) {
@@ -358,7 +358,7 @@ static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
     qemu_fdt_setprop_cell(vbi->fdt, "/cpus", "#address-cells", addr_cells);
     qemu_fdt_setprop_cell(vbi->fdt, "/cpus", "#size-cells", 0x0);
 
-    for (cpu = vbi->smp_cpus - 1; cpu >= 0; cpu--) {
+    for (cpu = vbi->cpus - 1; cpu >= 0; cpu--) {
         char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
         ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
 
@@ -367,7 +367,7 @@ static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
         qemu_fdt_setprop_string(vbi->fdt, nodename, "compatible",
                                     armcpu->dtb_compatible);
 
-        if (vbi->using_psci && vbi->smp_cpus > 1) {
+        if (vbi->using_psci && vbi->cpus > 1) {
             qemu_fdt_setprop_string(vbi->fdt, nodename,
                                         "enable-method", "psci");
         }
@@ -1170,7 +1170,7 @@ static void machvirt_init(MachineState *machine)
         exit(1);
     }
 
-    vbi->smp_cpus = smp_cpus;
+    vbi->cpus = smp_cpus;
 
     if (machine->ram_size > vbi->memmap[VIRT_MEM].size) {
         error_report("mach-virt: cannot model more than %dGB RAM", RAMLIMIT_GB);
@@ -1281,7 +1281,7 @@ static void machvirt_init(MachineState *machine)
     create_fw_cfg(vbi, &address_space_memory);
     rom_set_fw(fw_cfg_find());
 
-    guest_info->smp_cpus = smp_cpus;
+    guest_info->cpus = smp_cpus;
     guest_info->fw_cfg = fw_cfg_find();
     guest_info->memmap = vbi->memmap;
     guest_info->irqmap = vbi->irqmap;
diff --git a/include/hw/arm/virt-acpi-build.h b/include/hw/arm/virt-acpi-build.h
index e43330ad659b0..d6c5982960403 100644
--- a/include/hw/arm/virt-acpi-build.h
+++ b/include/hw/arm/virt-acpi-build.h
@@ -27,7 +27,7 @@
 #define ACPI_GICC_ENABLED 1
 
 typedef struct VirtGuestInfo {
-    int smp_cpus;
+    int cpus;
     FWCfgState *fw_cfg;
     const MemMapEntry *memmap;
     const int *irqmap;
-- 
2.4.11

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

* [Qemu-devel] [PATCH RFC 13/16] hw/arm/virt: don't use smp_cpus, max_cpus
  2016-06-10 17:40 [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Andrew Jones
                   ` (11 preceding siblings ...)
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 12/16] hw/arm/virt: rename *.smp_cpus to *.cpus Andrew Jones
@ 2016-06-10 17:40 ` Andrew Jones
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 14/16] hw/arm/virt: stash cpu topo info in VirtGuestInfo Andrew Jones
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 74+ messages in thread
From: Andrew Jones @ 2016-06-10 17:40 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, qemu-arm
  Cc: imammedo, ehabkost, pbonzini, peter.maydell, david, dgibson, agraf

Use MachineState.cpus or own copy from VirtBoardInfo.cpus instead.

(Congratulations mach-virt, you're the first machine type to be
 cpu topology globals free!)

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 hw/arm/virt.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 78d9aa996bafc..134b6e36623ba 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -467,7 +467,7 @@ static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic, int type, bool secure)
 
     gicdev = qdev_create(NULL, gictype);
     qdev_prop_set_uint32(gicdev, "revision", type);
-    qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);
+    qdev_prop_set_uint32(gicdev, "num-cpu", vbi->cpus);
     /* Note that the num-irq property counts both internal and external
      * interrupts; there are always 32 of the former (mandated by GIC spec).
      */
@@ -488,7 +488,7 @@ static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic, int type, bool secure)
      * appropriate GIC PPI inputs, and the GIC's IRQ output to
      * the CPU's IRQ input.
      */
-    for (i = 0; i < smp_cpus; i++) {
+    for (i = 0; i < vbi->cpus; i++) {
         DeviceState *cpudev = DEVICE(qemu_get_cpu(i));
         int ppibase = NUM_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
         int irq;
@@ -509,7 +509,7 @@ static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic, int type, bool secure)
         }
 
         sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
-        sysbus_connect_irq(gicbusdev, i + smp_cpus,
+        sysbus_connect_irq(gicbusdev, i + vbi->cpus,
                            qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
     }
 
@@ -1163,14 +1163,14 @@ static void machvirt_init(MachineState *machine)
         virt_max_cpus = GIC_NCPU;
     }
 
-    if (max_cpus > virt_max_cpus) {
+    if (machine->maxcpus > virt_max_cpus) {
         error_report("Number of SMP CPUs requested (%d) exceeds max CPUs "
                      "supported by machine 'mach-virt' (%d)",
-                     max_cpus, virt_max_cpus);
+                     machine->maxcpus, virt_max_cpus);
         exit(1);
     }
 
-    vbi->cpus = smp_cpus;
+    vbi->cpus = machine->cpus;
 
     if (machine->ram_size > vbi->memmap[VIRT_MEM].size) {
         error_report("mach-virt: cannot model more than %dGB RAM", RAMLIMIT_GB);
@@ -1196,7 +1196,7 @@ static void machvirt_init(MachineState *machine)
 
     create_fdt(vbi);
 
-    for (n = 0; n < smp_cpus; n++) {
+    for (n = 0; n < vbi->cpus; n++) {
         ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]);
         CPUClass *cc = CPU_CLASS(oc);
         Object *cpuobj;
@@ -1281,7 +1281,7 @@ static void machvirt_init(MachineState *machine)
     create_fw_cfg(vbi, &address_space_memory);
     rom_set_fw(fw_cfg_find());
 
-    guest_info->cpus = smp_cpus;
+    guest_info->cpus = vbi->cpus;
     guest_info->fw_cfg = fw_cfg_find();
     guest_info->memmap = vbi->memmap;
     guest_info->irqmap = vbi->irqmap;
@@ -1294,7 +1294,7 @@ static void machvirt_init(MachineState *machine)
     vbi->bootinfo.kernel_filename = machine->kernel_filename;
     vbi->bootinfo.kernel_cmdline = machine->kernel_cmdline;
     vbi->bootinfo.initrd_filename = machine->initrd_filename;
-    vbi->bootinfo.nb_cpus = smp_cpus;
+    vbi->bootinfo.nb_cpus = vbi->cpus;
     vbi->bootinfo.board_id = -1;
     vbi->bootinfo.loader_start = vbi->memmap[VIRT_MEM].base;
     vbi->bootinfo.get_dtb = machvirt_dtb;
-- 
2.4.11

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

* [Qemu-devel] [PATCH RFC 14/16] hw/arm/virt: stash cpu topo info in VirtGuestInfo
  2016-06-10 17:40 [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Andrew Jones
                   ` (12 preceding siblings ...)
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 13/16] hw/arm/virt: don't use smp_cpus, max_cpus Andrew Jones
@ 2016-06-10 17:40 ` Andrew Jones
  2016-07-14 20:43   ` Eduardo Habkost
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 15/16] smbios: don't use smp_cores, smp_threads Andrew Jones
                   ` (4 subsequent siblings)
  18 siblings, 1 reply; 74+ messages in thread
From: Andrew Jones @ 2016-06-10 17:40 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, qemu-arm
  Cc: imammedo, ehabkost, pbonzini, peter.maydell, david, dgibson, agraf

This is a first step to preparing mach-virt for configurable
cpu topology, and is necessary now to prepare to move smbios
code away from using cpu topology globals smp_cores,smp_threads.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 hw/arm/virt.c                    | 6 +++++-
 include/hw/arm/virt-acpi-build.h | 4 ++++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 134b6e36623ba..769a49aa5be77 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1281,7 +1281,11 @@ static void machvirt_init(MachineState *machine)
     create_fw_cfg(vbi, &address_space_memory);
     rom_set_fw(fw_cfg_find());
 
-    guest_info->cpus = vbi->cpus;
+    guest_info->sockets = machine->sockets;
+    guest_info->cores   = machine->cores;
+    guest_info->threads = machine->threads;
+    guest_info->maxcpus = machine->maxcpus;
+    guest_info->cpus    = machine->cpus;
     guest_info->fw_cfg = fw_cfg_find();
     guest_info->memmap = vbi->memmap;
     guest_info->irqmap = vbi->irqmap;
diff --git a/include/hw/arm/virt-acpi-build.h b/include/hw/arm/virt-acpi-build.h
index d6c5982960403..a34fb04230e66 100644
--- a/include/hw/arm/virt-acpi-build.h
+++ b/include/hw/arm/virt-acpi-build.h
@@ -27,6 +27,10 @@
 #define ACPI_GICC_ENABLED 1
 
 typedef struct VirtGuestInfo {
+    int sockets;
+    int cores;
+    int threads;
+    int maxcpus;
     int cpus;
     FWCfgState *fw_cfg;
     const MemMapEntry *memmap;
-- 
2.4.11

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

* [Qemu-devel] [PATCH RFC 15/16] smbios: don't use smp_cores, smp_threads
  2016-06-10 17:40 [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Andrew Jones
                   ` (13 preceding siblings ...)
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 14/16] hw/arm/virt: stash cpu topo info in VirtGuestInfo Andrew Jones
@ 2016-06-10 17:40 ` Andrew Jones
  2016-07-14 20:51   ` Eduardo Habkost
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 16/16] sysemu/cpus: bye, bye " Andrew Jones
                   ` (3 subsequent siblings)
  18 siblings, 1 reply; 74+ messages in thread
From: Andrew Jones @ 2016-06-10 17:40 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, qemu-arm
  Cc: imammedo, ehabkost, pbonzini, peter.maydell, david, dgibson, agraf

SMBIOS needs cpu topology for Type4 tables, so we need to pass
it in. There are several parameters so we use a structure. There
are two callers (of non-legacy, which generates Type4 tables),
x86 and arm, so we also update both to pass the topology
parameters from their MachineState properties (directly in the
case of x86, indirectly through VirtGuestInfo in the case of arm).

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 hw/arm/virt.c              |  9 ++++++++-
 hw/i386/pc.c               | 13 ++++++++++---
 hw/smbios/smbios.c         | 20 +++++++++++---------
 include/hw/smbios/smbios.h | 10 ++++++++++
 4 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 769a49aa5be77..4482fab91c139 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1067,6 +1067,13 @@ static void virt_build_smbios(VirtGuestInfo *guest_info)
     uint8_t *smbios_tables, *smbios_anchor;
     size_t smbios_tables_len, smbios_anchor_len;
     const char *product = "QEMU Virtual Machine";
+    struct smbios_cpu_topology topo = {
+        .sockets = guest_info->sockets,
+        .cores   = guest_info->cores,
+        .threads = guest_info->threads,
+        .maxcpus = guest_info->maxcpus,
+        .cpus    = guest_info->cpus,
+    };
 
     if (!fw_cfg) {
         return;
@@ -1079,7 +1086,7 @@ static void virt_build_smbios(VirtGuestInfo *guest_info)
     smbios_set_defaults("QEMU", product,
                         "1.0", false, true, SMBIOS_ENTRY_POINT_30);
 
-    smbios_get_tables(NULL, 0, &smbios_tables, &smbios_tables_len,
+    smbios_get_tables(NULL, 0, &topo, &smbios_tables, &smbios_tables_len,
                       &smbios_anchor, &smbios_anchor_len);
 
     if (smbios_anchor) {
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 4fa86d6387ce9..afea1a535a653 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -701,12 +701,19 @@ static uint32_t x86_cpu_apic_id_from_index(MachineState *ms,
     }
 }
 
-static void pc_build_smbios(FWCfgState *fw_cfg)
+static void pc_build_smbios(MachineState *ms, FWCfgState *fw_cfg)
 {
     uint8_t *smbios_tables, *smbios_anchor;
     size_t smbios_tables_len, smbios_anchor_len;
     struct smbios_phys_mem_area *mem_array;
     unsigned i, array_count;
+    struct smbios_cpu_topology topo = {
+        .sockets = ms->sockets,
+        .cores   = ms->cores,
+        .threads = ms->threads,
+        .maxcpus = ms->maxcpus,
+        .cpus    = ms->cpus,
+    };
 
     smbios_tables = smbios_get_table_legacy(&smbios_tables_len);
     if (smbios_tables) {
@@ -725,7 +732,7 @@ static void pc_build_smbios(FWCfgState *fw_cfg)
             array_count++;
         }
     }
-    smbios_get_tables(mem_array, array_count,
+    smbios_get_tables(mem_array, array_count, &topo,
                       &smbios_tables, &smbios_tables_len,
                       &smbios_anchor, &smbios_anchor_len);
     g_free(mem_array);
@@ -1176,7 +1183,7 @@ void pc_machine_done(Notifier *notifier, void *data)
 
     acpi_setup();
     if (pcms->fw_cfg) {
-        pc_build_smbios(pcms->fw_cfg);
+        pc_build_smbios(MACHINE(pcms), pcms->fw_cfg);
     }
 }
 
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index cf18ecfd8599c..99b5f984b945a 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -20,7 +20,6 @@
 #include "qemu/config-file.h"
 #include "qemu/error-report.h"
 #include "sysemu/sysemu.h"
-#include "sysemu/cpus.h"
 #include "hw/smbios/smbios.h"
 #include "hw/loader.h"
 #include "exec/cpu-common.h"
@@ -64,7 +63,9 @@ static SmbiosEntryPoint ep;
 static int smbios_type4_count = 0;
 static bool smbios_immutable;
 static bool smbios_have_defaults;
-static uint32_t smbios_cpuid_version, smbios_cpuid_features, smbios_smp_sockets;
+static uint32_t smbios_cpuid_version, smbios_cpuid_features;
+
+static struct smbios_cpu_topology smbios_cpu_topology;
 
 static DECLARE_BITMAP(have_binfile_bitmap, SMBIOS_MAX_TYPE+1);
 static DECLARE_BITMAP(have_fields_bitmap, SMBIOS_MAX_TYPE+1);
@@ -325,7 +326,8 @@ opts_init(smbios_register_config);
 
 static void smbios_validate_table(void)
 {
-    uint32_t expect_t4_count = smbios_legacy ? smp_cpus : smbios_smp_sockets;
+    uint32_t expect_t4_count = smbios_legacy ? smp_cpus
+                                             : smbios_cpu_topology.sockets;
 
     if (smbios_type4_count && smbios_type4_count != expect_t4_count) {
         error_report("Expected %d SMBIOS Type 4 tables, got %d instead",
@@ -637,8 +639,8 @@ static void smbios_build_type_4_table(unsigned instance)
     SMBIOS_TABLE_SET_STR(4, serial_number_str, type4.serial);
     SMBIOS_TABLE_SET_STR(4, asset_tag_number_str, type4.asset);
     SMBIOS_TABLE_SET_STR(4, part_number_str, type4.part);
-    t->core_count = t->core_enabled = smp_cores;
-    t->thread_count = smp_threads;
+    t->core_count = t->core_enabled = smbios_cpu_topology.cores;
+    t->thread_count = smbios_cpu_topology.threads;
     t->processor_characteristics = cpu_to_le16(0x02); /* Unknown */
     t->processor_family2 = cpu_to_le16(0x01); /* Other */
 
@@ -864,6 +866,7 @@ static void smbios_entry_point_setup(void)
 
 void smbios_get_tables(const struct smbios_phys_mem_area *mem_array,
                        const unsigned int mem_array_size,
+                       const struct smbios_cpu_topology *topo,
                        uint8_t **tables, size_t *tables_len,
                        uint8_t **anchor, size_t *anchor_len)
 {
@@ -875,16 +878,15 @@ void smbios_get_tables(const struct smbios_phys_mem_area *mem_array,
         return;
     }
 
+    smbios_cpu_topology = *topo;
+
     if (!smbios_immutable) {
         smbios_build_type_0_table();
         smbios_build_type_1_table();
         smbios_build_type_2_table();
         smbios_build_type_3_table();
 
-        smbios_smp_sockets = DIV_ROUND_UP(max_cpus, smp_cores * smp_threads);
-        assert(smbios_smp_sockets >= 1);
-
-        for (i = 0; i < smbios_smp_sockets; i++) {
+        for (i = 0; i < smbios_cpu_topology.sockets; i++) {
             smbios_build_type_4_table(i);
         }
 
diff --git a/include/hw/smbios/smbios.h b/include/hw/smbios/smbios.h
index ba3674609edf4..64f41ee9e2605 100644
--- a/include/hw/smbios/smbios.h
+++ b/include/hw/smbios/smbios.h
@@ -23,6 +23,15 @@ struct smbios_phys_mem_area {
     uint64_t length;
 };
 
+/* cpu topology, used by type 4 table */
+struct smbios_cpu_topology {
+    int sockets;
+    int cores;
+    int threads;
+    int maxcpus;
+    int cpus;
+};
+
 /*
  * SMBIOS spec defined tables
  */
@@ -264,6 +273,7 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
 uint8_t *smbios_get_table_legacy(size_t *length);
 void smbios_get_tables(const struct smbios_phys_mem_area *mem_array,
                        const unsigned int mem_array_size,
+                       const struct smbios_cpu_topology *topo,
                        uint8_t **tables, size_t *tables_len,
                        uint8_t **anchor, size_t *anchor_len);
 #endif /*QEMU_SMBIOS_H */
-- 
2.4.11

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

* [Qemu-devel] [PATCH RFC 16/16] sysemu/cpus: bye, bye smp_cores, smp_threads
  2016-06-10 17:40 [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Andrew Jones
                   ` (14 preceding siblings ...)
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 15/16] smbios: don't use smp_cores, smp_threads Andrew Jones
@ 2016-06-10 17:40 ` Andrew Jones
  2016-06-11  6:42 ` [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Thomas Huth
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 74+ messages in thread
From: Andrew Jones @ 2016-06-10 17:40 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, qemu-arm
  Cc: imammedo, ehabkost, pbonzini, peter.maydell, david, dgibson, agraf

The smp_cores and smp_threads globals are no longer used.
Vanish them.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 hw/core/machine.c     |  2 --
 include/sysemu/cpus.h | 10 ----------
 vl.c                  |  2 --
 3 files changed, 14 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 5427924d4c911..fdd28e5786685 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -529,8 +529,6 @@ static void machine_pre_init(MachineState *ms)
     };
 
     machine_set_smp_parameters(ms);
-    smp_cores   = ms->cores;
-    smp_threads = ms->threads;
     max_cpus    = ms->maxcpus;
     smp_cpus    = ms->cpus;
 
diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h
index fe992a8946ed5..d3e19ca214564 100644
--- a/include/sysemu/cpus.h
+++ b/include/sysemu/cpus.h
@@ -27,16 +27,6 @@ void cpu_synchronize_all_post_init(void);
 
 void qtest_clock_warp(int64_t dest);
 
-#ifndef CONFIG_USER_ONLY
-/* vl.c */
-extern int smp_cores;
-extern int smp_threads;
-#else
-/* *-user doesn't have configurable SMP topology */
-#define smp_cores   1
-#define smp_threads 1
-#endif
-
 void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg);
 
 #endif
diff --git a/vl.c b/vl.c
index 843b7a9dff753..e73c66364932c 100644
--- a/vl.c
+++ b/vl.c
@@ -155,8 +155,6 @@ int win2k_install_hack = 0;
 int singlestep = 0;
 int smp_cpus = 1;
 int max_cpus = 1;
-int smp_cores = 1;
-int smp_threads = 1;
 int acpi_enabled = 1;
 int no_hpet = 0;
 int fd_bootchk = 1;
-- 
2.4.11

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

* Re: [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters
  2016-06-10 17:40 [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Andrew Jones
                   ` (15 preceding siblings ...)
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 16/16] sysemu/cpus: bye, bye " Andrew Jones
@ 2016-06-11  6:42 ` Thomas Huth
  2016-06-12 13:58   ` Andrew Jones
  2016-06-12 14:03 ` Andrew Jones
  2016-07-14  9:16 ` Andrew Jones
  18 siblings, 1 reply; 74+ messages in thread
From: Thomas Huth @ 2016-06-11  6:42 UTC (permalink / raw)
  To: Andrew Jones, qemu-devel, qemu-ppc, qemu-arm
  Cc: peter.maydell, ehabkost, agraf, pbonzini, dgibson, imammedo, david

On 10.06.2016 19:40, Andrew Jones wrote:
> This series is a first step in eliminating smp_* global
> variables (the last patch gets rid of two of them!) And, it's
> a first step in deprecating '-smp' in favor of using machine
> properties, e.g.
>  qemu -machine pc,sockets=2,cores=2,threads=2,maxcpus=8,cpus=8 ...

Why isn't '-smp' good enough anymore so that it got to be deprecated?

 Thomas

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

* Re: [Qemu-devel] [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties Andrew Jones
@ 2016-06-11  6:54   ` Thomas Huth
  2016-06-12 13:48     ` Andrew Jones
  0 siblings, 1 reply; 74+ messages in thread
From: Thomas Huth @ 2016-06-11  6:54 UTC (permalink / raw)
  To: Andrew Jones, qemu-devel, qemu-ppc, qemu-arm
  Cc: peter.maydell, ehabkost, agraf, pbonzini, dgibson, imammedo,
	david, Bharata B Rao

On 10.06.2016 19:40, Andrew Jones wrote:
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> ---
>  qom/cpu.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/qom/cpu.c b/qom/cpu.c
> index 751e992de8823..024cda3eb98c8 100644
> --- a/qom/cpu.c
> +++ b/qom/cpu.c
> @@ -28,6 +28,7 @@
>  #include "exec/log.h"
>  #include "qemu/error-report.h"
>  #include "sysemu/sysemu.h"
> +#include "hw/qdev-properties.h"
>  
>  bool cpu_exists(int64_t id)
>  {
> @@ -342,6 +343,12 @@ static int64_t cpu_common_get_arch_id(CPUState *cpu)
>      return cpu->cpu_index;
>  }
>  
> +static Property cpu_common_properties[] = {
> +    DEFINE_PROP_INT32("nr-cores", CPUState, nr_cores, 1),
> +    DEFINE_PROP_INT32("nr-threads", CPUState, nr_threads, 1),
> +    DEFINE_PROP_END_OF_LIST()
> +};

Are you aware of the current CPU hotplug discussion that is going on?
I'm not very involved there, but I think some of these reworks also move
"nr_threads" into the CPU state already, e.g. see:

https://github.com/dgibson/qemu/commit/9d07719784ecbeebea71

... so you might want to check these patches first to see whether you
can base your rework on them?

 Thomas

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

* Re: [Qemu-devel] [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties
  2016-06-11  6:54   ` Thomas Huth
@ 2016-06-12 13:48     ` Andrew Jones
  2016-06-14  2:12       ` David Gibson
  0 siblings, 1 reply; 74+ messages in thread
From: Andrew Jones @ 2016-06-12 13:48 UTC (permalink / raw)
  To: Thomas Huth
  Cc: qemu-devel, qemu-ppc, qemu-arm, peter.maydell, ehabkost,
	Bharata B Rao, agraf, pbonzini, imammedo, dgibson, david

On Sat, Jun 11, 2016 at 08:54:35AM +0200, Thomas Huth wrote:
> On 10.06.2016 19:40, Andrew Jones wrote:
> > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > ---
> >  qom/cpu.c | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> > 
> > diff --git a/qom/cpu.c b/qom/cpu.c
> > index 751e992de8823..024cda3eb98c8 100644
> > --- a/qom/cpu.c
> > +++ b/qom/cpu.c
> > @@ -28,6 +28,7 @@
> >  #include "exec/log.h"
> >  #include "qemu/error-report.h"
> >  #include "sysemu/sysemu.h"
> > +#include "hw/qdev-properties.h"
> >  
> >  bool cpu_exists(int64_t id)
> >  {
> > @@ -342,6 +343,12 @@ static int64_t cpu_common_get_arch_id(CPUState *cpu)
> >      return cpu->cpu_index;
> >  }
> >  
> > +static Property cpu_common_properties[] = {
> > +    DEFINE_PROP_INT32("nr-cores", CPUState, nr_cores, 1),
> > +    DEFINE_PROP_INT32("nr-threads", CPUState, nr_threads, 1),
> > +    DEFINE_PROP_END_OF_LIST()
> > +};
> 
> Are you aware of the current CPU hotplug discussion that is going on?

I'm aware of it going on, but haven't been following it.

> I'm not very involved there, but I think some of these reworks also move
> "nr_threads" into the CPU state already, e.g. see:

nr_threads (and nr_cores) are already state in CPUState. This patch just
exposes that state via properties.

> 
> https://github.com/dgibson/qemu/commit/9d07719784ecbeebea71
> 
> ... so you might want to check these patches first to see whether you
> can base your rework on them?

Every cpu, and thus every machine, uses CPUState for its cpus. I'm
not sure every machine will want to use that new abstract core class
though. If they did, then we could indeed use nr_threads from there
instead (and remove it from CPUState), but we'd still need nr_cores
from the abstract cpu package class (CPUState).

Thanks,
drew

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

* Re: [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters
  2016-06-11  6:42 ` [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Thomas Huth
@ 2016-06-12 13:58   ` Andrew Jones
  0 siblings, 0 replies; 74+ messages in thread
From: Andrew Jones @ 2016-06-12 13:58 UTC (permalink / raw)
  To: Thomas Huth
  Cc: qemu-devel, qemu-ppc, qemu-arm, peter.maydell, ehabkost, agraf,
	pbonzini, imammedo, dgibson, david

On Sat, Jun 11, 2016 at 08:42:14AM +0200, Thomas Huth wrote:
> On 10.06.2016 19:40, Andrew Jones wrote:
> > This series is a first step in eliminating smp_* global
> > variables (the last patch gets rid of two of them!) And, it's
> > a first step in deprecating '-smp' in favor of using machine
> > properties, e.g.
> >  qemu -machine pc,sockets=2,cores=2,threads=2,maxcpus=8,cpus=8 ...
> 
> Why isn't '-smp' good enough anymore so that it got to be deprecated?
>

cpu topology is machine state, and the QEMU style of providing state
values for objects is through properties. So adding properties brings
cpu topology descriptions more in line. Keeping a redundant (not "in
line") command line option could confuse things.

Also, switching how the command line is used provides a clean breaking
point. -smp assumes values when none are provided. This can lead to
unexpected results for some machines. Rather than trying to code every
assumption possible, it's easier to just require all properties be
specified. Machines are still free to provide short-hand properties to
get defaults, if the 45 character collection of properties is too
annoying to use all the time (I agree that it may be).

Thanks,
drew

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

* Re: [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters
  2016-06-10 17:40 [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Andrew Jones
                   ` (16 preceding siblings ...)
  2016-06-11  6:42 ` [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Thomas Huth
@ 2016-06-12 14:03 ` Andrew Jones
  2016-07-14  9:16 ` Andrew Jones
  18 siblings, 0 replies; 74+ messages in thread
From: Andrew Jones @ 2016-06-12 14:03 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, qemu-arm
  Cc: peter.maydell, ehabkost, agraf, pbonzini, dgibson, imammedo, david

On Fri, Jun 10, 2016 at 07:40:11PM +0200, Andrew Jones wrote:
> This series is a first step in eliminating smp_* global
> variables (the last patch gets rid of two of them!) And, it's
> a first step in deprecating '-smp' in favor of using machine
> properties, e.g.
>  qemu -machine pc,sockets=2,cores=2,threads=2,maxcpus=8,cpus=8 ...
> 
> It's also a first step in allowing machine types to override
> the default parameter parsing, which makes assumptions that
> not all machine types may agree with. (mach-virt is coming...)
> 
> So, three first steps, I guess that's 3 steps. And a forth
> thing it does is some fixes for the smp parsing and also for
> SMBIOS use of cpu topology.
> 
> Tested with kvm-unit-tests on all five arches supported
> there, x86_64 both with KVM and TCG, and booting an x86_64
> guest (KVM) to check SMBIOS before and after in order to make
> sure it was the same. Also compile tested all targets.

I forgot to run 'make check'. Just did now. All but one test
passed. Nope, it wasn't pc-cpu-test (the only cpu topology
using test) that failed. That one did output two new warnings,
so I should fix and/or deprecate it. The one that did fail was
vhost-user-test. I confirmed that it does not fail without this
series. I'll look into it soon, maybe tomorrow.

drew

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

* Re: [Qemu-devel] [PATCH RFC 06/16] vl: move smp parsing to machine pre_init
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 06/16] vl: move smp parsing to machine pre_init Andrew Jones
@ 2016-06-13 17:04   ` Paolo Bonzini
  2016-06-13 20:35     ` Andrew Jones
  0 siblings, 1 reply; 74+ messages in thread
From: Paolo Bonzini @ 2016-06-13 17:04 UTC (permalink / raw)
  To: Andrew Jones, qemu-devel, qemu-ppc, qemu-arm
  Cc: imammedo, ehabkost, peter.maydell, david, dgibson, agraf



On 10/06/2016 19:40, Andrew Jones wrote:
> +    if (sockets == -1 || cores == -1 || threads == -1 ||
> +        maxcpus == -1 || cpus == -1) {
> +        error_report("cpu topology: "
> +                     "all machine properties must be specified");
> +        exit(1);
> +    }
> +

I think it's sane to accept some defaults.  It must not be the DWIM
thing that -smp does (which is targeted to Windows's dislike of
multi-socket machine on consumer hardware).  It must be something that
makes sense, and my proposal is:

- threads: 1
- cores: 1
- sockets:
  - maxcpus / (cores * threads) if maxcpus given
  - cpus / (cores * threads) if cpus given
  - else 1
- maxcpus: cores * threads * sockets
- cpus: maxcpus

This is a simple, linear logic that assigns defaults to each argument in
sequence.  At the same time -machine should fail for all invalid
combinations, namely:

- any argument < 1
- any argument > some compile-time value (1024?) to avoid overflows
- cpus % (cores * threads) != 0
- cpus > sockets * cores * threads
- maxcpus != cores * threads * sockets

Alone the last relation shows that requiring all four of maxcpus, cores,
threads and sockets is unnecessary. :)

This will catch situations where assigning a default for sockets doesn't
work well.  For example cores=2,cpus=4,maxcpus=5 will assign
threads=1,sockets=2; then the last relation will fail and QEMU will give
an error.

These invalid combination also make sure that other useful default cases
work.  For example "maxcpus given, sockets and cpus not" works thanks to
the following deduction:

- sockets = cpus/(cores*threads)
- maxcpus = cores*threads*sockets
- because cpus%(cores*threads) must be 0, this gives maxcpus=cpus

-smp should do its legacy magic and assign all five values based on it.
If the results do not match the obvious s/smp/-machine/ command line it
should warn, and perhaps suggest the equivalent -machine command line.
It doesn't have to be a minimal command line, just equivalent.

Apart from this point, these are lovely patches. :)

Paolo

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

* Re: [Qemu-devel] [PATCH RFC 06/16] vl: move smp parsing to machine pre_init
  2016-06-13 17:04   ` Paolo Bonzini
@ 2016-06-13 20:35     ` Andrew Jones
  2016-06-14  8:17       ` Paolo Bonzini
  0 siblings, 1 reply; 74+ messages in thread
From: Andrew Jones @ 2016-06-13 20:35 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: qemu-devel, qemu-ppc, qemu-arm, peter.maydell, ehabkost, agraf,
	dgibson, imammedo, david

On Mon, Jun 13, 2016 at 07:04:01PM +0200, Paolo Bonzini wrote:
> 
> 
> On 10/06/2016 19:40, Andrew Jones wrote:
> > +    if (sockets == -1 || cores == -1 || threads == -1 ||
> > +        maxcpus == -1 || cpus == -1) {
> > +        error_report("cpu topology: "
> > +                     "all machine properties must be specified");
> > +        exit(1);
> > +    }
> > +
> 
> I think it's sane to accept some defaults.  It must not be the DWIM

I agree requiring all these properties means a lot of typing, but I'm
not sure we want to calculate defaults. Reasoning below

> thing that -smp does (which is targeted to Windows's dislike of
> multi-socket machine on consumer hardware).  It must be something that
> makes sense, and my proposal is:
> 
> - threads: 1
> - cores: 1
> - sockets:
>   - maxcpus / (cores * threads) if maxcpus given
>   - cpus / (cores * threads) if cpus given
>   - else 1
> - maxcpus: cores * threads * sockets
> - cpus: maxcpus

I think some machines may prefer

- threads: 1
- sockets: 1
- cores:
  - maxcpus / (sockets * threads) if maxcpus given
  - cpus / (sockets * threads) if cpus given
  - else 1

> 
> This is a simple, linear logic that assigns defaults to each argument in
> sequence.  At the same time -machine should fail for all invalid
> combinations, namely:
> 
> - any argument < 1

What if a user says threads=0, because they don't have HT, and assume
that a value of zero will get them a non-HT system? Or what about
machines that don't describe sockets, so a user inputs zero? In both
those cases I agree we should just use 1, but from a user's perspective,
it might seem weird.

> - any argument > some compile-time value (1024?) to avoid overflows

Agreed. We should do this regardless of this series.

> - cpus % (cores * threads) != 0

Hmm. This makes sense where cpus is the number of cpu packages,
but I guess that's not how things currently work. Maybe Igor's
work is changing that?

> - cpus > sockets * cores * threads
> - maxcpus != cores * threads * sockets

We check these two (the 2nd added with this series) already.

> 
> Alone the last relation shows that requiring all four of maxcpus, cores,
> threads and sockets is unnecessary. :)

Not really. It depends on if you assume sockets, cores or threads to
be the N in maxcpus=N. We could just require sockets, cores, and threads
to be input, which allows us to easily calculate maxcpus, and then set
cpus from that. In that case maxcpus would just be an available input
for sanity checking.

> 
> This will catch situations where assigning a default for sockets doesn't
> work well.  For example cores=2,cpus=4,maxcpus=5 will assign
> threads=1,sockets=2; then the last relation will fail and QEMU will give
> an error.
> 
> These invalid combination also make sure that other useful default cases
> work.  For example "maxcpus given, sockets and cpus not" works thanks to
> the following deduction:
> 
> - sockets = cpus/(cores*threads)
> - maxcpus = cores*threads*sockets
> - because cpus%(cores*threads) must be 0, this gives maxcpus=cpus
> 
> -smp should do its legacy magic and assign all five values based on it.
> If the results do not match the obvious s/smp/-machine/ command line it
> should warn, and perhaps suggest the equivalent -machine command line.
> It doesn't have to be a minimal command line, just equivalent.

This is a good idea. I'm just still not sure what the -machine command
line should/should not assume. I'm still leaning towards nothing, but
at least maxcpus and cpus could be optional, making it just 3 required
inputs. And, machines are free to override this, allowing -machine
MACHINE,cpus=N to generate their default topology supporting N cpus,
maxcpus also =N. Or, -machine MACHINE,maxcpus=N,cpus=M for their common
hotplug-enabling case.

> 
> Apart from this point, these are lovely patches. :)

Thanks!

drew

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

* Re: [Qemu-devel] [PATCH RFC 01/16] vl: smp_parse: cleanups
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 01/16] vl: smp_parse: cleanups Andrew Jones
@ 2016-06-14  1:15   ` David Gibson
  0 siblings, 0 replies; 74+ messages in thread
From: David Gibson @ 2016-06-14  1:15 UTC (permalink / raw)
  To: Andrew Jones
  Cc: qemu-devel, qemu-ppc, qemu-arm, imammedo, ehabkost, pbonzini,
	peter.maydell, dgibson, agraf

[-- Attachment #1: Type: text/plain, Size: 3027 bytes --]

On Fri, Jun 10, 2016 at 07:40:12PM +0200, Andrew Jones wrote:
> No functional changes; only some code movement and removal of
> dead code (impossible conditions). Also, max_cpus can be
> initialized to 1, like smp_cpus, because it's either set by the
> user or set to smp_cpus, when smp_cpus is set by the user, or
> set to 1, when nothing is set.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> ---
>  vl.c | 34 +++++++++++++++-------------------
>  1 file changed, 15 insertions(+), 19 deletions(-)
> 
> diff --git a/vl.c b/vl.c
> index b0bcc255ee9a5..7b96e787922f9 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -154,7 +154,7 @@ CharDriverState *sclp_hds[MAX_SCLP_CONSOLES];
>  int win2k_install_hack = 0;
>  int singlestep = 0;
>  int smp_cpus = 1;
> -int max_cpus = 0;
> +int max_cpus = 1;
>  int smp_cores = 1;
>  int smp_threads = 1;
>  int acpi_enabled = 1;
> @@ -1223,7 +1223,6 @@ static QemuOptsList qemu_smp_opts = {
>  static void smp_parse(QemuOpts *opts)
>  {
>      if (opts) {
> -
>          unsigned cpus    = qemu_opt_get_number(opts, "cpus", 0);
>          unsigned sockets = qemu_opt_get_number(opts, "sockets", 0);
>          unsigned cores   = qemu_opt_get_number(opts, "cores", 0);
> @@ -1251,6 +1250,17 @@ static void smp_parse(QemuOpts *opts)
>          }
>  
>          max_cpus = qemu_opt_get_number(opts, "maxcpus", cpus);
> +
> +        if (max_cpus > MAX_CPUMASK_BITS) {
> +            error_report("unsupported number of maxcpus");
> +            exit(1);
> +        }
> +
> +        if (max_cpus < cpus) {
> +            error_report("maxcpus must be equal to or greater than smp");
> +            exit(1);
> +        }
> +
>          if (sockets * cores * threads > max_cpus) {
>              error_report("cpu topology: "
>                           "sockets (%u) * cores (%u) * threads (%u) > "
> @@ -1260,25 +1270,11 @@ static void smp_parse(QemuOpts *opts)
>          }
>  
>          smp_cpus = cpus;
> -        smp_cores = cores > 0 ? cores : 1;
> -        smp_threads = threads > 0 ? threads : 1;
> -
> -    }
> -
> -    if (max_cpus == 0) {
> -        max_cpus = smp_cpus;
> -    }
> -
> -    if (max_cpus > MAX_CPUMASK_BITS) {
> -        error_report("unsupported number of maxcpus");
> -        exit(1);
> -    }
> -    if (max_cpus < smp_cpus) {
> -        error_report("maxcpus must be equal to or greater than smp");
> -        exit(1);
> +        smp_cores = cores;
> +        smp_threads = threads;
>      }
>  
> -    if (smp_cpus > 1 || smp_cores > 1 || smp_threads > 1) {
> +    if (smp_cpus > 1) {
>          Error *blocker = NULL;
>          error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, "smp");
>          replay_add_blocker(blocker);

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH RFC 02/16] vl: smp: add checks for maxcpus based topologies
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 02/16] vl: smp: add checks for maxcpus based topologies Andrew Jones
@ 2016-06-14  1:28   ` David Gibson
  2016-06-14  6:43     ` Andrew Jones
  0 siblings, 1 reply; 74+ messages in thread
From: David Gibson @ 2016-06-14  1:28 UTC (permalink / raw)
  To: Andrew Jones
  Cc: qemu-devel, qemu-ppc, qemu-arm, imammedo, ehabkost, pbonzini,
	peter.maydell, dgibson, agraf

[-- Attachment #1: Type: text/plain, Size: 3002 bytes --]

On Fri, Jun 10, 2016 at 07:40:13PM +0200, Andrew Jones wrote:
> smp_parse computes missing smp options. Unfortunately cores and
> threads are computed by dividing smp_cpus, instead of max_cpus.
> This is incorrect because the topology doesn't leave room for
> hotplug. More unfortunately, we can't change it easily, as doing
> so would impact existing command lines. This patch adds a warning
> when the topology doesn't add up, and then checks that the topology
> at least computes when sockets are recalculated. If not, then it
> does fail.
> 
> Adding the new failure is justified by the fact that we don't
> store the number of input sockets, and thus all consumers of
> cpu topology information recalculate it. If they choose to
> (correctly) calculate it based on maxcpus, then we need to
> guard them against building topologies which provide more cpu
> slots than are the maximum allowed cpus.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>

Hmm.. this makes sense to me.  Except that I've never been clear if
sockets= was supposed to match initial cpus or maxcpus.

> ---
>  vl.c | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/vl.c b/vl.c
> index 7b96e787922f9..8d482cb1bf020 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -1227,6 +1227,7 @@ 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 sockets_input = sockets > 0;
>  
>          /* compute missing values, prefer sockets over cores over threads */
>          if (cpus == 0 || sockets == 0) {
> @@ -1269,6 +1270,24 @@ static void smp_parse(QemuOpts *opts)
>              exit(1);
>          }
>  
> +        if (sockets_input && sockets * cores * threads != max_cpus) {
> +            unsigned sockets_rounded = DIV_ROUND_UP(max_cpus, cores * threads);
> +
> +            error_report("warning: cpu topology: "
> +                         "sockets (%u) * cores (%u) * threads (%u) != "
> +                         "maxcpus (%u). Trying sockets=%u.",
> +                         sockets, cores, threads, max_cpus, sockets_rounded);
> +            sockets = sockets_rounded;
> +
> +            if (sockets * cores * threads > max_cpus) {
> +                error_report("cpu topology: "
> +                             "sockets (%u) * cores (%u) * threads (%u) > "
> +                             "maxcpus (%u)",
> +                             sockets, cores, threads, max_cpus);
> +                exit(1);
> +            }
> +        }
> +
>          smp_cpus = cpus;
>          smp_cores = cores;
>          smp_threads = threads;

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH RFC 04/16] hw/core/machine: Introduce pre_init
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 04/16] hw/core/machine: Introduce pre_init Andrew Jones
@ 2016-06-14  1:30   ` David Gibson
  2016-06-14  5:58     ` Andrew Jones
  0 siblings, 1 reply; 74+ messages in thread
From: David Gibson @ 2016-06-14  1:30 UTC (permalink / raw)
  To: Andrew Jones
  Cc: qemu-devel, qemu-ppc, qemu-arm, imammedo, ehabkost, pbonzini,
	peter.maydell, dgibson, agraf

[-- Attachment #1: Type: text/plain, Size: 2239 bytes --]

On Fri, Jun 10, 2016 at 07:40:15PM +0200, Andrew Jones wrote:
> From: Igor Mammedov <imammedo@redhat.com>
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> Signed-off-by: Andrew Jones <drjones@redhat.com>

I think this needs some kind of rationale.

Since with this patch it is called immediately before ->init, I'm not
really seeing the point of this.

> ---
>  hw/core/machine.c   | 6 ++++++
>  include/hw/boards.h | 1 +
>  vl.c                | 1 +
>  3 files changed, 8 insertions(+)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index ccdd5fa3e7728..3dce9020e510a 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -368,10 +368,16 @@ static void machine_init_notify(Notifier *notifier, void *data)
>      foreach_dynamic_sysbus_device(error_on_sysbus_device, NULL);
>  }
>  
> +static void machine_pre_init(MachineState *ms)
> +{
> +}
> +
>  static void machine_class_init(ObjectClass *oc, void *data)
>  {
>      MachineClass *mc = MACHINE_CLASS(oc);
>  
> +    mc->pre_init = machine_pre_init;
> +
>      /* Default 128 MB as guest ram size */
>      mc->default_ram_size = 128 * M_BYTE;
>      mc->rom_file_has_mr = true;
> diff --git a/include/hw/boards.h b/include/hw/boards.h
> index d268bd00a9f7d..4e8dc68b07a24 100644
> --- a/include/hw/boards.h
> +++ b/include/hw/boards.h
> @@ -92,6 +92,7 @@ struct MachineClass {
>      const char *alias;
>      const char *desc;
>  
> +    void (*pre_init)(MachineState *state);
>      void (*init)(MachineState *state);
>      void (*reset)(void);
>      void (*hot_add_cpu)(const int64_t id, Error **errp);
> diff --git a/vl.c b/vl.c
> index 8d482cb1bf020..4849dd465d667 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -4500,6 +4500,7 @@ int main(int argc, char **argv, char **envp)
>      current_machine->boot_order = boot_order;
>      current_machine->cpu_model = cpu_model;
>  
> +    machine_class->pre_init(current_machine);
>      machine_class->init(current_machine);
>  
>      realtime_init();

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH RFC 05/16] hw/core/machine: add smp properites
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 05/16] hw/core/machine: add smp properites Andrew Jones
@ 2016-06-14  2:00   ` David Gibson
  2016-06-14  6:08     ` Andrew Jones
  0 siblings, 1 reply; 74+ messages in thread
From: David Gibson @ 2016-06-14  2:00 UTC (permalink / raw)
  To: Andrew Jones
  Cc: qemu-devel, qemu-ppc, qemu-arm, imammedo, ehabkost, pbonzini,
	peter.maydell, dgibson, agraf

[-- Attachment #1: Type: text/plain, Size: 6088 bytes --]

On Fri, Jun 10, 2016 at 07:40:16PM +0200, Andrew Jones wrote:
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> ---
>  hw/core/machine.c   | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  include/hw/boards.h |  6 ++++
>  2 files changed, 87 insertions(+)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 3dce9020e510a..2625044002e57 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -172,6 +172,53 @@ static void machine_set_dumpdtb(Object *obj, const char *value, Error **errp)
>      ms->dumpdtb = g_strdup(value);
>  }
>  
> +static void machine_get_smp(Object *obj, Visitor *v, const char *name,
> +                            void *opaque, Error **errp)
> +{
> +    MachineState *ms = MACHINE(obj);
> +    int64_t value;
> +
> +    if (strncmp(name, "sockets", 7) == 0) {
> +        value = ms->sockets;
> +    } else if (strncmp(name, "cores", 5) == 0) {
> +        value = ms->cores;
> +    } else if (strncmp(name, "threads", 7) == 0) {
> +        value = ms->threads;
> +    } else if (strncmp(name, "maxcpus", 7) == 0) {
> +        value = ms->maxcpus;
> +    } else if (strncmp(name, "cpus", 4) == 0) {
> +        value = ms->cpus;
> +    }
> +
> +    visit_type_int(v, name, &value, errp);
> +}

Any particular for multiplexing all the set / get, rather than having
separate callbacks for each property?

> +
> +static void machine_set_smp(Object *obj, Visitor *v, const char *name,
> +                            void *opaque, Error **errp)
> +{
> +    MachineState *ms = MACHINE(obj);
> +    Error *error = NULL;
> +    int64_t value;
> +
> +    visit_type_int(v, name, &value, &error);
> +    if (error) {
> +        error_propagate(errp, error);
> +        return;
> +    }
> +
> +    if (strncmp(name, "sockets", 7) == 0) {
> +        ms->sockets = value;
> +    } else if (strncmp(name, "cores", 5) == 0) {
> +        ms->cores = value;;
> +    } else if (strncmp(name, "threads", 7) == 0) {
> +        ms->threads = value;
> +    } else if (strncmp(name, "maxcpus", 7) == 0) {
> +        ms->maxcpus = value;
> +    } else if (strncmp(name, "cpus", 4) == 0) {
> +        ms->cpus = value;
> +    }
> +}
> +
>  static void machine_get_phandle_start(Object *obj, Visitor *v,
>                                        const char *name, void *opaque,
>                                        Error **errp)
> @@ -368,8 +415,18 @@ static void machine_init_notify(Notifier *notifier, void *data)
>      foreach_dynamic_sysbus_device(error_on_sysbus_device, NULL);
>  }
>  
> +static void machine_set_smp_parameters(MachineState *ms)
> +{
> +    if (ms->sockets != -1 || ms->cores != -1 || ms->threads != -1 ||
> +        ms->maxcpus != -1 || ms->cpus != -1) {
> +        error_report("warning: cpu topology: "
> +                     "machine properties currently ignored");
> +    }
> +}
> +
>  static void machine_pre_init(MachineState *ms)
>  {
> +    machine_set_smp_parameters(ms);
>  }
>  
>  static void machine_class_init(ObjectClass *oc, void *data)
> @@ -403,6 +460,11 @@ static void machine_initfn(Object *obj)
>      ms->dump_guest_core = true;
>      ms->mem_merge = true;
>      ms->enable_graphics = true;
> +    ms->sockets = -1;
> +    ms->cores = -1;
> +    ms->threads = -1;
> +    ms->maxcpus = -1;
> +    ms->cpus = -1;
>  
>      object_property_add_str(obj, "accel",
>                              machine_get_accel, machine_set_accel, NULL);
> @@ -462,6 +524,25 @@ static void machine_initfn(Object *obj)
>      object_property_set_description(obj, "dt-compatible",
>                                      "Overrides the \"compatible\" property of the dt root node",
>                                      NULL);
> +    object_property_add(obj, "sockets", "int", machine_get_smp,
> +                        machine_set_smp, NULL, NULL, NULL);
> +    object_property_set_description(obj, "sockets", "Number of sockets", NULL);
> +    object_property_add(obj, "cores", "int", machine_get_smp,
> +                        machine_set_smp, NULL, NULL, NULL);
> +    object_property_set_description(obj, "cores",
> +                                    "Number of cores per socket", NULL);
> +    object_property_add(obj, "threads", "int", machine_get_smp,
> +                        machine_set_smp, NULL, NULL, NULL);
> +    object_property_set_description(obj, "threads",
> +                                    "Number of threads per core", NULL);
> +    object_property_add(obj, "maxcpus", "int", machine_get_smp,
> +                        machine_set_smp, NULL, NULL, NULL);
> +    object_property_set_description(obj, "maxcpus", "Maximum number of cpus",
> +                                    NULL);
> +    object_property_add(obj, "cpus", "int", machine_get_smp,
> +                        machine_set_smp, NULL, NULL, NULL);
> +    object_property_set_description(obj, "cpus", "Number of online cpus",
> +                                    NULL);
>      object_property_add_bool(obj, "dump-guest-core",
>                               machine_get_dump_guest_core,
>                               machine_set_dump_guest_core,
> diff --git a/include/hw/boards.h b/include/hw/boards.h
> index 4e8dc68b07a24..53adbfe2a3099 100644
> --- a/include/hw/boards.h
> +++ b/include/hw/boards.h
> @@ -166,6 +166,12 @@ struct MachineState {
>      char *initrd_filename;
>      const char *cpu_model;
>      AccelState *accelerator;
> +
> +    int sockets;
> +    int cores;
> +    int threads;
> +    int maxcpus;
> +    int cpus;

Hrm.. as the tests added in earlier patches highlight, essentially one
of these properties is redundant.  Is there a reason to include them
all, rather than to pick one to drop?

>  };
>  
>  #define DEFINE_MACHINE(namestr, machine_initfn) \

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties
  2016-06-12 13:48     ` Andrew Jones
@ 2016-06-14  2:12       ` David Gibson
  2016-06-14  6:19         ` Andrew Jones
  0 siblings, 1 reply; 74+ messages in thread
From: David Gibson @ 2016-06-14  2:12 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Thomas Huth, qemu-devel, qemu-ppc, qemu-arm, peter.maydell,
	ehabkost, Bharata B Rao, agraf, pbonzini, imammedo, dgibson

[-- Attachment #1: Type: text/plain, Size: 2469 bytes --]

On Sun, Jun 12, 2016 at 03:48:10PM +0200, Andrew Jones wrote:
> On Sat, Jun 11, 2016 at 08:54:35AM +0200, Thomas Huth wrote:
> > On 10.06.2016 19:40, Andrew Jones wrote:
> > > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > > ---
> > >  qom/cpu.c | 8 ++++++++
> > >  1 file changed, 8 insertions(+)
> > > 
> > > diff --git a/qom/cpu.c b/qom/cpu.c
> > > index 751e992de8823..024cda3eb98c8 100644
> > > --- a/qom/cpu.c
> > > +++ b/qom/cpu.c
> > > @@ -28,6 +28,7 @@
> > >  #include "exec/log.h"
> > >  #include "qemu/error-report.h"
> > >  #include "sysemu/sysemu.h"
> > > +#include "hw/qdev-properties.h"
> > >  
> > >  bool cpu_exists(int64_t id)
> > >  {
> > > @@ -342,6 +343,12 @@ static int64_t cpu_common_get_arch_id(CPUState *cpu)
> > >      return cpu->cpu_index;
> > >  }
> > >  
> > > +static Property cpu_common_properties[] = {
> > > +    DEFINE_PROP_INT32("nr-cores", CPUState, nr_cores, 1),
> > > +    DEFINE_PROP_INT32("nr-threads", CPUState, nr_threads, 1),
> > > +    DEFINE_PROP_END_OF_LIST()
> > > +};
> > 
> > Are you aware of the current CPU hotplug discussion that is going on?
> 
> I'm aware of it going on, but haven't been following it.
> 
> > I'm not very involved there, but I think some of these reworks also move
> > "nr_threads" into the CPU state already, e.g. see:
> 
> nr_threads (and nr_cores) are already state in CPUState. This patch just
> exposes that state via properties.
> 
> > 
> > https://github.com/dgibson/qemu/commit/9d07719784ecbeebea71
> > 
> > ... so you might want to check these patches first to see whether you
> > can base your rework on them?
> 
> Every cpu, and thus every machine, uses CPUState for its cpus. I'm
> not sure every machine will want to use that new abstract core class
> though. If they did, then we could indeed use nr_threads from there
> instead (and remove it from CPUState), but we'd still need nr_cores
> from the abstract cpu package class (CPUState).

Hmm.  Since the CPUState object represents just a single thread, it
seems weird to me that it would have nr_threads and nr_cores
information.

Exposing those as properties makes that much worse, because it's now
ABI, rather than internal detail we can clean up at some future time.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH RFC 10/16] hw/ppc/spapr: don't use smp_cores, smp_threads
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 10/16] hw/ppc/spapr: " Andrew Jones
@ 2016-06-14  3:03   ` David Gibson
  2016-06-14  6:23     ` Andrew Jones
  0 siblings, 1 reply; 74+ messages in thread
From: David Gibson @ 2016-06-14  3:03 UTC (permalink / raw)
  To: Andrew Jones
  Cc: qemu-devel, qemu-ppc, qemu-arm, imammedo, ehabkost, pbonzini,
	peter.maydell, dgibson, agraf

[-- Attachment #1: Type: text/plain, Size: 3321 bytes --]

On Fri, Jun 10, 2016 at 07:40:21PM +0200, Andrew Jones wrote:
> Use CPUState nr_cores,nr_threads and MachineState
> cores,threads instead.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> ---
>  hw/ppc/spapr.c      | 9 +++++----
>  hw/ppc/spapr_rtas.c | 2 +-
>  2 files changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 063664234106e..f78276bb4b164 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -35,7 +35,6 @@
>  #include "net/net.h"
>  #include "sysemu/device_tree.h"
>  #include "sysemu/block-backend.h"
> -#include "sysemu/cpus.h"
>  #include "sysemu/kvm.h"
>  #include "sysemu/device_tree.h"
>  #include "kvm_ppc.h"
> @@ -603,7 +602,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
>      uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 1000000000;
>      uint32_t page_sizes_prop[64];
>      size_t page_sizes_prop_size;
> -    uint32_t vcpus_per_socket = smp_threads * smp_cores;
> +    uint32_t vcpus_per_socket = cs->nr_cores * cs->nr_threads;
>      uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)};
>  
>      /* Note: we keep CI large pages off for now because a 64K capable guest
> @@ -1774,7 +1773,7 @@ static void ppc_spapr_init(MachineState *machine)
>      /* Set up Interrupt Controller before we create the VCPUs */
>      spapr->icp = xics_system_init(machine,
>                                    DIV_ROUND_UP(max_cpus * kvmppc_smt_threads(),
> -                                               smp_threads),
> +                                               machine->threads),
>                                    XICS_IRQS, &error_fatal);
>  
>      if (smc->dr_lmb_enabled) {
> @@ -2268,9 +2267,11 @@ static HotplugHandler *spapr_get_hotpug_handler(MachineState *machine,
>  
>  static unsigned spapr_cpu_index_to_socket_id(unsigned cpu_index)
>  {
> +    CPUState *cs = first_cpu;
> +
>      /* Allocate to NUMA nodes on a "socket" basis (not that concept of
>       * socket means much for the paravirtualized PAPR platform) */
> -    return cpu_index / smp_threads / smp_cores;
> +    return cpu_index / cs->nr_cores / cs->nr_threads;
>  }
>  
>  static void spapr_machine_class_init(ObjectClass *oc, void *data)
> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
> index 43e2c684fda8d..3fdfbb01a20dd 100644
> --- a/hw/ppc/spapr_rtas.c
> +++ b/hw/ppc/spapr_rtas.c
> @@ -742,7 +742,7 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
>      lrdr_capacity[1] = cpu_to_be32(max_hotplug_addr & 0xffffffff);
>      lrdr_capacity[2] = 0;
>      lrdr_capacity[3] = cpu_to_be32(SPAPR_MEMORY_BLOCK_SIZE);
> -    lrdr_capacity[4] = cpu_to_be32(max_cpus/smp_threads);
> +    lrdr_capacity[4] = cpu_to_be32(max_cpus / machine->threads);
>      ret = qemu_fdt_setprop(fdt, "/rtas", "ibm,lrdr-capacity", lrdr_capacity,
>                       sizeof(lrdr_capacity));
>      if (ret < 0) {

I think all the places that use cs->nr_* here it actually makes more
sense to use the value in the machine state.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH RFC 04/16] hw/core/machine: Introduce pre_init
  2016-06-14  1:30   ` David Gibson
@ 2016-06-14  5:58     ` Andrew Jones
  2016-07-14 20:10       ` Eduardo Habkost
  0 siblings, 1 reply; 74+ messages in thread
From: Andrew Jones @ 2016-06-14  5:58 UTC (permalink / raw)
  To: David Gibson
  Cc: peter.maydell, ehabkost, qemu-devel, agraf, qemu-arm, qemu-ppc,
	pbonzini, imammedo, dgibson

On Tue, Jun 14, 2016 at 11:30:37AM +1000, David Gibson wrote:
> On Fri, Jun 10, 2016 at 07:40:15PM +0200, Andrew Jones wrote:
> > From: Igor Mammedov <imammedo@redhat.com>
> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > Signed-off-by: Andrew Jones <drjones@redhat.com>
> 
> I think this needs some kind of rationale.
> 
> Since with this patch it is called immediately before ->init, I'm not
> really seeing the point of this.

Many machines already override ->init, so if we want to move code
from vl.c into machine methods, but be sure that they run it now,
then we have to invent a pre-init. I (or Igor) can add something
like that to the commit message for the next round.

Thanks,
drew

> 
> > ---
> >  hw/core/machine.c   | 6 ++++++
> >  include/hw/boards.h | 1 +
> >  vl.c                | 1 +
> >  3 files changed, 8 insertions(+)
> > 
> > diff --git a/hw/core/machine.c b/hw/core/machine.c
> > index ccdd5fa3e7728..3dce9020e510a 100644
> > --- a/hw/core/machine.c
> > +++ b/hw/core/machine.c
> > @@ -368,10 +368,16 @@ static void machine_init_notify(Notifier *notifier, void *data)
> >      foreach_dynamic_sysbus_device(error_on_sysbus_device, NULL);
> >  }
> >  
> > +static void machine_pre_init(MachineState *ms)
> > +{
> > +}
> > +
> >  static void machine_class_init(ObjectClass *oc, void *data)
> >  {
> >      MachineClass *mc = MACHINE_CLASS(oc);
> >  
> > +    mc->pre_init = machine_pre_init;
> > +
> >      /* Default 128 MB as guest ram size */
> >      mc->default_ram_size = 128 * M_BYTE;
> >      mc->rom_file_has_mr = true;
> > diff --git a/include/hw/boards.h b/include/hw/boards.h
> > index d268bd00a9f7d..4e8dc68b07a24 100644
> > --- a/include/hw/boards.h
> > +++ b/include/hw/boards.h
> > @@ -92,6 +92,7 @@ struct MachineClass {
> >      const char *alias;
> >      const char *desc;
> >  
> > +    void (*pre_init)(MachineState *state);
> >      void (*init)(MachineState *state);
> >      void (*reset)(void);
> >      void (*hot_add_cpu)(const int64_t id, Error **errp);
> > diff --git a/vl.c b/vl.c
> > index 8d482cb1bf020..4849dd465d667 100644
> > --- a/vl.c
> > +++ b/vl.c
> > @@ -4500,6 +4500,7 @@ int main(int argc, char **argv, char **envp)
> >      current_machine->boot_order = boot_order;
> >      current_machine->cpu_model = cpu_model;
> >  
> > +    machine_class->pre_init(current_machine);
> >      machine_class->init(current_machine);
> >  
> >      realtime_init();
> 
> -- 
> David Gibson			| I'll have my music baroque, and my code
> david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
> 				| _way_ _around_!
> http://www.ozlabs.org/~dgibson

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

* Re: [Qemu-devel] [PATCH RFC 05/16] hw/core/machine: add smp properites
  2016-06-14  2:00   ` David Gibson
@ 2016-06-14  6:08     ` Andrew Jones
  2016-06-15  0:37       ` David Gibson
  0 siblings, 1 reply; 74+ messages in thread
From: Andrew Jones @ 2016-06-14  6:08 UTC (permalink / raw)
  To: David Gibson
  Cc: peter.maydell, ehabkost, qemu-devel, agraf, qemu-arm, qemu-ppc,
	pbonzini, imammedo, dgibson

On Tue, Jun 14, 2016 at 12:00:26PM +1000, David Gibson wrote:
> On Fri, Jun 10, 2016 at 07:40:16PM +0200, Andrew Jones wrote:
> > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > ---
> >  hw/core/machine.c   | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  include/hw/boards.h |  6 ++++
> >  2 files changed, 87 insertions(+)
> > 
> > diff --git a/hw/core/machine.c b/hw/core/machine.c
> > index 3dce9020e510a..2625044002e57 100644
> > --- a/hw/core/machine.c
> > +++ b/hw/core/machine.c
> > @@ -172,6 +172,53 @@ static void machine_set_dumpdtb(Object *obj, const char *value, Error **errp)
> >      ms->dumpdtb = g_strdup(value);
> >  }
> >  
> > +static void machine_get_smp(Object *obj, Visitor *v, const char *name,
> > +                            void *opaque, Error **errp)
> > +{
> > +    MachineState *ms = MACHINE(obj);
> > +    int64_t value;
> > +
> > +    if (strncmp(name, "sockets", 7) == 0) {
> > +        value = ms->sockets;
> > +    } else if (strncmp(name, "cores", 5) == 0) {
> > +        value = ms->cores;
> > +    } else if (strncmp(name, "threads", 7) == 0) {
> > +        value = ms->threads;
> > +    } else if (strncmp(name, "maxcpus", 7) == 0) {
> > +        value = ms->maxcpus;
> > +    } else if (strncmp(name, "cpus", 4) == 0) {
> > +        value = ms->cpus;
> > +    }
> > +
> > +    visit_type_int(v, name, &value, errp);
> > +}
> 
> Any particular for multiplexing all the set / get, rather than having
> separate callbacks for each property?

Not really. This way just makes denser code. But I'll go whichever
direction people prefer. Actually I should probably add an
else { error_report(...) } in either case, which means the multifunction
direction would still contain strncmps.

> 
> > +
> > +static void machine_set_smp(Object *obj, Visitor *v, const char *name,
> > +                            void *opaque, Error **errp)
> > +{
> > +    MachineState *ms = MACHINE(obj);
> > +    Error *error = NULL;
> > +    int64_t value;
> > +
> > +    visit_type_int(v, name, &value, &error);
> > +    if (error) {
> > +        error_propagate(errp, error);
> > +        return;
> > +    }
> > +
> > +    if (strncmp(name, "sockets", 7) == 0) {
> > +        ms->sockets = value;
> > +    } else if (strncmp(name, "cores", 5) == 0) {
> > +        ms->cores = value;;
> > +    } else if (strncmp(name, "threads", 7) == 0) {
> > +        ms->threads = value;
> > +    } else if (strncmp(name, "maxcpus", 7) == 0) {
> > +        ms->maxcpus = value;
> > +    } else if (strncmp(name, "cpus", 4) == 0) {
> > +        ms->cpus = value;
> > +    }
> > +}
> > +
> >  static void machine_get_phandle_start(Object *obj, Visitor *v,
> >                                        const char *name, void *opaque,
> >                                        Error **errp)
> > @@ -368,8 +415,18 @@ static void machine_init_notify(Notifier *notifier, void *data)
> >      foreach_dynamic_sysbus_device(error_on_sysbus_device, NULL);
> >  }
> >  
> > +static void machine_set_smp_parameters(MachineState *ms)
> > +{
> > +    if (ms->sockets != -1 || ms->cores != -1 || ms->threads != -1 ||
> > +        ms->maxcpus != -1 || ms->cpus != -1) {
> > +        error_report("warning: cpu topology: "
> > +                     "machine properties currently ignored");
> > +    }
> > +}
> > +
> >  static void machine_pre_init(MachineState *ms)
> >  {
> > +    machine_set_smp_parameters(ms);
> >  }
> >  
> >  static void machine_class_init(ObjectClass *oc, void *data)
> > @@ -403,6 +460,11 @@ static void machine_initfn(Object *obj)
> >      ms->dump_guest_core = true;
> >      ms->mem_merge = true;
> >      ms->enable_graphics = true;
> > +    ms->sockets = -1;
> > +    ms->cores = -1;
> > +    ms->threads = -1;
> > +    ms->maxcpus = -1;
> > +    ms->cpus = -1;
> >  
> >      object_property_add_str(obj, "accel",
> >                              machine_get_accel, machine_set_accel, NULL);
> > @@ -462,6 +524,25 @@ static void machine_initfn(Object *obj)
> >      object_property_set_description(obj, "dt-compatible",
> >                                      "Overrides the \"compatible\" property of the dt root node",
> >                                      NULL);
> > +    object_property_add(obj, "sockets", "int", machine_get_smp,
> > +                        machine_set_smp, NULL, NULL, NULL);
> > +    object_property_set_description(obj, "sockets", "Number of sockets", NULL);
> > +    object_property_add(obj, "cores", "int", machine_get_smp,
> > +                        machine_set_smp, NULL, NULL, NULL);
> > +    object_property_set_description(obj, "cores",
> > +                                    "Number of cores per socket", NULL);
> > +    object_property_add(obj, "threads", "int", machine_get_smp,
> > +                        machine_set_smp, NULL, NULL, NULL);
> > +    object_property_set_description(obj, "threads",
> > +                                    "Number of threads per core", NULL);
> > +    object_property_add(obj, "maxcpus", "int", machine_get_smp,
> > +                        machine_set_smp, NULL, NULL, NULL);
> > +    object_property_set_description(obj, "maxcpus", "Maximum number of cpus",
> > +                                    NULL);
> > +    object_property_add(obj, "cpus", "int", machine_get_smp,
> > +                        machine_set_smp, NULL, NULL, NULL);
> > +    object_property_set_description(obj, "cpus", "Number of online cpus",
> > +                                    NULL);
> >      object_property_add_bool(obj, "dump-guest-core",
> >                               machine_get_dump_guest_core,
> >                               machine_set_dump_guest_core,
> > diff --git a/include/hw/boards.h b/include/hw/boards.h
> > index 4e8dc68b07a24..53adbfe2a3099 100644
> > --- a/include/hw/boards.h
> > +++ b/include/hw/boards.h
> > @@ -166,6 +166,12 @@ struct MachineState {
> >      char *initrd_filename;
> >      const char *cpu_model;
> >      AccelState *accelerator;
> > +
> > +    int sockets;
> > +    int cores;
> > +    int threads;
> > +    int maxcpus;
> > +    int cpus;
> 
> Hrm.. as the tests added in earlier patches highlight, essentially one
> of these properties is redundant.  Is there a reason to include them
> all, rather than to pick one to drop?

Well, IMO, only maxcpus could be dropped. I'd prefer not to though
because it's a convenient state to have pre-calculated, and possibly
error prone to leave to all users to re-calculate.

Thanks,
drew

> 
> >  };
> >  
> >  #define DEFINE_MACHINE(namestr, machine_initfn) \
> 
> -- 
> David Gibson			| I'll have my music baroque, and my code
> david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
> 				| _way_ _around_!
> http://www.ozlabs.org/~dgibson

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

* Re: [Qemu-devel] [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties
  2016-06-14  2:12       ` David Gibson
@ 2016-06-14  6:19         ` Andrew Jones
  2016-06-15  0:56           ` David Gibson
  0 siblings, 1 reply; 74+ messages in thread
From: Andrew Jones @ 2016-06-14  6:19 UTC (permalink / raw)
  To: David Gibson
  Cc: peter.maydell, Thomas Huth, ehabkost, imammedo, qemu-devel,
	agraf, qemu-arm, qemu-ppc, Bharata B Rao, pbonzini, dgibson

On Tue, Jun 14, 2016 at 12:12:16PM +1000, David Gibson wrote:
> On Sun, Jun 12, 2016 at 03:48:10PM +0200, Andrew Jones wrote:
> > On Sat, Jun 11, 2016 at 08:54:35AM +0200, Thomas Huth wrote:
> > > On 10.06.2016 19:40, Andrew Jones wrote:
> > > > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > > > ---
> > > >  qom/cpu.c | 8 ++++++++
> > > >  1 file changed, 8 insertions(+)
> > > > 
> > > > diff --git a/qom/cpu.c b/qom/cpu.c
> > > > index 751e992de8823..024cda3eb98c8 100644
> > > > --- a/qom/cpu.c
> > > > +++ b/qom/cpu.c
> > > > @@ -28,6 +28,7 @@
> > > >  #include "exec/log.h"
> > > >  #include "qemu/error-report.h"
> > > >  #include "sysemu/sysemu.h"
> > > > +#include "hw/qdev-properties.h"
> > > >  
> > > >  bool cpu_exists(int64_t id)
> > > >  {
> > > > @@ -342,6 +343,12 @@ static int64_t cpu_common_get_arch_id(CPUState *cpu)
> > > >      return cpu->cpu_index;
> > > >  }
> > > >  
> > > > +static Property cpu_common_properties[] = {
> > > > +    DEFINE_PROP_INT32("nr-cores", CPUState, nr_cores, 1),
> > > > +    DEFINE_PROP_INT32("nr-threads", CPUState, nr_threads, 1),
> > > > +    DEFINE_PROP_END_OF_LIST()
> > > > +};
> > > 
> > > Are you aware of the current CPU hotplug discussion that is going on?
> > 
> > I'm aware of it going on, but haven't been following it.
> > 
> > > I'm not very involved there, but I think some of these reworks also move
> > > "nr_threads" into the CPU state already, e.g. see:
> > 
> > nr_threads (and nr_cores) are already state in CPUState. This patch just
> > exposes that state via properties.
> > 
> > > 
> > > https://github.com/dgibson/qemu/commit/9d07719784ecbeebea71
> > > 
> > > ... so you might want to check these patches first to see whether you
> > > can base your rework on them?
> > 
> > Every cpu, and thus every machine, uses CPUState for its cpus. I'm
> > not sure every machine will want to use that new abstract core class
> > though. If they did, then we could indeed use nr_threads from there
> > instead (and remove it from CPUState), but we'd still need nr_cores
> > from the abstract cpu package class (CPUState).
> 
> Hmm.  Since the CPUState object represents just a single thread, it
> seems weird to me that it would have nr_threads and nr_cores
> information.
> 
> Exposing those as properties makes that much worse, because it's now
> ABI, rather than internal detail we can clean up at some future time.

CPUState is supposed to be "State of one CPU core or thread", which
justifies having nr_threads state, as it may be describing a core.
I guess there's no justification for having nr_cores in there though.
I agree adding the Core class is a good idea, assuming it will get used
by all machines, and CPUState then gets changed to a Thread class. The
question then, though, is do we also create a Socket class that contains
nr_cores? And how will a Thread method get that information when it
needs to emulate, e.g. CPUID, that requires it? It's a bit messy, so
I'm open to all suggestions on it.

Thanks,
drew

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

* Re: [Qemu-devel] [PATCH RFC 10/16] hw/ppc/spapr: don't use smp_cores, smp_threads
  2016-06-14  3:03   ` David Gibson
@ 2016-06-14  6:23     ` Andrew Jones
  2016-06-15  0:59       ` David Gibson
  0 siblings, 1 reply; 74+ messages in thread
From: Andrew Jones @ 2016-06-14  6:23 UTC (permalink / raw)
  To: David Gibson
  Cc: peter.maydell, ehabkost, qemu-devel, agraf, qemu-arm, qemu-ppc,
	pbonzini, imammedo, dgibson

On Tue, Jun 14, 2016 at 01:03:41PM +1000, David Gibson wrote:
> On Fri, Jun 10, 2016 at 07:40:21PM +0200, Andrew Jones wrote:
> > Use CPUState nr_cores,nr_threads and MachineState
> > cores,threads instead.
> > 
> > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > ---
> >  hw/ppc/spapr.c      | 9 +++++----
> >  hw/ppc/spapr_rtas.c | 2 +-
> >  2 files changed, 6 insertions(+), 5 deletions(-)
> > 
> > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > index 063664234106e..f78276bb4b164 100644
> > --- a/hw/ppc/spapr.c
> > +++ b/hw/ppc/spapr.c
> > @@ -35,7 +35,6 @@
> >  #include "net/net.h"
> >  #include "sysemu/device_tree.h"
> >  #include "sysemu/block-backend.h"
> > -#include "sysemu/cpus.h"
> >  #include "sysemu/kvm.h"
> >  #include "sysemu/device_tree.h"
> >  #include "kvm_ppc.h"
> > @@ -603,7 +602,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
> >      uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 1000000000;
> >      uint32_t page_sizes_prop[64];
> >      size_t page_sizes_prop_size;
> > -    uint32_t vcpus_per_socket = smp_threads * smp_cores;
> > +    uint32_t vcpus_per_socket = cs->nr_cores * cs->nr_threads;
> >      uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)};
> >  
> >      /* Note: we keep CI large pages off for now because a 64K capable guest
> > @@ -1774,7 +1773,7 @@ static void ppc_spapr_init(MachineState *machine)
> >      /* Set up Interrupt Controller before we create the VCPUs */
> >      spapr->icp = xics_system_init(machine,
> >                                    DIV_ROUND_UP(max_cpus * kvmppc_smt_threads(),
> > -                                               smp_threads),
> > +                                               machine->threads),
> >                                    XICS_IRQS, &error_fatal);
> >  
> >      if (smc->dr_lmb_enabled) {
> > @@ -2268,9 +2267,11 @@ static HotplugHandler *spapr_get_hotpug_handler(MachineState *machine,
> >  
> >  static unsigned spapr_cpu_index_to_socket_id(unsigned cpu_index)
> >  {
> > +    CPUState *cs = first_cpu;
> > +
> >      /* Allocate to NUMA nodes on a "socket" basis (not that concept of
> >       * socket means much for the paravirtualized PAPR platform) */
> > -    return cpu_index / smp_threads / smp_cores;
> > +    return cpu_index / cs->nr_cores / cs->nr_threads;
> >  }
> >  
> >  static void spapr_machine_class_init(ObjectClass *oc, void *data)
> > diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
> > index 43e2c684fda8d..3fdfbb01a20dd 100644
> > --- a/hw/ppc/spapr_rtas.c
> > +++ b/hw/ppc/spapr_rtas.c
> > @@ -742,7 +742,7 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
> >      lrdr_capacity[1] = cpu_to_be32(max_hotplug_addr & 0xffffffff);
> >      lrdr_capacity[2] = 0;
> >      lrdr_capacity[3] = cpu_to_be32(SPAPR_MEMORY_BLOCK_SIZE);
> > -    lrdr_capacity[4] = cpu_to_be32(max_cpus/smp_threads);
> > +    lrdr_capacity[4] = cpu_to_be32(max_cpus / machine->threads);
> >      ret = qemu_fdt_setprop(fdt, "/rtas", "ibm,lrdr-capacity", lrdr_capacity,
> >                       sizeof(lrdr_capacity));
> >      if (ret < 0) {
> 
> I think all the places that use cs->nr_* here it actually makes more
> sense to use the value in the machine state.

I think I used machine state whenever I (easily) could. How do I get to
machine state from a CPU method? I will if I can, for all machines,
and then gladly kill the CPUState->nr_cores/nr_threads.

Thanks,
drew

> 
> -- 
> David Gibson			| I'll have my music baroque, and my code
> david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
> 				| _way_ _around_!
> http://www.ozlabs.org/~dgibson

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

* Re: [Qemu-devel] [PATCH RFC 02/16] vl: smp: add checks for maxcpus based topologies
  2016-06-14  1:28   ` David Gibson
@ 2016-06-14  6:43     ` Andrew Jones
  0 siblings, 0 replies; 74+ messages in thread
From: Andrew Jones @ 2016-06-14  6:43 UTC (permalink / raw)
  To: David Gibson
  Cc: peter.maydell, ehabkost, qemu-devel, agraf, qemu-arm, qemu-ppc,
	pbonzini, imammedo, dgibson

On Tue, Jun 14, 2016 at 11:28:52AM +1000, David Gibson wrote:
> On Fri, Jun 10, 2016 at 07:40:13PM +0200, Andrew Jones wrote:
> > smp_parse computes missing smp options. Unfortunately cores and
> > threads are computed by dividing smp_cpus, instead of max_cpus.
> > This is incorrect because the topology doesn't leave room for
> > hotplug. More unfortunately, we can't change it easily, as doing
> > so would impact existing command lines. This patch adds a warning
> > when the topology doesn't add up, and then checks that the topology
> > at least computes when sockets are recalculated. If not, then it
> > does fail.
> > 
> > Adding the new failure is justified by the fact that we don't
> > store the number of input sockets, and thus all consumers of
> > cpu topology information recalculate it. If they choose to
> > (correctly) calculate it based on maxcpus, then we need to
> > guard them against building topologies which provide more cpu
> > slots than are the maximum allowed cpus.
> > 
> > Signed-off-by: Andrew Jones <drjones@redhat.com>
> 
> Hmm.. this makes sense to me.  Except that I've never been clear if
> sockets= was supposed to match initial cpus or maxcpus.

The topology we describe in DT and ACPI (at least ACPI) must describe
all possible cpus (maxcpus).

Thanks,
drew

> 
> > ---
> >  vl.c | 19 +++++++++++++++++++
> >  1 file changed, 19 insertions(+)
> > 
> > diff --git a/vl.c b/vl.c
> > index 7b96e787922f9..8d482cb1bf020 100644
> > --- a/vl.c
> > +++ b/vl.c
> > @@ -1227,6 +1227,7 @@ 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 sockets_input = sockets > 0;
> >  
> >          /* compute missing values, prefer sockets over cores over threads */
> >          if (cpus == 0 || sockets == 0) {
> > @@ -1269,6 +1270,24 @@ static void smp_parse(QemuOpts *opts)
> >              exit(1);
> >          }
> >  
> > +        if (sockets_input && sockets * cores * threads != max_cpus) {
> > +            unsigned sockets_rounded = DIV_ROUND_UP(max_cpus, cores * threads);
> > +
> > +            error_report("warning: cpu topology: "
> > +                         "sockets (%u) * cores (%u) * threads (%u) != "
> > +                         "maxcpus (%u). Trying sockets=%u.",
> > +                         sockets, cores, threads, max_cpus, sockets_rounded);
> > +            sockets = sockets_rounded;
> > +
> > +            if (sockets * cores * threads > max_cpus) {
> > +                error_report("cpu topology: "
> > +                             "sockets (%u) * cores (%u) * threads (%u) > "
> > +                             "maxcpus (%u)",
> > +                             sockets, cores, threads, max_cpus);
> > +                exit(1);
> > +            }
> > +        }
> > +
> >          smp_cpus = cpus;
> >          smp_cores = cores;
> >          smp_threads = threads;
> 
> -- 
> David Gibson			| I'll have my music baroque, and my code
> david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
> 				| _way_ _around_!
> http://www.ozlabs.org/~dgibson

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

* Re: [Qemu-devel] [PATCH RFC 06/16] vl: move smp parsing to machine pre_init
  2016-06-13 20:35     ` Andrew Jones
@ 2016-06-14  8:17       ` Paolo Bonzini
  2016-06-14 11:39         ` Andrew Jones
  2016-06-15  0:43         ` David Gibson
  0 siblings, 2 replies; 74+ messages in thread
From: Paolo Bonzini @ 2016-06-14  8:17 UTC (permalink / raw)
  To: Andrew Jones
  Cc: peter.maydell, ehabkost, agraf, qemu-devel, qemu-arm, qemu-ppc,
	imammedo, dgibson, david



On 13/06/2016 22:35, Andrew Jones wrote:
> On Mon, Jun 13, 2016 at 07:04:01PM +0200, Paolo Bonzini wrote:
>> On 10/06/2016 19:40, Andrew Jones wrote:
>>> +    if (sockets == -1 || cores == -1 || threads == -1 ||
>>> +        maxcpus == -1 || cpus == -1) {
>>> +        error_report("cpu topology: "
>>> +                     "all machine properties must be specified");
>>> +        exit(1);
>>> +    }
>>> +
>>
>> I think it's sane to accept some defaults.  It must not be the DWIM
>> thing that -smp does (which is targeted to Windows's dislike of
>> multi-socket machine on consumer hardware).  It must be something that
>> makes sense, and my proposal is:
>>
>> - threads: 1
>> - cores: 1
>> - sockets:
>>   - maxcpus / (cores * threads) if maxcpus given
>>   - cpus / (cores * threads) if cpus given
>>   - else 1
>> - maxcpus: cores * threads * sockets
>> - cpus: maxcpus
> 
> I think some machines may prefer
> 
> - threads: 1
> - sockets: 1
> - cores:
>   - maxcpus / (sockets * threads) if maxcpus given
>   - cpus / (sockets * threads) if cpus given
>   - else 1

smp_cores is only used by pseries and x86 machines.  I expect machines
that must be single-socket to disregard smp_sockets altogether.

>> - any argument < 1
> 
> What if a user says threads=0, because they don't have HT, and assume
> that a value of zero will get them a non-HT system? Or what about
> machines that don't describe sockets, so a user inputs zero? In both
> those cases I agree we should just use 1, but from a user's perspective,
> it might seem weird.

They should just not specify it and get a default of 1. ;)

>> - any argument > some compile-time value (1024?) to avoid overflows
> 
> Agreed. We should do this regardless of this series.
> 
>> - cpus % (cores * threads) != 0
> 
> Hmm. This makes sense where cpus is the number of cpu packages,

I'm not sure I understand what you mean here.  The point is that the
machine starts with an integral number of sockets.

>> - cpus > sockets * cores * threads
>> - maxcpus != cores * threads * sockets
> 
> We check these two (the 2nd added with this series) already.

Yup, I was just making a complete list.

>> Alone the last relation shows that requiring all four of maxcpus, cores,
>> threads and sockets is unnecessary. :)
> 
> Not really. It depends on if you assume sockets, cores or threads to
> be the N in maxcpus=N. We could just require sockets, cores, and threads
> to be input, which allows us to easily calculate maxcpus, and then set
> cpus from that. In that case maxcpus would just be an available input
> for sanity checking.

Or you could just specify -machine cpus=16,maxcpus=32 and expect 1
core/socket, 1 thread/core, and 16 to 32 sockets.

>> -smp should do its legacy magic and assign all five values based on it.
>> If the results do not match the obvious s/smp/-machine/ command line it
>> should warn, and perhaps suggest the equivalent -machine command line.
>> It doesn't have to be a minimal command line, just equivalent.
> 
> This is a good idea. I'm just still not sure what the -machine command
> line should/should not assume.

It's okay.  Adding defaults can be done later, as long as strict checks
are in place from the beginning and there is a clean separation between
-smp defaults and -machine.

Relaxing checks can be done later, so I am much more interested in
having strict checks than in having defaults.

Though I think that we can at least agree on defaults for threads,
maxcpus and cpus.  The only sticky point is sockets vs. cores.  We can
make them both mandatory for now.  That is: cores and sockets are
mandatory until we decide which one to default to 1; threads is
optional; cpus is mandatory if you want hotplug, otherwise it's
redundant; maxcpus is optional and always redundant.

Paolo

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

* Re: [Qemu-devel] [PATCH RFC 06/16] vl: move smp parsing to machine pre_init
  2016-06-14  8:17       ` Paolo Bonzini
@ 2016-06-14 11:39         ` Andrew Jones
  2016-06-14 11:53           ` Paolo Bonzini
  2016-06-15  0:43         ` David Gibson
  1 sibling, 1 reply; 74+ messages in thread
From: Andrew Jones @ 2016-06-14 11:39 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: peter.maydell, ehabkost, qemu-devel, agraf, qemu-arm, qemu-ppc,
	dgibson, imammedo, david

On Tue, Jun 14, 2016 at 10:17:49AM +0200, Paolo Bonzini wrote:
> 
> 
> On 13/06/2016 22:35, Andrew Jones wrote:
> > On Mon, Jun 13, 2016 at 07:04:01PM +0200, Paolo Bonzini wrote:
> >> On 10/06/2016 19:40, Andrew Jones wrote:
> >>> +    if (sockets == -1 || cores == -1 || threads == -1 ||
> >>> +        maxcpus == -1 || cpus == -1) {
> >>> +        error_report("cpu topology: "
> >>> +                     "all machine properties must be specified");
> >>> +        exit(1);
> >>> +    }
> >>> +
> >>
> >> I think it's sane to accept some defaults.  It must not be the DWIM
> >> thing that -smp does (which is targeted to Windows's dislike of
> >> multi-socket machine on consumer hardware).  It must be something that
> >> makes sense, and my proposal is:
> >>
> >> - threads: 1
> >> - cores: 1
> >> - sockets:
> >>   - maxcpus / (cores * threads) if maxcpus given
> >>   - cpus / (cores * threads) if cpus given
> >>   - else 1
> >> - maxcpus: cores * threads * sockets
> >> - cpus: maxcpus
> > 
> > I think some machines may prefer
> > 
> > - threads: 1
> > - sockets: 1
> > - cores:
> >   - maxcpus / (sockets * threads) if maxcpus given
> >   - cpus / (sockets * threads) if cpus given
> >   - else 1
> 
> smp_cores is only used by pseries and x86 machines.  I expect machines
> that must be single-socket to disregard smp_sockets altogether.

mach-virt currently assumes 1 "socket" with N cores when -smp N is used.
This is because, until recently, ARM machines didn't define sockets. I
presume the mindset will remain that cpus=N means cores=N even after
introducing support for multi-socket topology.

> 
> >> - any argument < 1
> > 
> > What if a user says threads=0, because they don't have HT, and assume
> > that a value of zero will get them a non-HT system? Or what about
> > machines that don't describe sockets, so a user inputs zero? In both
> > those cases I agree we should just use 1, but from a user's perspective,
> > it might seem weird.
> 
> They should just not specify it and get a default of 1. ;)

Yeah, threads, the only one we should never calculate, could be
optional. If not specified, defaulting to 1 makes perfect sense.
But, threads=0, which is weird, but in a way specifying that it's
not specified, also makes some sense.

> 
> >> - any argument > some compile-time value (1024?) to avoid overflows
> > 
> > Agreed. We should do this regardless of this series.
> > 
> >> - cpus % (cores * threads) != 0
> > 
> > Hmm. This makes sense where cpus is the number of cpu packages,
> 
> I'm not sure I understand what you mean here.  The point is that the
> machine starts with an integral number of sockets.

OK, s/cpus/maxcpus/ then. By using the currently online number, I
thought you were starting to prepare for cpu packages, which are
indivisible sets of cores and threads. But now that I think about
it, cpus % (cores * threads) isn't right for that either. It should
be total-online-threads % (cores * threads) != 0

> 
> >> - cpus > sockets * cores * threads
> >> - maxcpus != cores * threads * sockets
> > 
> > We check these two (the 2nd added with this series) already.
> 
> Yup, I was just making a complete list.
> 
> >> Alone the last relation shows that requiring all four of maxcpus, cores,
> >> threads and sockets is unnecessary. :)
> > 
> > Not really. It depends on if you assume sockets, cores or threads to
> > be the N in maxcpus=N. We could just require sockets, cores, and threads
> > to be input, which allows us to easily calculate maxcpus, and then set
> > cpus from that. In that case maxcpus would just be an available input
> > for sanity checking.
> 
> Or you could just specify -machine cpus=16,maxcpus=32 and expect 1
> core/socket, 1 thread/core, and 16 to 32 sockets.

Or 32 cores/socket (only 16 populated), 1 thread/core

> 
> >> -smp should do its legacy magic and assign all five values based on it.
> >> If the results do not match the obvious s/smp/-machine/ command line it
> >> should warn, and perhaps suggest the equivalent -machine command line.
> >> It doesn't have to be a minimal command line, just equivalent.
> > 
> > This is a good idea. I'm just still not sure what the -machine command
> > line should/should not assume.
> 
> It's okay.  Adding defaults can be done later, as long as strict checks
> are in place from the beginning and there is a clean separation between
> -smp defaults and -machine.
> 
> Relaxing checks can be done later, so I am much more interested in
> having strict checks than in having defaults.

Yes, my current thinking (which is always adjustable :-) is to start
with strict checks, and maybe always have them in this common code.
Machines that override this can implement defaults based on their
machine-specific knowledge, allowing the user to get sane topologies
without really needing to know what they want.

> 
> Though I think that we can at least agree on defaults for threads,
> maxcpus and cpus.  The only sticky point is sockets vs. cores.  We can
> make them both mandatory for now.  That is: cores and sockets are
> mandatory until we decide which one to default to 1; threads is
> optional; cpus is mandatory if you want hotplug, otherwise it's
> redundant; maxcpus is optional and always redundant.

Agreed. I'll do the following for the next round of this series

 threads: 1
 cores:   required
 sockets: required
 maxcpus: maxcpus ? maxcpus : sockets * cores * threads
 cpus:    cpus ? cpus : maxcpus

If maxcpus is input, it's redundant, but should be sanity checked.
Maybe the user wants to use the QEMU cmdline to check their math...

Thanks,
drew

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

* Re: [Qemu-devel] [PATCH RFC 06/16] vl: move smp parsing to machine pre_init
  2016-06-14 11:39         ` Andrew Jones
@ 2016-06-14 11:53           ` Paolo Bonzini
  2016-06-14 14:03             ` Andrew Jones
  0 siblings, 1 reply; 74+ messages in thread
From: Paolo Bonzini @ 2016-06-14 11:53 UTC (permalink / raw)
  To: Andrew Jones
  Cc: peter.maydell, ehabkost, agraf, qemu-devel, qemu-arm, qemu-ppc,
	imammedo, dgibson, david



On 14/06/2016 13:39, Andrew Jones wrote:
> On Tue, Jun 14, 2016 at 10:17:49AM +0200, Paolo Bonzini wrote:
>> On 13/06/2016 22:35, Andrew Jones wrote:
>>> On Mon, Jun 13, 2016 at 07:04:01PM +0200, Paolo Bonzini wrote:
>>>> On 10/06/2016 19:40, Andrew Jones wrote:
>> They should just not specify it and get a default of 1. ;)
> 
> Yeah, threads, the only one we should never calculate, could be
> optional. If not specified, defaulting to 1 makes perfect sense.
> But, threads=0, which is weird, but in a way specifying that it's
> not specified, also makes some sense.

If it's weird, let's make it invalid. :)

>>>> - cpus % (cores * threads) != 0
>>>
>>> Hmm. This makes sense where cpus is the number of cpu packages,
>>
>> I'm not sure I understand what you mean here.  The point is that the
>> machine starts with an integral number of sockets.
> 
> OK, s/cpus/maxcpus/ then. By using the currently online number, I
> thought you were starting to prepare for cpu packages, which are
> indivisible sets of cores and threads.

Yes, that's what I meant to do.  Isn't cpus what you call
"total-online-threads" below?

> But now that I think about
> it, cpus % (cores * threads) isn't right for that either. It should
> be total-online-threads % (cores * threads) != 0
> 
>> [...] you could just specify -machine cpus=16,maxcpus=32 and expect 1
>> core/socket, 1 thread/core, and 16 to 32 sockets.
> 
> Or 32 cores/socket (only 16 populated), 1 thread/core

Does that make sense?  How do you "populate" parts of a socket lazily? I
know it's all virtual, but... ;)

>> Though I think that we can at least agree on defaults for threads,
>> maxcpus and cpus.  The only sticky point is sockets vs. cores.  We can
>> make them both mandatory for now.  That is: cores and sockets are
>> mandatory until we decide which one to default to 1; threads is
>> optional; cpus is mandatory if you want hotplug, otherwise it's
>> redundant; maxcpus is optional and always redundant.
> 
> Agreed. I'll do the following for the next round of this series
> 
>  threads: 1
>  cores:   required
>  sockets: required
>  maxcpus: maxcpus ? maxcpus : sockets * cores * threads
>  cpus:    cpus ? cpus : maxcpus
> 
> If maxcpus is input, it's redundant, but should be sanity checked.
> Maybe the user wants to use the QEMU cmdline to check their math...

Yes, all this is fine.  As to the checks, here's my list:

>>> - any argument < 1
>>> - any argument > some compile-time value (1024?) to avoid overflows
>>> - cpus % (cores * threads) != 0
>>> - cpus > sockets * cores * threads
>>> - maxcpus != cores * threads * sockets

?  The second, fourth and fifth are fine, and IMO the first too.  What
about the "integral package" check?   It needs to be disabled with some
ugly global when using -smp, but apart from that I believe it's better
to have it.

Paolo

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

* Re: [Qemu-devel] [PATCH RFC 06/16] vl: move smp parsing to machine pre_init
  2016-06-14 11:53           ` Paolo Bonzini
@ 2016-06-14 14:03             ` Andrew Jones
  2016-06-14 14:05               ` Paolo Bonzini
  2016-06-15  0:51               ` David Gibson
  0 siblings, 2 replies; 74+ messages in thread
From: Andrew Jones @ 2016-06-14 14:03 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: peter.maydell, ehabkost, qemu-devel, agraf, qemu-arm, qemu-ppc,
	dgibson, imammedo, david

On Tue, Jun 14, 2016 at 01:53:05PM +0200, Paolo Bonzini wrote:
> 
> 
> On 14/06/2016 13:39, Andrew Jones wrote:
> > On Tue, Jun 14, 2016 at 10:17:49AM +0200, Paolo Bonzini wrote:
> >> On 13/06/2016 22:35, Andrew Jones wrote:
> >>> On Mon, Jun 13, 2016 at 07:04:01PM +0200, Paolo Bonzini wrote:
> >>>> On 10/06/2016 19:40, Andrew Jones wrote:
> >> They should just not specify it and get a default of 1. ;)
> > 
> > Yeah, threads, the only one we should never calculate, could be
> > optional. If not specified, defaulting to 1 makes perfect sense.
> > But, threads=0, which is weird, but in a way specifying that it's
> > not specified, also makes some sense.
> 
> If it's weird, let's make it invalid. :)

I'm weird, and starting to like it :-)

> 
> >>>> - cpus % (cores * threads) != 0
> >>>
> >>> Hmm. This makes sense where cpus is the number of cpu packages,
> >>
> >> I'm not sure I understand what you mean here.  The point is that the
> >> machine starts with an integral number of sockets.
> > 
> > OK, s/cpus/maxcpus/ then. By using the currently online number, I
> > thought you were starting to prepare for cpu packages, which are
> > indivisible sets of cores and threads.
> 
> Yes, that's what I meant to do.  Isn't cpus what you call
> "total-online-threads" below?

It is. I was thinking it may need to be redefined if we wanted to
hotplug these "indivisible sets of cores and threads" (sockets),
instead of what we do today, which is to hotplug one "cpu" at a time.
However, I just chatted with Igor, and he says cpu hotplug operates
on logical processors, and thus it's fine to talk about hotplugging
threads. Even real hardware does this. Real hardware will plug a
socket full of threads, but then the firmware may keep most of them
disabled until they're "hotplugged". So, I think the value of cpus
can be anything. Even the useless value of zero.

> 
> > But now that I think about
> > it, cpus % (cores * threads) isn't right for that either. It should
> > be total-online-threads % (cores * threads) != 0
> > 
> >> [...] you could just specify -machine cpus=16,maxcpus=32 and expect 1
> >> core/socket, 1 thread/core, and 16 to 32 sockets.
> > 
> > Or 32 cores/socket (only 16 populated), 1 thread/core
> 
> Does that make sense?  How do you "populate" parts of a socket lazily? I
> know it's all virtual, but... ;)

In real hardware that would be a socket of 32 cores, 16 disabled.
Hotplug can then enable them one at a time.

> 
> >> Though I think that we can at least agree on defaults for threads,
> >> maxcpus and cpus.  The only sticky point is sockets vs. cores.  We can
> >> make them both mandatory for now.  That is: cores and sockets are
> >> mandatory until we decide which one to default to 1; threads is
> >> optional; cpus is mandatory if you want hotplug, otherwise it's
> >> redundant; maxcpus is optional and always redundant.
> > 
> > Agreed. I'll do the following for the next round of this series
> > 
> >  threads: 1
> >  cores:   required
> >  sockets: required
> >  maxcpus: maxcpus ? maxcpus : sockets * cores * threads
> >  cpus:    cpus ? cpus : maxcpus
> > 
> > If maxcpus is input, it's redundant, but should be sanity checked.
> > Maybe the user wants to use the QEMU cmdline to check their math...
> 
> Yes, all this is fine.  As to the checks, here's my list:
> 
> >>> - any argument < 1
> >>> - any argument > some compile-time value (1024?) to avoid overflows
> >>> - cpus % (cores * threads) != 0
> >>> - cpus > sockets * cores * threads
> >>> - maxcpus != cores * threads * sockets
> 
> ?  The second, fourth and fifth are fine, and IMO the first too.  What
> about the "integral package" check?   It needs to be disabled with some
> ugly global when using -smp, but apart from that I believe it's better
> to have it.

I'd keep =0 allowed. In most cases it just means =1, same as if the
property wasn't input. In some cases, cpus,maxcpus it creates a
useless machine, but maybe could accelerate QEMU runs for the purpose
of probing? Eh, it probably adds more complication than necessary...

Considering cpus should mean logical processors, I think that can
have any value on (0, maxcpus]

Thanks,
drew

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

* Re: [Qemu-devel] [PATCH RFC 06/16] vl: move smp parsing to machine pre_init
  2016-06-14 14:03             ` Andrew Jones
@ 2016-06-14 14:05               ` Paolo Bonzini
  2016-06-15  0:51               ` David Gibson
  1 sibling, 0 replies; 74+ messages in thread
From: Paolo Bonzini @ 2016-06-14 14:05 UTC (permalink / raw)
  To: Andrew Jones
  Cc: peter.maydell, ehabkost, qemu-devel, agraf, qemu-arm, qemu-ppc,
	dgibson, imammedo, david



On 14/06/2016 16:03, Andrew Jones wrote:
> However, I just chatted with Igor, and he says cpu hotplug operates
> on logical processors, and thus it's fine to talk about hotplugging
> threads. Even real hardware does this. Real hardware will plug a
> socket full of threads, but then the firmware may keep most of them
> disabled until they're "hotplugged". So, I think the value of cpus
> can be anything. Even the useless value of zero.

Fair enough!

> I'd keep =0 allowed. In most cases it just means =1, same as if the
> property wasn't input. In some cases, cpus,maxcpus it creates a
> useless machine, but maybe could accelerate QEMU runs for the purpose
> of probing? Eh, it probably adds more complication than necessary...
> Considering cpus should mean logical processors, I think that can
> have any value on (0, maxcpus]

Ok.  The machine can warn if necessary.

Paolo

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

* Re: [Qemu-devel] [PATCH RFC 05/16] hw/core/machine: add smp properites
  2016-06-14  6:08     ` Andrew Jones
@ 2016-06-15  0:37       ` David Gibson
  2016-06-15  7:11         ` Andrew Jones
  0 siblings, 1 reply; 74+ messages in thread
From: David Gibson @ 2016-06-15  0:37 UTC (permalink / raw)
  To: Andrew Jones
  Cc: peter.maydell, ehabkost, qemu-devel, agraf, qemu-arm, qemu-ppc,
	pbonzini, imammedo, dgibson

[-- Attachment #1: Type: text/plain, Size: 7870 bytes --]

On Tue, Jun 14, 2016 at 08:08:07AM +0200, Andrew Jones wrote:
> On Tue, Jun 14, 2016 at 12:00:26PM +1000, David Gibson wrote:
> > On Fri, Jun 10, 2016 at 07:40:16PM +0200, Andrew Jones wrote:
> > > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > > ---
> > >  hw/core/machine.c   | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> > >  include/hw/boards.h |  6 ++++
> > >  2 files changed, 87 insertions(+)
> > > 
> > > diff --git a/hw/core/machine.c b/hw/core/machine.c
> > > index 3dce9020e510a..2625044002e57 100644
> > > --- a/hw/core/machine.c
> > > +++ b/hw/core/machine.c
> > > @@ -172,6 +172,53 @@ static void machine_set_dumpdtb(Object *obj, const char *value, Error **errp)
> > >      ms->dumpdtb = g_strdup(value);
> > >  }
> > >  
> > > +static void machine_get_smp(Object *obj, Visitor *v, const char *name,
> > > +                            void *opaque, Error **errp)
> > > +{
> > > +    MachineState *ms = MACHINE(obj);
> > > +    int64_t value;
> > > +
> > > +    if (strncmp(name, "sockets", 7) == 0) {
> > > +        value = ms->sockets;
> > > +    } else if (strncmp(name, "cores", 5) == 0) {
> > > +        value = ms->cores;
> > > +    } else if (strncmp(name, "threads", 7) == 0) {
> > > +        value = ms->threads;
> > > +    } else if (strncmp(name, "maxcpus", 7) == 0) {
> > > +        value = ms->maxcpus;
> > > +    } else if (strncmp(name, "cpus", 4) == 0) {
> > > +        value = ms->cpus;
> > > +    }
> > > +
> > > +    visit_type_int(v, name, &value, errp);
> > > +}
> > 
> > Any particular for multiplexing all the set / get, rather than having
> > separate callbacks for each property?
> 
> Not really. This way just makes denser code. But I'll go whichever
> direction people prefer.

I'd prefer not to have the multiplexer, but I don't care that much.

> Actually I should probably add an
> else { error_report(...) } in either case, which means the multifunction
> direction would still contain strncmps.

Hrm.. that would seem an odd choice to me if you didn't have the
multiplex.  Not including the strncmp() means you can change the
property name (or add aliases) in a single place, without changing the
callback functions.

Note also that the current set of strncmp()s is only correct because
there is a limited set of things bound to this callback.  Remember
that strncmp(name, "sockets", 7) will match "socketsfoo".

> > > +
> > > +static void machine_set_smp(Object *obj, Visitor *v, const char *name,
> > > +                            void *opaque, Error **errp)
> > > +{
> > > +    MachineState *ms = MACHINE(obj);
> > > +    Error *error = NULL;
> > > +    int64_t value;
> > > +
> > > +    visit_type_int(v, name, &value, &error);
> > > +    if (error) {
> > > +        error_propagate(errp, error);
> > > +        return;
> > > +    }
> > > +
> > > +    if (strncmp(name, "sockets", 7) == 0) {
> > > +        ms->sockets = value;
> > > +    } else if (strncmp(name, "cores", 5) == 0) {
> > > +        ms->cores = value;;
> > > +    } else if (strncmp(name, "threads", 7) == 0) {
> > > +        ms->threads = value;
> > > +    } else if (strncmp(name, "maxcpus", 7) == 0) {
> > > +        ms->maxcpus = value;
> > > +    } else if (strncmp(name, "cpus", 4) == 0) {
> > > +        ms->cpus = value;
> > > +    }
> > > +}
> > > +
> > >  static void machine_get_phandle_start(Object *obj, Visitor *v,
> > >                                        const char *name, void *opaque,
> > >                                        Error **errp)
> > > @@ -368,8 +415,18 @@ static void machine_init_notify(Notifier *notifier, void *data)
> > >      foreach_dynamic_sysbus_device(error_on_sysbus_device, NULL);
> > >  }
> > >  
> > > +static void machine_set_smp_parameters(MachineState *ms)
> > > +{
> > > +    if (ms->sockets != -1 || ms->cores != -1 || ms->threads != -1 ||
> > > +        ms->maxcpus != -1 || ms->cpus != -1) {
> > > +        error_report("warning: cpu topology: "
> > > +                     "machine properties currently ignored");
> > > +    }
> > > +}
> > > +
> > >  static void machine_pre_init(MachineState *ms)
> > >  {
> > > +    machine_set_smp_parameters(ms);
> > >  }
> > >  
> > >  static void machine_class_init(ObjectClass *oc, void *data)
> > > @@ -403,6 +460,11 @@ static void machine_initfn(Object *obj)
> > >      ms->dump_guest_core = true;
> > >      ms->mem_merge = true;
> > >      ms->enable_graphics = true;
> > > +    ms->sockets = -1;
> > > +    ms->cores = -1;
> > > +    ms->threads = -1;
> > > +    ms->maxcpus = -1;
> > > +    ms->cpus = -1;
> > >  
> > >      object_property_add_str(obj, "accel",
> > >                              machine_get_accel, machine_set_accel, NULL);
> > > @@ -462,6 +524,25 @@ static void machine_initfn(Object *obj)
> > >      object_property_set_description(obj, "dt-compatible",
> > >                                      "Overrides the \"compatible\" property of the dt root node",
> > >                                      NULL);
> > > +    object_property_add(obj, "sockets", "int", machine_get_smp,
> > > +                        machine_set_smp, NULL, NULL, NULL);
> > > +    object_property_set_description(obj, "sockets", "Number of sockets", NULL);
> > > +    object_property_add(obj, "cores", "int", machine_get_smp,
> > > +                        machine_set_smp, NULL, NULL, NULL);
> > > +    object_property_set_description(obj, "cores",
> > > +                                    "Number of cores per socket", NULL);
> > > +    object_property_add(obj, "threads", "int", machine_get_smp,
> > > +                        machine_set_smp, NULL, NULL, NULL);
> > > +    object_property_set_description(obj, "threads",
> > > +                                    "Number of threads per core", NULL);
> > > +    object_property_add(obj, "maxcpus", "int", machine_get_smp,
> > > +                        machine_set_smp, NULL, NULL, NULL);
> > > +    object_property_set_description(obj, "maxcpus", "Maximum number of cpus",
> > > +                                    NULL);
> > > +    object_property_add(obj, "cpus", "int", machine_get_smp,
> > > +                        machine_set_smp, NULL, NULL, NULL);
> > > +    object_property_set_description(obj, "cpus", "Number of online cpus",
> > > +                                    NULL);
> > >      object_property_add_bool(obj, "dump-guest-core",
> > >                               machine_get_dump_guest_core,
> > >                               machine_set_dump_guest_core,
> > > diff --git a/include/hw/boards.h b/include/hw/boards.h
> > > index 4e8dc68b07a24..53adbfe2a3099 100644
> > > --- a/include/hw/boards.h
> > > +++ b/include/hw/boards.h
> > > @@ -166,6 +166,12 @@ struct MachineState {
> > >      char *initrd_filename;
> > >      const char *cpu_model;
> > >      AccelState *accelerator;
> > > +
> > > +    int sockets;
> > > +    int cores;
> > > +    int threads;
> > > +    int maxcpus;
> > > +    int cpus;
> > 
> > Hrm.. as the tests added in earlier patches highlight, essentially one
> > of these properties is redundant.  Is there a reason to include them
> > all, rather than to pick one to drop?
> 
> Well, IMO, only maxcpus could be dropped. I'd prefer not to though
> because it's a convenient state to have pre-calculated, and possibly
> error prone to leave to all users to re-calculate.

Sorry, to clarify.  I have no problem with having all 5 variables,
with one precalculated from the others.  What I'm not convinced is a
good idea is exposing all 5 as settable properties.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH RFC 06/16] vl: move smp parsing to machine pre_init
  2016-06-14  8:17       ` Paolo Bonzini
  2016-06-14 11:39         ` Andrew Jones
@ 2016-06-15  0:43         ` David Gibson
  1 sibling, 0 replies; 74+ messages in thread
From: David Gibson @ 2016-06-15  0:43 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Andrew Jones, peter.maydell, ehabkost, agraf, qemu-devel,
	qemu-arm, qemu-ppc, imammedo, dgibson

[-- Attachment #1: Type: text/plain, Size: 1837 bytes --]

On Tue, Jun 14, 2016 at 10:17:49AM +0200, Paolo Bonzini wrote:
> 
> 
> On 13/06/2016 22:35, Andrew Jones wrote:
> > On Mon, Jun 13, 2016 at 07:04:01PM +0200, Paolo Bonzini wrote:
> >> On 10/06/2016 19:40, Andrew Jones wrote:
> >>> +    if (sockets == -1 || cores == -1 || threads == -1 ||
> >>> +        maxcpus == -1 || cpus == -1) {
> >>> +        error_report("cpu topology: "
> >>> +                     "all machine properties must be specified");
> >>> +        exit(1);
> >>> +    }
> >>> +
> >>
> >> I think it's sane to accept some defaults.  It must not be the DWIM
> >> thing that -smp does (which is targeted to Windows's dislike of
> >> multi-socket machine on consumer hardware).  It must be something that
> >> makes sense, and my proposal is:
> >>
> >> - threads: 1
> >> - cores: 1
> >> - sockets:
> >>   - maxcpus / (cores * threads) if maxcpus given
> >>   - cpus / (cores * threads) if cpus given
> >>   - else 1
> >> - maxcpus: cores * threads * sockets
> >> - cpus: maxcpus
> > 
> > I think some machines may prefer
> > 
> > - threads: 1
> > - sockets: 1
> > - cores:
> >   - maxcpus / (sockets * threads) if maxcpus given
> >   - cpus / (sockets * threads) if cpus given
> >   - else 1
> 
> smp_cores is only used by pseries and x86 machines.  I expect machines
> that must be single-socket to disregard smp_sockets altogether.

Note that on pseries (as a purely paravirt platform), the distinction
between cores and sockets is basically meaningless - there is no
important difference between a threads=4,cores=4,sockets=1 machine and
a threads=4,cores=1,sockets=4 machine.s

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH RFC 06/16] vl: move smp parsing to machine pre_init
  2016-06-14 14:03             ` Andrew Jones
  2016-06-14 14:05               ` Paolo Bonzini
@ 2016-06-15  0:51               ` David Gibson
  2016-06-15  7:19                 ` Andrew Jones
  1 sibling, 1 reply; 74+ messages in thread
From: David Gibson @ 2016-06-15  0:51 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Paolo Bonzini, peter.maydell, ehabkost, qemu-devel, agraf,
	qemu-arm, qemu-ppc, dgibson, imammedo

[-- Attachment #1: Type: text/plain, Size: 2873 bytes --]

On Tue, Jun 14, 2016 at 04:03:29PM +0200, Andrew Jones wrote:
> On Tue, Jun 14, 2016 at 01:53:05PM +0200, Paolo Bonzini wrote:
> > 
> > 
> > On 14/06/2016 13:39, Andrew Jones wrote:
> > > On Tue, Jun 14, 2016 at 10:17:49AM +0200, Paolo Bonzini wrote:
> > >> On 13/06/2016 22:35, Andrew Jones wrote:
> > >>> On Mon, Jun 13, 2016 at 07:04:01PM +0200, Paolo Bonzini wrote:
> > >>>> On 10/06/2016 19:40, Andrew Jones wrote:
> > >> They should just not specify it and get a default of 1. ;)
> > > 
> > > Yeah, threads, the only one we should never calculate, could be
> > > optional. If not specified, defaulting to 1 makes perfect sense.
> > > But, threads=0, which is weird, but in a way specifying that it's
> > > not specified, also makes some sense.
> > 
> > If it's weird, let's make it invalid. :)
> 
> I'm weird, and starting to like it :-)
> 
> > 
> > >>>> - cpus % (cores * threads) != 0
> > >>>
> > >>> Hmm. This makes sense where cpus is the number of cpu packages,
> > >>
> > >> I'm not sure I understand what you mean here.  The point is that the
> > >> machine starts with an integral number of sockets.
> > > 
> > > OK, s/cpus/maxcpus/ then. By using the currently online number, I
> > > thought you were starting to prepare for cpu packages, which are
> > > indivisible sets of cores and threads.
> > 
> > Yes, that's what I meant to do.  Isn't cpus what you call
> > "total-online-threads" below?
> 
> It is. I was thinking it may need to be redefined if we wanted to
> hotplug these "indivisible sets of cores and threads" (sockets),
> instead of what we do today, which is to hotplug one "cpu" at a time.
> However, I just chatted with Igor, and he says cpu hotplug operates
> on logical processors, and thus it's fine to talk about hotplugging
> threads. Even real hardware does this. Real hardware will plug a
> socket full of threads, but then the firmware may keep most of them
> disabled until they're "hotplugged". So, I think the value of cpus
> can be anything. Even the useless value of zero.

Uh.. this depends on the platform (machine type).  ACPI allows
(logical) hotplugging of individual threads.  However on pseries the
hotplug mechanism works at core granularity only.  I don't know of
real examples off hand, but it's easy to imagine a platform interface
which worked at socket, or even a multi-socket-module level

In other words the "cpu package" doesn't necessarily lie at a fixed
level of the thread/core/socket heirarchy.

This is something we're grappling with in trying to implement
cross-platform cpu hotplug, and we obviously don't want to make it
worse with these -smp changes.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties
  2016-06-14  6:19         ` Andrew Jones
@ 2016-06-15  0:56           ` David Gibson
  2016-07-14 20:07             ` Eduardo Habkost
  0 siblings, 1 reply; 74+ messages in thread
From: David Gibson @ 2016-06-15  0:56 UTC (permalink / raw)
  To: Andrew Jones
  Cc: peter.maydell, Thomas Huth, ehabkost, imammedo, qemu-devel,
	agraf, qemu-arm, qemu-ppc, Bharata B Rao, pbonzini, dgibson

[-- Attachment #1: Type: text/plain, Size: 4220 bytes --]

On Tue, Jun 14, 2016 at 08:19:49AM +0200, Andrew Jones wrote:
> On Tue, Jun 14, 2016 at 12:12:16PM +1000, David Gibson wrote:
> > On Sun, Jun 12, 2016 at 03:48:10PM +0200, Andrew Jones wrote:
> > > On Sat, Jun 11, 2016 at 08:54:35AM +0200, Thomas Huth wrote:
> > > > On 10.06.2016 19:40, Andrew Jones wrote:
> > > > > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > > > > ---
> > > > >  qom/cpu.c | 8 ++++++++
> > > > >  1 file changed, 8 insertions(+)
> > > > > 
> > > > > diff --git a/qom/cpu.c b/qom/cpu.c
> > > > > index 751e992de8823..024cda3eb98c8 100644
> > > > > --- a/qom/cpu.c
> > > > > +++ b/qom/cpu.c
> > > > > @@ -28,6 +28,7 @@
> > > > >  #include "exec/log.h"
> > > > >  #include "qemu/error-report.h"
> > > > >  #include "sysemu/sysemu.h"
> > > > > +#include "hw/qdev-properties.h"
> > > > >  
> > > > >  bool cpu_exists(int64_t id)
> > > > >  {
> > > > > @@ -342,6 +343,12 @@ static int64_t cpu_common_get_arch_id(CPUState *cpu)
> > > > >      return cpu->cpu_index;
> > > > >  }
> > > > >  
> > > > > +static Property cpu_common_properties[] = {
> > > > > +    DEFINE_PROP_INT32("nr-cores", CPUState, nr_cores, 1),
> > > > > +    DEFINE_PROP_INT32("nr-threads", CPUState, nr_threads, 1),
> > > > > +    DEFINE_PROP_END_OF_LIST()
> > > > > +};
> > > > 
> > > > Are you aware of the current CPU hotplug discussion that is going on?
> > > 
> > > I'm aware of it going on, but haven't been following it.
> > > 
> > > > I'm not very involved there, but I think some of these reworks also move
> > > > "nr_threads" into the CPU state already, e.g. see:
> > > 
> > > nr_threads (and nr_cores) are already state in CPUState. This patch just
> > > exposes that state via properties.
> > > 
> > > > 
> > > > https://github.com/dgibson/qemu/commit/9d07719784ecbeebea71
> > > > 
> > > > ... so you might want to check these patches first to see whether you
> > > > can base your rework on them?
> > > 
> > > Every cpu, and thus every machine, uses CPUState for its cpus. I'm
> > > not sure every machine will want to use that new abstract core class
> > > though. If they did, then we could indeed use nr_threads from there
> > > instead (and remove it from CPUState), but we'd still need nr_cores
> > > from the abstract cpu package class (CPUState).
> > 
> > Hmm.  Since the CPUState object represents just a single thread, it
> > seems weird to me that it would have nr_threads and nr_cores
> > information.
> > 
> > Exposing those as properties makes that much worse, because it's now
> > ABI, rather than internal detail we can clean up at some future time.
> 
> CPUState is supposed to be "State of one CPU core or thread", which
> justifies having nr_threads state, as it may be describing a core.

Um.. does it ever actually represent a (multithread) core in practice?
It would need to have duplicated register state for every thread were
that the case.

> I guess there's no justification for having nr_cores in there though.
> I agree adding the Core class is a good idea, assuming it will get used
> by all machines, and CPUState then gets changed to a Thread class. The
> question then, though, is do we also create a Socket class that contains
> nr_cores?

That was roughly our intention with the way the cross platform hotplug
stuff is evolving.  But the intention was that the Socket objects
would only need to be constructed for machine types where it makes
sense.  So for example on the paravirt pseries platform, we'll only
have Core objects, because the socket distinction isn't really
meaningful.

> And how will a Thread method get that information when it
> needs to emulate, e.g. CPUID, that requires it? It's a bit messy, so
> I'm open to all suggestions on it.

So, if the Thread needs this information, I'm not opposed to it having
it internally (presumably populated earlier from the Core object).
But I am opposed to it being a locked in part of the interface by
having it as an exposed property.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH RFC 10/16] hw/ppc/spapr: don't use smp_cores, smp_threads
  2016-06-14  6:23     ` Andrew Jones
@ 2016-06-15  0:59       ` David Gibson
  2016-06-15  7:34         ` Andrew Jones
  0 siblings, 1 reply; 74+ messages in thread
From: David Gibson @ 2016-06-15  0:59 UTC (permalink / raw)
  To: Andrew Jones
  Cc: peter.maydell, ehabkost, qemu-devel, agraf, qemu-arm, qemu-ppc,
	pbonzini, imammedo, dgibson

[-- Attachment #1: Type: text/plain, Size: 4253 bytes --]

On Tue, Jun 14, 2016 at 08:23:08AM +0200, Andrew Jones wrote:
> On Tue, Jun 14, 2016 at 01:03:41PM +1000, David Gibson wrote:
> > On Fri, Jun 10, 2016 at 07:40:21PM +0200, Andrew Jones wrote:
> > > Use CPUState nr_cores,nr_threads and MachineState
> > > cores,threads instead.
> > > 
> > > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > > ---
> > >  hw/ppc/spapr.c      | 9 +++++----
> > >  hw/ppc/spapr_rtas.c | 2 +-
> > >  2 files changed, 6 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > > index 063664234106e..f78276bb4b164 100644
> > > --- a/hw/ppc/spapr.c
> > > +++ b/hw/ppc/spapr.c
> > > @@ -35,7 +35,6 @@
> > >  #include "net/net.h"
> > >  #include "sysemu/device_tree.h"
> > >  #include "sysemu/block-backend.h"
> > > -#include "sysemu/cpus.h"
> > >  #include "sysemu/kvm.h"
> > >  #include "sysemu/device_tree.h"
> > >  #include "kvm_ppc.h"
> > > @@ -603,7 +602,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
> > >      uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 1000000000;
> > >      uint32_t page_sizes_prop[64];
> > >      size_t page_sizes_prop_size;
> > > -    uint32_t vcpus_per_socket = smp_threads * smp_cores;
> > > +    uint32_t vcpus_per_socket = cs->nr_cores * cs->nr_threads;

This function has an 'spapr' parameter which is a subcloss of
MachineState, so you can get to the machine value from there.

> > >      uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)};
> > >  
> > >      /* Note: we keep CI large pages off for now because a 64K capable guest
> > > @@ -1774,7 +1773,7 @@ static void ppc_spapr_init(MachineState *machine)
> > >      /* Set up Interrupt Controller before we create the VCPUs */
> > >      spapr->icp = xics_system_init(machine,
> > >                                    DIV_ROUND_UP(max_cpus * kvmppc_smt_threads(),
> > > -                                               smp_threads),
> > > +                                               machine->threads),
> > >                                    XICS_IRQS, &error_fatal);
> > >  
> > >      if (smc->dr_lmb_enabled) {
> > > @@ -2268,9 +2267,11 @@ static HotplugHandler *spapr_get_hotpug_handler(MachineState *machine,
> > >  
> > >  static unsigned spapr_cpu_index_to_socket_id(unsigned cpu_index)
> > >  {
> > > +    CPUState *cs = first_cpu;
> > > +
> > >      /* Allocate to NUMA nodes on a "socket" basis (not that concept of
> > >       * socket means much for the paravirtualized PAPR platform) */
> > > -    return cpu_index / smp_threads / smp_cores;
> > > +    return cpu_index / cs->nr_cores / cs->nr_threads;

Here you can use qdev_get_machine().  That's no more an ugly use of a
global than using first_cpu.

> > >  }
> > >  
> > >  static void spapr_machine_class_init(ObjectClass *oc, void *data)
> > > diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
> > > index 43e2c684fda8d..3fdfbb01a20dd 100644
> > > --- a/hw/ppc/spapr_rtas.c
> > > +++ b/hw/ppc/spapr_rtas.c
> > > @@ -742,7 +742,7 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
> > >      lrdr_capacity[1] = cpu_to_be32(max_hotplug_addr & 0xffffffff);
> > >      lrdr_capacity[2] = 0;
> > >      lrdr_capacity[3] = cpu_to_be32(SPAPR_MEMORY_BLOCK_SIZE);
> > > -    lrdr_capacity[4] = cpu_to_be32(max_cpus/smp_threads);
> > > +    lrdr_capacity[4] = cpu_to_be32(max_cpus / machine->threads);
> > >      ret = qemu_fdt_setprop(fdt, "/rtas", "ibm,lrdr-capacity", lrdr_capacity,
> > >                       sizeof(lrdr_capacity));
> > >      if (ret < 0) {
> > 
> > I think all the places that use cs->nr_* here it actually makes more
> > sense to use the value in the machine state.
> 
> I think I used machine state whenever I (easily) could. How do I get to
> machine state from a CPU method? I will if I can, for all machines,
> and then gladly kill the CPUState->nr_cores/nr_threads.

I can't speak to all machines, but notes above on how it can be done
for spapr.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH RFC 05/16] hw/core/machine: add smp properites
  2016-06-15  0:37       ` David Gibson
@ 2016-06-15  7:11         ` Andrew Jones
  2016-07-14 20:18           ` Eduardo Habkost
  0 siblings, 1 reply; 74+ messages in thread
From: Andrew Jones @ 2016-06-15  7:11 UTC (permalink / raw)
  To: David Gibson
  Cc: peter.maydell, ehabkost, agraf, qemu-devel, qemu-arm, qemu-ppc,
	imammedo, pbonzini, dgibson

On Wed, Jun 15, 2016 at 10:37:59AM +1000, David Gibson wrote:
> On Tue, Jun 14, 2016 at 08:08:07AM +0200, Andrew Jones wrote:
> > On Tue, Jun 14, 2016 at 12:00:26PM +1000, David Gibson wrote:
> > > On Fri, Jun 10, 2016 at 07:40:16PM +0200, Andrew Jones wrote:
> > > > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > > > ---
> > > >  hw/core/machine.c   | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> > > >  include/hw/boards.h |  6 ++++
> > > >  2 files changed, 87 insertions(+)
> > > > 
> > > > diff --git a/hw/core/machine.c b/hw/core/machine.c
> > > > index 3dce9020e510a..2625044002e57 100644
> > > > --- a/hw/core/machine.c
> > > > +++ b/hw/core/machine.c
> > > > @@ -172,6 +172,53 @@ static void machine_set_dumpdtb(Object *obj, const char *value, Error **errp)
> > > >      ms->dumpdtb = g_strdup(value);
> > > >  }
> > > >  
> > > > +static void machine_get_smp(Object *obj, Visitor *v, const char *name,
> > > > +                            void *opaque, Error **errp)
> > > > +{
> > > > +    MachineState *ms = MACHINE(obj);
> > > > +    int64_t value;
> > > > +
> > > > +    if (strncmp(name, "sockets", 7) == 0) {
> > > > +        value = ms->sockets;
> > > > +    } else if (strncmp(name, "cores", 5) == 0) {
> > > > +        value = ms->cores;
> > > > +    } else if (strncmp(name, "threads", 7) == 0) {
> > > > +        value = ms->threads;
> > > > +    } else if (strncmp(name, "maxcpus", 7) == 0) {
> > > > +        value = ms->maxcpus;
> > > > +    } else if (strncmp(name, "cpus", 4) == 0) {
> > > > +        value = ms->cpus;
> > > > +    }
> > > > +
> > > > +    visit_type_int(v, name, &value, errp);
> > > > +}
> > > 
> > > Any particular for multiplexing all the set / get, rather than having
> > > separate callbacks for each property?
> > 
> > Not really. This way just makes denser code. But I'll go whichever
> > direction people prefer.
> 
> I'd prefer not to have the multiplexer, but I don't care that much.
> 
> > Actually I should probably add an
> > else { error_report(...) } in either case, which means the multifunction
> > direction would still contain strncmps.
> 
> Hrm.. that would seem an odd choice to me if you didn't have the
> multiplex.  Not including the strncmp() means you can change the
> property name (or add aliases) in a single place, without changing the
> callback functions.
> 
> Note also that the current set of strncmp()s is only correct because
> there is a limited set of things bound to this callback.  Remember
> that strncmp(name, "sockets", 7) will match "socketsfoo".

Good point. I'll change to multiple functions and just drop the
strncmps.

> 
> > > > +
> > > > +static void machine_set_smp(Object *obj, Visitor *v, const char *name,
> > > > +                            void *opaque, Error **errp)
> > > > +{
> > > > +    MachineState *ms = MACHINE(obj);
> > > > +    Error *error = NULL;
> > > > +    int64_t value;
> > > > +
> > > > +    visit_type_int(v, name, &value, &error);
> > > > +    if (error) {
> > > > +        error_propagate(errp, error);
> > > > +        return;
> > > > +    }
> > > > +
> > > > +    if (strncmp(name, "sockets", 7) == 0) {
> > > > +        ms->sockets = value;
> > > > +    } else if (strncmp(name, "cores", 5) == 0) {
> > > > +        ms->cores = value;;
> > > > +    } else if (strncmp(name, "threads", 7) == 0) {
> > > > +        ms->threads = value;
> > > > +    } else if (strncmp(name, "maxcpus", 7) == 0) {
> > > > +        ms->maxcpus = value;
> > > > +    } else if (strncmp(name, "cpus", 4) == 0) {
> > > > +        ms->cpus = value;
> > > > +    }
> > > > +}
> > > > +
> > > >  static void machine_get_phandle_start(Object *obj, Visitor *v,
> > > >                                        const char *name, void *opaque,
> > > >                                        Error **errp)
> > > > @@ -368,8 +415,18 @@ static void machine_init_notify(Notifier *notifier, void *data)
> > > >      foreach_dynamic_sysbus_device(error_on_sysbus_device, NULL);
> > > >  }
> > > >  
> > > > +static void machine_set_smp_parameters(MachineState *ms)
> > > > +{
> > > > +    if (ms->sockets != -1 || ms->cores != -1 || ms->threads != -1 ||
> > > > +        ms->maxcpus != -1 || ms->cpus != -1) {
> > > > +        error_report("warning: cpu topology: "
> > > > +                     "machine properties currently ignored");
> > > > +    }
> > > > +}
> > > > +
> > > >  static void machine_pre_init(MachineState *ms)
> > > >  {
> > > > +    machine_set_smp_parameters(ms);
> > > >  }
> > > >  
> > > >  static void machine_class_init(ObjectClass *oc, void *data)
> > > > @@ -403,6 +460,11 @@ static void machine_initfn(Object *obj)
> > > >      ms->dump_guest_core = true;
> > > >      ms->mem_merge = true;
> > > >      ms->enable_graphics = true;
> > > > +    ms->sockets = -1;
> > > > +    ms->cores = -1;
> > > > +    ms->threads = -1;
> > > > +    ms->maxcpus = -1;
> > > > +    ms->cpus = -1;
> > > >  
> > > >      object_property_add_str(obj, "accel",
> > > >                              machine_get_accel, machine_set_accel, NULL);
> > > > @@ -462,6 +524,25 @@ static void machine_initfn(Object *obj)
> > > >      object_property_set_description(obj, "dt-compatible",
> > > >                                      "Overrides the \"compatible\" property of the dt root node",
> > > >                                      NULL);
> > > > +    object_property_add(obj, "sockets", "int", machine_get_smp,
> > > > +                        machine_set_smp, NULL, NULL, NULL);
> > > > +    object_property_set_description(obj, "sockets", "Number of sockets", NULL);
> > > > +    object_property_add(obj, "cores", "int", machine_get_smp,
> > > > +                        machine_set_smp, NULL, NULL, NULL);
> > > > +    object_property_set_description(obj, "cores",
> > > > +                                    "Number of cores per socket", NULL);
> > > > +    object_property_add(obj, "threads", "int", machine_get_smp,
> > > > +                        machine_set_smp, NULL, NULL, NULL);
> > > > +    object_property_set_description(obj, "threads",
> > > > +                                    "Number of threads per core", NULL);
> > > > +    object_property_add(obj, "maxcpus", "int", machine_get_smp,
> > > > +                        machine_set_smp, NULL, NULL, NULL);
> > > > +    object_property_set_description(obj, "maxcpus", "Maximum number of cpus",
> > > > +                                    NULL);
> > > > +    object_property_add(obj, "cpus", "int", machine_get_smp,
> > > > +                        machine_set_smp, NULL, NULL, NULL);
> > > > +    object_property_set_description(obj, "cpus", "Number of online cpus",
> > > > +                                    NULL);
> > > >      object_property_add_bool(obj, "dump-guest-core",
> > > >                               machine_get_dump_guest_core,
> > > >                               machine_set_dump_guest_core,
> > > > diff --git a/include/hw/boards.h b/include/hw/boards.h
> > > > index 4e8dc68b07a24..53adbfe2a3099 100644
> > > > --- a/include/hw/boards.h
> > > > +++ b/include/hw/boards.h
> > > > @@ -166,6 +166,12 @@ struct MachineState {
> > > >      char *initrd_filename;
> > > >      const char *cpu_model;
> > > >      AccelState *accelerator;
> > > > +
> > > > +    int sockets;
> > > > +    int cores;
> > > > +    int threads;
> > > > +    int maxcpus;
> > > > +    int cpus;
> > > 
> > > Hrm.. as the tests added in earlier patches highlight, essentially one
> > > of these properties is redundant.  Is there a reason to include them
> > > all, rather than to pick one to drop?
> > 
> > Well, IMO, only maxcpus could be dropped. I'd prefer not to though
> > because it's a convenient state to have pre-calculated, and possibly
> > error prone to leave to all users to re-calculate.
> 
> Sorry, to clarify.  I have no problem with having all 5 variables,
> with one precalculated from the others.  What I'm not convinced is a
> good idea is exposing all 5 as settable properties.

I see. I think we need them all, especially as we decide which ones
can be optional, if given others. For example we need cpus and maxcpus
for obvious reasons. threads can be optional (default =1), but if you
want to specify more than 1 then we need the property. Currently I
think both sockets and cores should be required since we don't know
which should be calculated form the other, and therefore can't set
a default for either. That's all five.

Thanks,
drew

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

* Re: [Qemu-devel] [PATCH RFC 06/16] vl: move smp parsing to machine pre_init
  2016-06-15  0:51               ` David Gibson
@ 2016-06-15  7:19                 ` Andrew Jones
  0 siblings, 0 replies; 74+ messages in thread
From: Andrew Jones @ 2016-06-15  7:19 UTC (permalink / raw)
  To: David Gibson
  Cc: peter.maydell, ehabkost, imammedo, qemu-devel, agraf, qemu-arm,
	qemu-ppc, dgibson, Paolo Bonzini

On Wed, Jun 15, 2016 at 10:51:08AM +1000, David Gibson wrote:
> On Tue, Jun 14, 2016 at 04:03:29PM +0200, Andrew Jones wrote:
> > On Tue, Jun 14, 2016 at 01:53:05PM +0200, Paolo Bonzini wrote:
> > > 
> > > 
> > > On 14/06/2016 13:39, Andrew Jones wrote:
> > > > On Tue, Jun 14, 2016 at 10:17:49AM +0200, Paolo Bonzini wrote:
> > > >> On 13/06/2016 22:35, Andrew Jones wrote:
> > > >>> On Mon, Jun 13, 2016 at 07:04:01PM +0200, Paolo Bonzini wrote:
> > > >>>> On 10/06/2016 19:40, Andrew Jones wrote:
> > > >> They should just not specify it and get a default of 1. ;)
> > > > 
> > > > Yeah, threads, the only one we should never calculate, could be
> > > > optional. If not specified, defaulting to 1 makes perfect sense.
> > > > But, threads=0, which is weird, but in a way specifying that it's
> > > > not specified, also makes some sense.
> > > 
> > > If it's weird, let's make it invalid. :)
> > 
> > I'm weird, and starting to like it :-)
> > 
> > > 
> > > >>>> - cpus % (cores * threads) != 0
> > > >>>
> > > >>> Hmm. This makes sense where cpus is the number of cpu packages,
> > > >>
> > > >> I'm not sure I understand what you mean here.  The point is that the
> > > >> machine starts with an integral number of sockets.
> > > > 
> > > > OK, s/cpus/maxcpus/ then. By using the currently online number, I
> > > > thought you were starting to prepare for cpu packages, which are
> > > > indivisible sets of cores and threads.
> > > 
> > > Yes, that's what I meant to do.  Isn't cpus what you call
> > > "total-online-threads" below?
> > 
> > It is. I was thinking it may need to be redefined if we wanted to
> > hotplug these "indivisible sets of cores and threads" (sockets),
> > instead of what we do today, which is to hotplug one "cpu" at a time.
> > However, I just chatted with Igor, and he says cpu hotplug operates
> > on logical processors, and thus it's fine to talk about hotplugging
> > threads. Even real hardware does this. Real hardware will plug a
> > socket full of threads, but then the firmware may keep most of them
> > disabled until they're "hotplugged". So, I think the value of cpus
> > can be anything. Even the useless value of zero.
> 
> Uh.. this depends on the platform (machine type).  ACPI allows
> (logical) hotplugging of individual threads.  However on pseries the
> hotplug mechanism works at core granularity only.  I don't know of
> real examples off hand, but it's easy to imagine a platform interface
> which worked at socket, or even a multi-socket-module level
> 
> In other words the "cpu package" doesn't necessarily lie at a fixed
> level of the thread/core/socket heirarchy.
> 
> This is something we're grappling with in trying to implement
> cross-platform cpu hotplug, and we obviously don't want to make it
> worse with these -smp changes.

Right now we're bringing hotplug up in this discussion purely to set
the largest range of inputs for each of the five properties, in
order to do a first pass of sanity checks. If a particular machine
has a stricter range for a given property then it's free to override
pre-init and do what it likes. If pre-init gets used for non-smp
related stuff in the future then we'll make a specific smp-init machine
method, allowing smp init to always be easily overridden by machines.

Thanks,
drew

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

* Re: [Qemu-devel] [PATCH RFC 10/16] hw/ppc/spapr: don't use smp_cores, smp_threads
  2016-06-15  0:59       ` David Gibson
@ 2016-06-15  7:34         ` Andrew Jones
  0 siblings, 0 replies; 74+ messages in thread
From: Andrew Jones @ 2016-06-15  7:34 UTC (permalink / raw)
  To: David Gibson
  Cc: peter.maydell, ehabkost, agraf, qemu-devel, qemu-arm, qemu-ppc,
	imammedo, pbonzini, dgibson

On Wed, Jun 15, 2016 at 10:59:01AM +1000, David Gibson wrote:
> On Tue, Jun 14, 2016 at 08:23:08AM +0200, Andrew Jones wrote:
> > On Tue, Jun 14, 2016 at 01:03:41PM +1000, David Gibson wrote:
> > > On Fri, Jun 10, 2016 at 07:40:21PM +0200, Andrew Jones wrote:
> > > > Use CPUState nr_cores,nr_threads and MachineState
> > > > cores,threads instead.
> > > > 
> > > > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > > > ---
> > > >  hw/ppc/spapr.c      | 9 +++++----
> > > >  hw/ppc/spapr_rtas.c | 2 +-
> > > >  2 files changed, 6 insertions(+), 5 deletions(-)
> > > > 
> > > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > > > index 063664234106e..f78276bb4b164 100644
> > > > --- a/hw/ppc/spapr.c
> > > > +++ b/hw/ppc/spapr.c
> > > > @@ -35,7 +35,6 @@
> > > >  #include "net/net.h"
> > > >  #include "sysemu/device_tree.h"
> > > >  #include "sysemu/block-backend.h"
> > > > -#include "sysemu/cpus.h"
> > > >  #include "sysemu/kvm.h"
> > > >  #include "sysemu/device_tree.h"
> > > >  #include "kvm_ppc.h"
> > > > @@ -603,7 +602,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
> > > >      uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 1000000000;
> > > >      uint32_t page_sizes_prop[64];
> > > >      size_t page_sizes_prop_size;
> > > > -    uint32_t vcpus_per_socket = smp_threads * smp_cores;
> > > > +    uint32_t vcpus_per_socket = cs->nr_cores * cs->nr_threads;
> 
> This function has an 'spapr' parameter which is a subcloss of
> MachineState, so you can get to the machine value from there.
> 
> > > >      uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)};
> > > >  
> > > >      /* Note: we keep CI large pages off for now because a 64K capable guest
> > > > @@ -1774,7 +1773,7 @@ static void ppc_spapr_init(MachineState *machine)
> > > >      /* Set up Interrupt Controller before we create the VCPUs */
> > > >      spapr->icp = xics_system_init(machine,
> > > >                                    DIV_ROUND_UP(max_cpus * kvmppc_smt_threads(),
> > > > -                                               smp_threads),
> > > > +                                               machine->threads),
> > > >                                    XICS_IRQS, &error_fatal);
> > > >  
> > > >      if (smc->dr_lmb_enabled) {
> > > > @@ -2268,9 +2267,11 @@ static HotplugHandler *spapr_get_hotpug_handler(MachineState *machine,
> > > >  
> > > >  static unsigned spapr_cpu_index_to_socket_id(unsigned cpu_index)
> > > >  {
> > > > +    CPUState *cs = first_cpu;
> > > > +
> > > >      /* Allocate to NUMA nodes on a "socket" basis (not that concept of
> > > >       * socket means much for the paravirtualized PAPR platform) */
> > > > -    return cpu_index / smp_threads / smp_cores;
> > > > +    return cpu_index / cs->nr_cores / cs->nr_threads;
> 
> Here you can use qdev_get_machine().  That's no more an ugly use of a
> global than using first_cpu.
> 
> > > >  }
> > > >  
> > > >  static void spapr_machine_class_init(ObjectClass *oc, void *data)
> > > > diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
> > > > index 43e2c684fda8d..3fdfbb01a20dd 100644
> > > > --- a/hw/ppc/spapr_rtas.c
> > > > +++ b/hw/ppc/spapr_rtas.c
> > > > @@ -742,7 +742,7 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
> > > >      lrdr_capacity[1] = cpu_to_be32(max_hotplug_addr & 0xffffffff);
> > > >      lrdr_capacity[2] = 0;
> > > >      lrdr_capacity[3] = cpu_to_be32(SPAPR_MEMORY_BLOCK_SIZE);
> > > > -    lrdr_capacity[4] = cpu_to_be32(max_cpus/smp_threads);
> > > > +    lrdr_capacity[4] = cpu_to_be32(max_cpus / machine->threads);
> > > >      ret = qemu_fdt_setprop(fdt, "/rtas", "ibm,lrdr-capacity", lrdr_capacity,
> > > >                       sizeof(lrdr_capacity));
> > > >      if (ret < 0) {
> > > 
> > > I think all the places that use cs->nr_* here it actually makes more
> > > sense to use the value in the machine state.
> > 
> > I think I used machine state whenever I (easily) could. How do I get to
> > machine state from a CPU method? I will if I can, for all machines,
> > and then gladly kill the CPUState->nr_cores/nr_threads.
> 
> I can't speak to all machines, but notes above on how it can be done
> for spapr.

Sounds good. I'll try to find ways to avoid CPUState nr-cores,nr-threads
and just kill those too if possible.

Thanks,
drew

> 
> -- 
> David Gibson			| I'll have my music baroque, and my code
> david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
> 				| _way_ _around_!
> http://www.ozlabs.org/~dgibson

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

* Re: [Qemu-devel] [PATCH RFC 03/16] hw/smbios/smbios: fix number of sockets calculation
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 03/16] hw/smbios/smbios: fix number of sockets calculation Andrew Jones
@ 2016-07-11 14:23   ` Igor Mammedov
  0 siblings, 0 replies; 74+ messages in thread
From: Igor Mammedov @ 2016-07-11 14:23 UTC (permalink / raw)
  To: Andrew Jones
  Cc: qemu-devel, qemu-ppc, qemu-arm, ehabkost, pbonzini,
	peter.maydell, david, dgibson, agraf

On Fri, 10 Jun 2016 19:40:14 +0200
Andrew Jones <drjones@redhat.com> wrote:

> The specification "sect. 7.5 Processor Information (Type 4)" says
>  "NOTE One structure is provided for each processor instance in a
>   system. For example, a system that supports up to two processors
>   includes two Processor Information structures - even if only one
>   processor is currently installed..."
> 
> We should use max_cpus in the calculation. The rounding is still
> necessary, since smp_cores and smp_threads may have been calculated
> based on smp_cpus, rather than max_cpus. The rounding is safe,
> because smp_parse will fail when the result produces a topology
> supporting more cpus than max_cpus.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>

> ---
>  hw/smbios/smbios.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
> index cb8a1111029cf..cf18ecfd8599c 100644
> --- a/hw/smbios/smbios.c
> +++ b/hw/smbios/smbios.c
> @@ -881,7 +881,7 @@ void smbios_get_tables(const struct smbios_phys_mem_area *mem_array,
>          smbios_build_type_2_table();
>          smbios_build_type_3_table();
>  
> -        smbios_smp_sockets = DIV_ROUND_UP(smp_cpus, smp_cores * smp_threads);
> +        smbios_smp_sockets = DIV_ROUND_UP(max_cpus, smp_cores * smp_threads);
>          assert(smbios_smp_sockets >= 1);
>  
>          for (i = 0; i < smbios_smp_sockets; i++) {

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

* Re: [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters
  2016-06-10 17:40 [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Andrew Jones
                   ` (17 preceding siblings ...)
  2016-06-12 14:03 ` Andrew Jones
@ 2016-07-14  9:16 ` Andrew Jones
  18 siblings, 0 replies; 74+ messages in thread
From: Andrew Jones @ 2016-07-14  9:16 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc, qemu-arm
  Cc: peter.maydell, ehabkost, agraf, pbonzini, dgibson, imammedo, david


Eduardo,

ping?

I'd like to spin a v1 soon, but have been putting it off until
I can get some input from you about this RFC.

Thanks,
drew


On Fri, Jun 10, 2016 at 07:40:11PM +0200, Andrew Jones wrote:
> This series is a first step in eliminating smp_* global
> variables (the last patch gets rid of two of them!) And, it's
> a first step in deprecating '-smp' in favor of using machine
> properties, e.g.
>  qemu -machine pc,sockets=2,cores=2,threads=2,maxcpus=8,cpus=8 ...
> 
> It's also a first step in allowing machine types to override
> the default parameter parsing, which makes assumptions that
> not all machine types may agree with. (mach-virt is coming...)
> 
> So, three first steps, I guess that's 3 steps. And a forth
> thing it does is some fixes for the smp parsing and also for
> SMBIOS use of cpu topology.
> 
> Tested with kvm-unit-tests on all five arches supported
> there, x86_64 both with KVM and TCG, and booting an x86_64
> guest (KVM) to check SMBIOS before and after in order to make
> sure it was the same. Also compile tested all targets.
> 
> Thanks,
> drew
> 
> 
> Andrew Jones (15):
>   vl: smp_parse: cleanups
>   vl: smp: add checks for maxcpus based topologies
>   hw/smbios/smbios: fix number of sockets calculation
>   hw/core/machine: add smp properites
>   vl: move smp parsing to machine pre_init
>   qom/cpu: make nr-cores,nr-threads real properties
>   hw/core/machine: set cpu global nr_cores,nr_threads in pre_init
>   hw/i386/pc: don't use smp_cores,smp_threads
>   hw/ppc/spapr: don't use smp_cores,smp_threads
>   target-ppc: don't use smp_threads
>   hw/arm/virt: rename *.smp_cpus to *.cpus
>   hw/arm/virt: don't use smp_cpus,max_cpus
>   hw/arm/virt: stash cpu topo info in VirtGuestInfo
>   smbios: don't use smp_cores,smp_threads
>   sysemu/cpus: bye, bye smp_cores,smp_threads
> 
> Igor Mammedov (1):
>   hw/core/machine: Introduce pre_init
> 
>  cpus.c                           |   2 -
>  hw/arm/virt-acpi-build.c         |  14 +--
>  hw/arm/virt.c                    |  41 +++++---
>  hw/core/machine.c                | 210 +++++++++++++++++++++++++++++++++++++++
>  hw/i386/pc.c                     |  39 +++++---
>  hw/ppc/spapr.c                   |   9 +-
>  hw/ppc/spapr_rtas.c              |   2 +-
>  hw/smbios/smbios.c               |  20 ++--
>  include/hw/arm/virt-acpi-build.h |   6 +-
>  include/hw/boards.h              |   7 ++
>  include/hw/smbios/smbios.h       |  10 ++
>  include/sysemu/cpus.h            |  10 --
>  qom/cpu.c                        |   8 ++
>  target-ppc/translate_init.c      |  15 ++-
>  vl.c                             | 101 +++++++------------
>  15 files changed, 356 insertions(+), 138 deletions(-)
> 
> -- 
> 2.4.11
> 
> 

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

* Re: [Qemu-devel] [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties
  2016-06-15  0:56           ` David Gibson
@ 2016-07-14 20:07             ` Eduardo Habkost
  2016-07-15  6:35               ` Andrew Jones
  0 siblings, 1 reply; 74+ messages in thread
From: Eduardo Habkost @ 2016-07-14 20:07 UTC (permalink / raw)
  To: David Gibson
  Cc: Andrew Jones, peter.maydell, Thomas Huth, pbonzini, qemu-devel,
	agraf, qemu-arm, qemu-ppc, Bharata B Rao, imammedo, dgibson


First of all, sorry for the horrible delay in replying to this
thread.

On Wed, Jun 15, 2016 at 10:56:20AM +1000, David Gibson wrote:
> On Tue, Jun 14, 2016 at 08:19:49AM +0200, Andrew Jones wrote:
> > On Tue, Jun 14, 2016 at 12:12:16PM +1000, David Gibson wrote:
> > > On Sun, Jun 12, 2016 at 03:48:10PM +0200, Andrew Jones wrote:
> > > > On Sat, Jun 11, 2016 at 08:54:35AM +0200, Thomas Huth wrote:
> > > > > On 10.06.2016 19:40, Andrew Jones wrote:
> > > > > > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > > > > > ---
> > > > > >  qom/cpu.c | 8 ++++++++
> > > > > >  1 file changed, 8 insertions(+)
> > > > > > 
> > > > > > diff --git a/qom/cpu.c b/qom/cpu.c
> > > > > > index 751e992de8823..024cda3eb98c8 100644
> > > > > > --- a/qom/cpu.c
> > > > > > +++ b/qom/cpu.c
> > > > > > @@ -28,6 +28,7 @@
> > > > > >  #include "exec/log.h"
> > > > > >  #include "qemu/error-report.h"
> > > > > >  #include "sysemu/sysemu.h"
> > > > > > +#include "hw/qdev-properties.h"
> > > > > >  
> > > > > >  bool cpu_exists(int64_t id)
> > > > > >  {
> > > > > > @@ -342,6 +343,12 @@ static int64_t cpu_common_get_arch_id(CPUState *cpu)
> > > > > >      return cpu->cpu_index;
> > > > > >  }
> > > > > >  
> > > > > > +static Property cpu_common_properties[] = {
> > > > > > +    DEFINE_PROP_INT32("nr-cores", CPUState, nr_cores, 1),
> > > > > > +    DEFINE_PROP_INT32("nr-threads", CPUState, nr_threads, 1),
> > > > > > +    DEFINE_PROP_END_OF_LIST()
> > > > > > +};
> > > > > 
> > > > > Are you aware of the current CPU hotplug discussion that is going on?
> > > > 
> > > > I'm aware of it going on, but haven't been following it.
> > > > 
> > > > > I'm not very involved there, but I think some of these reworks also move
> > > > > "nr_threads" into the CPU state already, e.g. see:
> > > > 
> > > > nr_threads (and nr_cores) are already state in CPUState. This patch just
> > > > exposes that state via properties.
> > > > 
> > > > > 
> > > > > https://github.com/dgibson/qemu/commit/9d07719784ecbeebea71
> > > > > 
> > > > > ... so you might want to check these patches first to see whether you
> > > > > can base your rework on them?
> > > > 
> > > > Every cpu, and thus every machine, uses CPUState for its cpus. I'm
> > > > not sure every machine will want to use that new abstract core class
> > > > though. If they did, then we could indeed use nr_threads from there
> > > > instead (and remove it from CPUState), but we'd still need nr_cores
> > > > from the abstract cpu package class (CPUState).
> > > 
> > > Hmm.  Since the CPUState object represents just a single thread, it
> > > seems weird to me that it would have nr_threads and nr_cores
> > > information.

Agreed it is weird, and I think we should try to move it away
from CPUState, not make it part of the TYPE_CPU interface.
nr_threads belongs to the actual container of the Thread objects,
and nr_cores in the actual container of the Core objects.

The problem is how to implement that in a non-intrusive way that
would require changing the object hierarchy of all architectures.


> > > 
> > > Exposing those as properties makes that much worse, because it's now
> > > ABI, rather than internal detail we can clean up at some future time.
> > 
> > CPUState is supposed to be "State of one CPU core or thread", which
> > justifies having nr_threads state, as it may be describing a core.
> 
> Um.. does it ever actually represent a (multithread) core in practice?
> It would need to have duplicated register state for every thread were
> that the case.

AFAIK, CPUState is still always thread state. Or has this changed
in some architectures, already?

> 
> > I guess there's no justification for having nr_cores in there though.
> > I agree adding the Core class is a good idea, assuming it will get used
> > by all machines, and CPUState then gets changed to a Thread class. The
> > question then, though, is do we also create a Socket class that contains
> > nr_cores?
> 
> That was roughly our intention with the way the cross platform hotplug
> stuff is evolving.  But the intention was that the Socket objects
> would only need to be constructed for machine types where it makes
> sense.  So for example on the paravirt pseries platform, we'll only
> have Core objects, because the socket distinction isn't really
> meaningful.
> 
> > And how will a Thread method get that information when it
> > needs to emulate, e.g. CPUID, that requires it? It's a bit messy, so
> > I'm open to all suggestions on it.
> 
> So, if the Thread needs this information, I'm not opposed to it having
> it internally (presumably populated earlier from the Core object).
> But I am opposed to it being a locked in part of the interface by
> having it as an exposed property.

I agree we don't want to make this part of the external
interface. In this case, if we don't add the properties, how
exactly is the Machine or Core code supposed to pass that
information to the Thread object?

Maybe the intermediate steps could be:

* Make the Thread code that uses CPUState::nr_{cores,threads} and
  smp_{cores,threads} get that info from MachineState instead.
* On the architectures where we already have a reasonable
  Socket/Core/Thread hierarchy, let the Thread code simply ask
  for that information from its parent.

-- 
Eduardo

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

* Re: [Qemu-devel] [PATCH RFC 04/16] hw/core/machine: Introduce pre_init
  2016-06-14  5:58     ` Andrew Jones
@ 2016-07-14 20:10       ` Eduardo Habkost
  2016-07-15  6:26         ` Andrew Jones
  0 siblings, 1 reply; 74+ messages in thread
From: Eduardo Habkost @ 2016-07-14 20:10 UTC (permalink / raw)
  To: Andrew Jones
  Cc: David Gibson, peter.maydell, agraf, qemu-devel, qemu-arm,
	qemu-ppc, imammedo, pbonzini, dgibson

On Tue, Jun 14, 2016 at 07:58:56AM +0200, Andrew Jones wrote:
> On Tue, Jun 14, 2016 at 11:30:37AM +1000, David Gibson wrote:
> > On Fri, Jun 10, 2016 at 07:40:15PM +0200, Andrew Jones wrote:
> > > From: Igor Mammedov <imammedo@redhat.com>
> > > 
> > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > 
> > I think this needs some kind of rationale.
> > 
> > Since with this patch it is called immediately before ->init, I'm not
> > really seeing the point of this.
> 
> Many machines already override ->init, so if we want to move code
> from vl.c into machine methods, but be sure that they run it now,
> then we have to invent a pre-init. I (or Igor) can add something
> like that to the commit message for the next round.

If we just want to move vl.c code into machine, why not just
create a simple machine_pre_init() function?

We can add a virtual method that can be reimplemented by
subclasses later, only when we really see the need for a subclass
to override some behavior.

-- 
Eduardo

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

* Re: [Qemu-devel] [PATCH RFC 05/16] hw/core/machine: add smp properites
  2016-06-15  7:11         ` Andrew Jones
@ 2016-07-14 20:18           ` Eduardo Habkost
  2016-07-15  6:29             ` Andrew Jones
  0 siblings, 1 reply; 74+ messages in thread
From: Eduardo Habkost @ 2016-07-14 20:18 UTC (permalink / raw)
  To: Andrew Jones
  Cc: David Gibson, peter.maydell, qemu-devel, agraf, qemu-arm,
	qemu-ppc, pbonzini, imammedo, dgibson

On Wed, Jun 15, 2016 at 09:11:13AM +0200, Andrew Jones wrote:
> On Wed, Jun 15, 2016 at 10:37:59AM +1000, David Gibson wrote:
> > On Tue, Jun 14, 2016 at 08:08:07AM +0200, Andrew Jones wrote:
> > > On Tue, Jun 14, 2016 at 12:00:26PM +1000, David Gibson wrote:
> > > > On Fri, Jun 10, 2016 at 07:40:16PM +0200, Andrew Jones wrote:
> > > > > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > > > > ---
> > > > >  hw/core/machine.c   | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> > > > >  include/hw/boards.h |  6 ++++
> > > > >  2 files changed, 87 insertions(+)
> > > > > 
> > > > > diff --git a/hw/core/machine.c b/hw/core/machine.c
> > > > > index 3dce9020e510a..2625044002e57 100644
> > > > > --- a/hw/core/machine.c
> > > > > +++ b/hw/core/machine.c
> > > > > @@ -172,6 +172,53 @@ static void machine_set_dumpdtb(Object *obj, const char *value, Error **errp)
> > > > >      ms->dumpdtb = g_strdup(value);
> > > > >  }
> > > > >  
> > > > > +static void machine_get_smp(Object *obj, Visitor *v, const char *name,
> > > > > +                            void *opaque, Error **errp)
> > > > > +{
> > > > > +    MachineState *ms = MACHINE(obj);
> > > > > +    int64_t value;
> > > > > +
> > > > > +    if (strncmp(name, "sockets", 7) == 0) {
> > > > > +        value = ms->sockets;
> > > > > +    } else if (strncmp(name, "cores", 5) == 0) {
> > > > > +        value = ms->cores;
> > > > > +    } else if (strncmp(name, "threads", 7) == 0) {
> > > > > +        value = ms->threads;
> > > > > +    } else if (strncmp(name, "maxcpus", 7) == 0) {
> > > > > +        value = ms->maxcpus;
> > > > > +    } else if (strncmp(name, "cpus", 4) == 0) {
> > > > > +        value = ms->cpus;
> > > > > +    }
> > > > > +
> > > > > +    visit_type_int(v, name, &value, errp);
> > > > > +}
> > > > 
> > > > Any particular for multiplexing all the set / get, rather than having
> > > > separate callbacks for each property?
> > > 
> > > Not really. This way just makes denser code. But I'll go whichever
> > > direction people prefer.
> > 
> > I'd prefer not to have the multiplexer, but I don't care that much.
> > 
> > > Actually I should probably add an
> > > else { error_report(...) } in either case, which means the multifunction
> > > direction would still contain strncmps.
> > 
> > Hrm.. that would seem an odd choice to me if you didn't have the
> > multiplex.  Not including the strncmp() means you can change the
> > property name (or add aliases) in a single place, without changing the
> > callback functions.
> > 
> > Note also that the current set of strncmp()s is only correct because
> > there is a limited set of things bound to this callback.  Remember
> > that strncmp(name, "sockets", 7) will match "socketsfoo".
> 
> Good point. I'll change to multiple functions and just drop the
> strncmps.

Multiple functions that just get/set struct fields would be
easier to convert to use a better property API (that don't
require writing getter/setters) in the future.

[...]
> > > > > +
> > > > > +    int sockets;
> > > > > +    int cores;
> > > > > +    int threads;
> > > > > +    int maxcpus;
> > > > > +    int cpus;
> > > > 
> > > > Hrm.. as the tests added in earlier patches highlight, essentially one
> > > > of these properties is redundant.  Is there a reason to include them
> > > > all, rather than to pick one to drop?
> > > 
> > > Well, IMO, only maxcpus could be dropped. I'd prefer not to though
> > > because it's a convenient state to have pre-calculated, and possibly
> > > error prone to leave to all users to re-calculate.
> > 
> > Sorry, to clarify.  I have no problem with having all 5 variables,
> > with one precalculated from the others.  What I'm not convinced is a
> > good idea is exposing all 5 as settable properties.
> 
> I see. I think we need them all, especially as we decide which ones
> can be optional, if given others. For example we need cpus and maxcpus
> for obvious reasons. threads can be optional (default =1), but if you
> want to specify more than 1 then we need the property. Currently I
> think both sockets and cores should be required since we don't know
> which should be calculated form the other, and therefore can't set
> a default for either. That's all five.

If we were designing a new interface, I would prefer to make it
different, and add properties only to machine classes that really
make this configurable. But as we are just moving existing data
and logic from vl.c into MachineState fields, I agree we need all
the struct fields, so the existing vl.c code can be easily moved
to machine.c.

But:

About the new externally-visible interface: what about we
register the properties only on the machine subclasses that
really do something with those options? Then we won't need to
worry about keeping compatibility in machines that never
supported multi-core/multi-thread configurations in the first
place.

-- 
Eduardo

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

* Re: [Qemu-devel] [PATCH RFC 09/16] hw/i386/pc: don't use smp_cores, smp_threads
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 09/16] hw/i386/pc: don't use smp_cores, smp_threads Andrew Jones
@ 2016-07-14 20:33   ` Eduardo Habkost
  0 siblings, 0 replies; 74+ messages in thread
From: Eduardo Habkost @ 2016-07-14 20:33 UTC (permalink / raw)
  To: Andrew Jones
  Cc: qemu-devel, qemu-ppc, qemu-arm, peter.maydell, agraf, pbonzini,
	dgibson, imammedo, david

On Fri, Jun 10, 2016 at 07:40:20PM +0200, Andrew Jones wrote:
[...]
> @@ -1940,9 +1943,10 @@ static void pc_machine_reset(void)
>  
>  static unsigned pc_cpu_index_to_socket_id(unsigned cpu_index)
>  {
> +    CPUState *cs = first_cpu;

Eww.

>      X86CPUTopoInfo topo;
> -    x86_topo_ids_from_idx(smp_cores, smp_threads, cpu_index,
> -                          &topo);
> +
> +    x86_topo_ids_from_idx(cs->nr_cores, cs->nr_threads, cpu_index, &topo);

If first_cpu is already available[1], then current_machine would
also be available. Better to use the new MachineState fields you
added, than the CPUState::nr_{cores,threads} fields that
shouldn't have existed in the first place.

[1] Is it really available? This function is called very early,
    from parse_numa_opts(). I think current_machine is already
    available, though. But we need to ensure parse_numa_opts()
    will be called only after SMP option parsing is done and SMP
    topology data in MachineState is already populated.

    Later, we could also make the NUMA option parsing not depend
    on SMP parsing to be done first. The cpu_index_to_socket_id()
    magic can be moved to numa_post_machine_init(), probably.

-- 
Eduardo

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

* Re: [Qemu-devel] [PATCH RFC 14/16] hw/arm/virt: stash cpu topo info in VirtGuestInfo
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 14/16] hw/arm/virt: stash cpu topo info in VirtGuestInfo Andrew Jones
@ 2016-07-14 20:43   ` Eduardo Habkost
  2016-07-15  6:40     ` Andrew Jones
  0 siblings, 1 reply; 74+ messages in thread
From: Eduardo Habkost @ 2016-07-14 20:43 UTC (permalink / raw)
  To: Andrew Jones
  Cc: qemu-devel, qemu-ppc, qemu-arm, peter.maydell, agraf, pbonzini,
	dgibson, imammedo, david

On Fri, Jun 10, 2016 at 07:40:25PM +0200, Andrew Jones wrote:
> This is a first step to preparing mach-virt for configurable
> cpu topology, and is necessary now to prepare to move smbios
> code away from using cpu topology globals smp_cores,smp_threads.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>

I'd rather put a MachineState pointer inside VirtGuestInfo, and
eventually eliminate VirtGuestInfo completely (like we already
did with PCGuestInfo in x86).

> ---
>  hw/arm/virt.c                    | 6 +++++-
>  include/hw/arm/virt-acpi-build.h | 4 ++++
>  2 files changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index 134b6e36623ba..769a49aa5be77 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -1281,7 +1281,11 @@ static void machvirt_init(MachineState *machine)
>      create_fw_cfg(vbi, &address_space_memory);
>      rom_set_fw(fw_cfg_find());
>  
> -    guest_info->cpus = vbi->cpus;
> +    guest_info->sockets = machine->sockets;
> +    guest_info->cores   = machine->cores;
> +    guest_info->threads = machine->threads;
> +    guest_info->maxcpus = machine->maxcpus;
> +    guest_info->cpus    = machine->cpus;
>      guest_info->fw_cfg = fw_cfg_find();
>      guest_info->memmap = vbi->memmap;
>      guest_info->irqmap = vbi->irqmap;
> diff --git a/include/hw/arm/virt-acpi-build.h b/include/hw/arm/virt-acpi-build.h
> index d6c5982960403..a34fb04230e66 100644
> --- a/include/hw/arm/virt-acpi-build.h
> +++ b/include/hw/arm/virt-acpi-build.h
> @@ -27,6 +27,10 @@
>  #define ACPI_GICC_ENABLED 1
>  
>  typedef struct VirtGuestInfo {
> +    int sockets;
> +    int cores;
> +    int threads;
> +    int maxcpus;
>      int cpus;
>      FWCfgState *fw_cfg;
>      const MemMapEntry *memmap;
> -- 
> 2.4.11
> 
> 

-- 
Eduardo

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

* Re: [Qemu-devel] [PATCH RFC 15/16] smbios: don't use smp_cores, smp_threads
  2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 15/16] smbios: don't use smp_cores, smp_threads Andrew Jones
@ 2016-07-14 20:51   ` Eduardo Habkost
  2016-07-15  6:45     ` Andrew Jones
  0 siblings, 1 reply; 74+ messages in thread
From: Eduardo Habkost @ 2016-07-14 20:51 UTC (permalink / raw)
  To: Andrew Jones
  Cc: qemu-devel, qemu-ppc, qemu-arm, peter.maydell, agraf, pbonzini,
	dgibson, imammedo, david

On Fri, Jun 10, 2016 at 07:40:26PM +0200, Andrew Jones wrote:
> SMBIOS needs cpu topology for Type4 tables, so we need to pass
> it in. There are several parameters so we use a structure. There
> are two callers (of non-legacy, which generates Type4 tables),
> x86 and arm, so we also update both to pass the topology
> parameters from their MachineState properties (directly in the
> case of x86, indirectly through VirtGuestInfo in the case of arm).
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
[...]
> @@ -701,12 +701,19 @@ static uint32_t x86_cpu_apic_id_from_index(MachineState *ms,
>      }
>  }
>  
> -static void pc_build_smbios(FWCfgState *fw_cfg)
> +static void pc_build_smbios(MachineState *ms, FWCfgState *fw_cfg)
>  {
>      uint8_t *smbios_tables, *smbios_anchor;
>      size_t smbios_tables_len, smbios_anchor_len;
>      struct smbios_phys_mem_area *mem_array;
>      unsigned i, array_count;
> +    struct smbios_cpu_topology topo = {
> +        .sockets = ms->sockets,
> +        .cores   = ms->cores,
> +        .threads = ms->threads,
> +        .maxcpus = ms->maxcpus,
> +        .cpus    = ms->cpus,
> +    };
>  

Do we really need to manually copy data around this way when
smbios.c could just use qdev_get_machine() directly?

-- 
Eduardo

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

* Re: [Qemu-devel] [PATCH RFC 04/16] hw/core/machine: Introduce pre_init
  2016-07-14 20:10       ` Eduardo Habkost
@ 2016-07-15  6:26         ` Andrew Jones
  0 siblings, 0 replies; 74+ messages in thread
From: Andrew Jones @ 2016-07-15  6:26 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: peter.maydell, qemu-devel, agraf, qemu-arm, qemu-ppc, pbonzini,
	imammedo, dgibson, David Gibson

On Thu, Jul 14, 2016 at 05:10:47PM -0300, Eduardo Habkost wrote:
> On Tue, Jun 14, 2016 at 07:58:56AM +0200, Andrew Jones wrote:
> > On Tue, Jun 14, 2016 at 11:30:37AM +1000, David Gibson wrote:
> > > On Fri, Jun 10, 2016 at 07:40:15PM +0200, Andrew Jones wrote:
> > > > From: Igor Mammedov <imammedo@redhat.com>
> > > > 
> > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > > 
> > > I think this needs some kind of rationale.
> > > 
> > > Since with this patch it is called immediately before ->init, I'm not
> > > really seeing the point of this.
> > 
> > Many machines already override ->init, so if we want to move code
> > from vl.c into machine methods, but be sure that they run it now,
> > then we have to invent a pre-init. I (or Igor) can add something
> > like that to the commit message for the next round.
> 
> If we just want to move vl.c code into machine, why not just
> create a simple machine_pre_init() function?
> 
> We can add a virtual method that can be reimplemented by
> subclasses later, only when we really see the need for a subclass
> to override some behavior.

That's fine for this series. Of course one of the main motivators
of this series is to be able to override the old parsing though, so
I already see the need. I'll need to either add this method now, or
later, when I add cpu topo support to the ARM mach-virt machine type.

Thanks,
drew

> 
> -- 
> Eduardo
> 

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

* Re: [Qemu-devel] [PATCH RFC 05/16] hw/core/machine: add smp properites
  2016-07-14 20:18           ` Eduardo Habkost
@ 2016-07-15  6:29             ` Andrew Jones
  0 siblings, 0 replies; 74+ messages in thread
From: Andrew Jones @ 2016-07-15  6:29 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: peter.maydell, agraf, qemu-devel, qemu-arm, qemu-ppc, imammedo,
	pbonzini, dgibson, David Gibson

On Thu, Jul 14, 2016 at 05:18:20PM -0300, Eduardo Habkost wrote:
> On Wed, Jun 15, 2016 at 09:11:13AM +0200, Andrew Jones wrote:
> > On Wed, Jun 15, 2016 at 10:37:59AM +1000, David Gibson wrote:
> > > On Tue, Jun 14, 2016 at 08:08:07AM +0200, Andrew Jones wrote:
> > > > On Tue, Jun 14, 2016 at 12:00:26PM +1000, David Gibson wrote:
> > > > > On Fri, Jun 10, 2016 at 07:40:16PM +0200, Andrew Jones wrote:
> > > > > > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > > > > > ---
> > > > > >  hw/core/machine.c   | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> > > > > >  include/hw/boards.h |  6 ++++
> > > > > >  2 files changed, 87 insertions(+)
> > > > > > 
> > > > > > diff --git a/hw/core/machine.c b/hw/core/machine.c
> > > > > > index 3dce9020e510a..2625044002e57 100644
> > > > > > --- a/hw/core/machine.c
> > > > > > +++ b/hw/core/machine.c
> > > > > > @@ -172,6 +172,53 @@ static void machine_set_dumpdtb(Object *obj, const char *value, Error **errp)
> > > > > >      ms->dumpdtb = g_strdup(value);
> > > > > >  }
> > > > > >  
> > > > > > +static void machine_get_smp(Object *obj, Visitor *v, const char *name,
> > > > > > +                            void *opaque, Error **errp)
> > > > > > +{
> > > > > > +    MachineState *ms = MACHINE(obj);
> > > > > > +    int64_t value;
> > > > > > +
> > > > > > +    if (strncmp(name, "sockets", 7) == 0) {
> > > > > > +        value = ms->sockets;
> > > > > > +    } else if (strncmp(name, "cores", 5) == 0) {
> > > > > > +        value = ms->cores;
> > > > > > +    } else if (strncmp(name, "threads", 7) == 0) {
> > > > > > +        value = ms->threads;
> > > > > > +    } else if (strncmp(name, "maxcpus", 7) == 0) {
> > > > > > +        value = ms->maxcpus;
> > > > > > +    } else if (strncmp(name, "cpus", 4) == 0) {
> > > > > > +        value = ms->cpus;
> > > > > > +    }
> > > > > > +
> > > > > > +    visit_type_int(v, name, &value, errp);
> > > > > > +}
> > > > > 
> > > > > Any particular for multiplexing all the set / get, rather than having
> > > > > separate callbacks for each property?
> > > > 
> > > > Not really. This way just makes denser code. But I'll go whichever
> > > > direction people prefer.
> > > 
> > > I'd prefer not to have the multiplexer, but I don't care that much.
> > > 
> > > > Actually I should probably add an
> > > > else { error_report(...) } in either case, which means the multifunction
> > > > direction would still contain strncmps.
> > > 
> > > Hrm.. that would seem an odd choice to me if you didn't have the
> > > multiplex.  Not including the strncmp() means you can change the
> > > property name (or add aliases) in a single place, without changing the
> > > callback functions.
> > > 
> > > Note also that the current set of strncmp()s is only correct because
> > > there is a limited set of things bound to this callback.  Remember
> > > that strncmp(name, "sockets", 7) will match "socketsfoo".
> > 
> > Good point. I'll change to multiple functions and just drop the
> > strncmps.
> 
> Multiple functions that just get/set struct fields would be
> easier to convert to use a better property API (that don't
> require writing getter/setters) in the future.
> 
> [...]
> > > > > > +
> > > > > > +    int sockets;
> > > > > > +    int cores;
> > > > > > +    int threads;
> > > > > > +    int maxcpus;
> > > > > > +    int cpus;
> > > > > 
> > > > > Hrm.. as the tests added in earlier patches highlight, essentially one
> > > > > of these properties is redundant.  Is there a reason to include them
> > > > > all, rather than to pick one to drop?
> > > > 
> > > > Well, IMO, only maxcpus could be dropped. I'd prefer not to though
> > > > because it's a convenient state to have pre-calculated, and possibly
> > > > error prone to leave to all users to re-calculate.
> > > 
> > > Sorry, to clarify.  I have no problem with having all 5 variables,
> > > with one precalculated from the others.  What I'm not convinced is a
> > > good idea is exposing all 5 as settable properties.
> > 
> > I see. I think we need them all, especially as we decide which ones
> > can be optional, if given others. For example we need cpus and maxcpus
> > for obvious reasons. threads can be optional (default =1), but if you
> > want to specify more than 1 then we need the property. Currently I
> > think both sockets and cores should be required since we don't know
> > which should be calculated form the other, and therefore can't set
> > a default for either. That's all five.
> 
> If we were designing a new interface, I would prefer to make it
> different, and add properties only to machine classes that really
> make this configurable. But as we are just moving existing data
> and logic from vl.c into MachineState fields, I agree we need all
> the struct fields, so the existing vl.c code can be easily moved
> to machine.c.
> 
> But:
> 
> About the new externally-visible interface: what about we
> register the properties only on the machine subclasses that
> really do something with those options? Then we won't need to
> worry about keeping compatibility in machines that never
> supported multi-core/multi-thread configurations in the first
> place.

I like that. I'll look into it for v1.

Thanks,
drew

> 
> -- 
> Eduardo
> 

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

* Re: [Qemu-devel] [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties
  2016-07-14 20:07             ` Eduardo Habkost
@ 2016-07-15  6:35               ` Andrew Jones
  2016-07-15  9:11                 ` Igor Mammedov
  0 siblings, 1 reply; 74+ messages in thread
From: Andrew Jones @ 2016-07-15  6:35 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: David Gibson, peter.maydell, imammedo, qemu-devel, agraf,
	qemu-arm, qemu-ppc, Bharata B Rao, Thomas Huth, pbonzini,
	dgibson

On Thu, Jul 14, 2016 at 05:07:43PM -0300, Eduardo Habkost wrote:
> 
> First of all, sorry for the horrible delay in replying to this
> thread.
> 
> On Wed, Jun 15, 2016 at 10:56:20AM +1000, David Gibson wrote:
> > On Tue, Jun 14, 2016 at 08:19:49AM +0200, Andrew Jones wrote:
> > > On Tue, Jun 14, 2016 at 12:12:16PM +1000, David Gibson wrote:
> > > > On Sun, Jun 12, 2016 at 03:48:10PM +0200, Andrew Jones wrote:
> > > > > On Sat, Jun 11, 2016 at 08:54:35AM +0200, Thomas Huth wrote:
> > > > > > On 10.06.2016 19:40, Andrew Jones wrote:
> > > > > > > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > > > > > > ---
> > > > > > >  qom/cpu.c | 8 ++++++++
> > > > > > >  1 file changed, 8 insertions(+)
> > > > > > > 
> > > > > > > diff --git a/qom/cpu.c b/qom/cpu.c
> > > > > > > index 751e992de8823..024cda3eb98c8 100644
> > > > > > > --- a/qom/cpu.c
> > > > > > > +++ b/qom/cpu.c
> > > > > > > @@ -28,6 +28,7 @@
> > > > > > >  #include "exec/log.h"
> > > > > > >  #include "qemu/error-report.h"
> > > > > > >  #include "sysemu/sysemu.h"
> > > > > > > +#include "hw/qdev-properties.h"
> > > > > > >  
> > > > > > >  bool cpu_exists(int64_t id)
> > > > > > >  {
> > > > > > > @@ -342,6 +343,12 @@ static int64_t cpu_common_get_arch_id(CPUState *cpu)
> > > > > > >      return cpu->cpu_index;
> > > > > > >  }
> > > > > > >  
> > > > > > > +static Property cpu_common_properties[] = {
> > > > > > > +    DEFINE_PROP_INT32("nr-cores", CPUState, nr_cores, 1),
> > > > > > > +    DEFINE_PROP_INT32("nr-threads", CPUState, nr_threads, 1),
> > > > > > > +    DEFINE_PROP_END_OF_LIST()
> > > > > > > +};
> > > > > > 
> > > > > > Are you aware of the current CPU hotplug discussion that is going on?
> > > > > 
> > > > > I'm aware of it going on, but haven't been following it.
> > > > > 
> > > > > > I'm not very involved there, but I think some of these reworks also move
> > > > > > "nr_threads" into the CPU state already, e.g. see:
> > > > > 
> > > > > nr_threads (and nr_cores) are already state in CPUState. This patch just
> > > > > exposes that state via properties.
> > > > > 
> > > > > > 
> > > > > > https://github.com/dgibson/qemu/commit/9d07719784ecbeebea71
> > > > > > 
> > > > > > ... so you might want to check these patches first to see whether you
> > > > > > can base your rework on them?
> > > > > 
> > > > > Every cpu, and thus every machine, uses CPUState for its cpus. I'm
> > > > > not sure every machine will want to use that new abstract core class
> > > > > though. If they did, then we could indeed use nr_threads from there
> > > > > instead (and remove it from CPUState), but we'd still need nr_cores
> > > > > from the abstract cpu package class (CPUState).
> > > > 
> > > > Hmm.  Since the CPUState object represents just a single thread, it
> > > > seems weird to me that it would have nr_threads and nr_cores
> > > > information.
> 
> Agreed it is weird, and I think we should try to move it away
> from CPUState, not make it part of the TYPE_CPU interface.
> nr_threads belongs to the actual container of the Thread objects,
> and nr_cores in the actual container of the Core objects.
> 
> The problem is how to implement that in a non-intrusive way that
> would require changing the object hierarchy of all architectures.
> 
> 
> > > > 
> > > > Exposing those as properties makes that much worse, because it's now
> > > > ABI, rather than internal detail we can clean up at some future time.
> > > 
> > > CPUState is supposed to be "State of one CPU core or thread", which
> > > justifies having nr_threads state, as it may be describing a core.
> > 
> > Um.. does it ever actually represent a (multithread) core in practice?
> > It would need to have duplicated register state for every thread were
> > that the case.
> 
> AFAIK, CPUState is still always thread state. Or has this changed
> in some architectures, already?
> 
> > 
> > > I guess there's no justification for having nr_cores in there though.
> > > I agree adding the Core class is a good idea, assuming it will get used
> > > by all machines, and CPUState then gets changed to a Thread class. The
> > > question then, though, is do we also create a Socket class that contains
> > > nr_cores?
> > 
> > That was roughly our intention with the way the cross platform hotplug
> > stuff is evolving.  But the intention was that the Socket objects
> > would only need to be constructed for machine types where it makes
> > sense.  So for example on the paravirt pseries platform, we'll only
> > have Core objects, because the socket distinction isn't really
> > meaningful.
> > 
> > > And how will a Thread method get that information when it
> > > needs to emulate, e.g. CPUID, that requires it? It's a bit messy, so
> > > I'm open to all suggestions on it.
> > 
> > So, if the Thread needs this information, I'm not opposed to it having
> > it internally (presumably populated earlier from the Core object).
> > But I am opposed to it being a locked in part of the interface by
> > having it as an exposed property.
> 
> I agree we don't want to make this part of the external
> interface. In this case, if we don't add the properties, how
> exactly is the Machine or Core code supposed to pass that
> information to the Thread object?
> 
> Maybe the intermediate steps could be:
> 
> * Make the Thread code that uses CPUState::nr_{cores,threads} and
>   smp_{cores,threads} get that info from MachineState instead.

I have some patches already headed down this road.

> * On the architectures where we already have a reasonable
>   Socket/Core/Thread hierarchy, let the Thread code simply ask
>   for that information from its parent.

I guess that's just spapr so far, or at least spapr is the closest.
Indeed this appears to be the cleanest approach, so architectures
adding support for cpu topology should likely strive to implement it
this way.

Thanks,
drew

> 
> -- 
> Eduardo
> 

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

* Re: [Qemu-devel] [PATCH RFC 14/16] hw/arm/virt: stash cpu topo info in VirtGuestInfo
  2016-07-14 20:43   ` Eduardo Habkost
@ 2016-07-15  6:40     ` Andrew Jones
  0 siblings, 0 replies; 74+ messages in thread
From: Andrew Jones @ 2016-07-15  6:40 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: peter.maydell, imammedo, qemu-devel, agraf, qemu-arm, qemu-ppc,
	dgibson, pbonzini, david

On Thu, Jul 14, 2016 at 05:43:51PM -0300, Eduardo Habkost wrote:
> On Fri, Jun 10, 2016 at 07:40:25PM +0200, Andrew Jones wrote:
> > This is a first step to preparing mach-virt for configurable
> > cpu topology, and is necessary now to prepare to move smbios
> > code away from using cpu topology globals smp_cores,smp_threads.
> > 
> > Signed-off-by: Andrew Jones <drjones@redhat.com>
> 
> I'd rather put a MachineState pointer inside VirtGuestInfo, and
> eventually eliminate VirtGuestInfo completely (like we already
> did with PCGuestInfo in x86).

I'll look at the history of PCGuestInfo's death. It sounds good to me.

> 
> > ---
> >  hw/arm/virt.c                    | 6 +++++-
> >  include/hw/arm/virt-acpi-build.h | 4 ++++
> >  2 files changed, 9 insertions(+), 1 deletion(-)
> > 
> > diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> > index 134b6e36623ba..769a49aa5be77 100644
> > --- a/hw/arm/virt.c
> > +++ b/hw/arm/virt.c
> > @@ -1281,7 +1281,11 @@ static void machvirt_init(MachineState *machine)
> >      create_fw_cfg(vbi, &address_space_memory);
> >      rom_set_fw(fw_cfg_find());
> >  
> > -    guest_info->cpus = vbi->cpus;
> > +    guest_info->sockets = machine->sockets;
> > +    guest_info->cores   = machine->cores;
> > +    guest_info->threads = machine->threads;
> > +    guest_info->maxcpus = machine->maxcpus;
> > +    guest_info->cpus    = machine->cpus;
> >      guest_info->fw_cfg = fw_cfg_find();
> >      guest_info->memmap = vbi->memmap;
> >      guest_info->irqmap = vbi->irqmap;
> > diff --git a/include/hw/arm/virt-acpi-build.h b/include/hw/arm/virt-acpi-build.h
> > index d6c5982960403..a34fb04230e66 100644
> > --- a/include/hw/arm/virt-acpi-build.h
> > +++ b/include/hw/arm/virt-acpi-build.h
> > @@ -27,6 +27,10 @@
> >  #define ACPI_GICC_ENABLED 1
> >  
> >  typedef struct VirtGuestInfo {
> > +    int sockets;
> > +    int cores;
> > +    int threads;
> > +    int maxcpus;
> >      int cpus;
> >      FWCfgState *fw_cfg;
> >      const MemMapEntry *memmap;
> > -- 
> > 2.4.11
> > 
> > 
> 
> -- 
> Eduardo
> 

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

* Re: [Qemu-devel] [PATCH RFC 15/16] smbios: don't use smp_cores, smp_threads
  2016-07-14 20:51   ` Eduardo Habkost
@ 2016-07-15  6:45     ` Andrew Jones
  0 siblings, 0 replies; 74+ messages in thread
From: Andrew Jones @ 2016-07-15  6:45 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: peter.maydell, imammedo, qemu-devel, agraf, qemu-arm, qemu-ppc,
	dgibson, pbonzini, david

On Thu, Jul 14, 2016 at 05:51:19PM -0300, Eduardo Habkost wrote:
> On Fri, Jun 10, 2016 at 07:40:26PM +0200, Andrew Jones wrote:
> > SMBIOS needs cpu topology for Type4 tables, so we need to pass
> > it in. There are several parameters so we use a structure. There
> > are two callers (of non-legacy, which generates Type4 tables),
> > x86 and arm, so we also update both to pass the topology
> > parameters from their MachineState properties (directly in the
> > case of x86, indirectly through VirtGuestInfo in the case of arm).
> > 
> > Signed-off-by: Andrew Jones <drjones@redhat.com>
> [...]
> > @@ -701,12 +701,19 @@ static uint32_t x86_cpu_apic_id_from_index(MachineState *ms,
> >      }
> >  }
> >  
> > -static void pc_build_smbios(FWCfgState *fw_cfg)
> > +static void pc_build_smbios(MachineState *ms, FWCfgState *fw_cfg)
> >  {
> >      uint8_t *smbios_tables, *smbios_anchor;
> >      size_t smbios_tables_len, smbios_anchor_len;
> >      struct smbios_phys_mem_area *mem_array;
> >      unsigned i, array_count;
> > +    struct smbios_cpu_topology topo = {
> > +        .sockets = ms->sockets,
> > +        .cores   = ms->cores,
> > +        .threads = ms->threads,
> > +        .maxcpus = ms->maxcpus,
> > +        .cpus    = ms->cpus,
> > +    };
> >  
> 
> Do we really need to manually copy data around this way when
> smbios.c could just use qdev_get_machine() directly?

You tell me. The art of writing object-oriented-ish code in C with
qom and qdev and a pile of qemu-best-practices is still something
I'm trying to sort out :-)

Using qdev_get_machine() sounds good to me though.

drew

> 
> -- 
> Eduardo
> 

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

* Re: [Qemu-devel] [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties
  2016-07-15  6:35               ` Andrew Jones
@ 2016-07-15  9:11                 ` Igor Mammedov
  2016-07-15 16:10                   ` [Qemu-devel] QOM: best way for parents to pass information to children? (was Re: [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties) Eduardo Habkost
  0 siblings, 1 reply; 74+ messages in thread
From: Igor Mammedov @ 2016-07-15  9:11 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Eduardo Habkost, David Gibson, peter.maydell, qemu-devel, agraf,
	qemu-arm, qemu-ppc, Bharata B Rao, Thomas Huth, pbonzini,
	dgibson, Andreas Färber

On Fri, 15 Jul 2016 08:35:30 +0200
Andrew Jones <drjones@redhat.com> wrote:

> On Thu, Jul 14, 2016 at 05:07:43PM -0300, Eduardo Habkost wrote:
> > 
> > First of all, sorry for the horrible delay in replying to this
> > thread.
> > 
> > On Wed, Jun 15, 2016 at 10:56:20AM +1000, David Gibson wrote:  
> > > On Tue, Jun 14, 2016 at 08:19:49AM +0200, Andrew Jones wrote:  
> > > > On Tue, Jun 14, 2016 at 12:12:16PM +1000, David Gibson wrote:  
> > > > > On Sun, Jun 12, 2016 at 03:48:10PM +0200, Andrew Jones wrote:  
> > > > > > On Sat, Jun 11, 2016 at 08:54:35AM +0200, Thomas Huth wrote:  
> > > > > > > On 10.06.2016 19:40, Andrew Jones wrote:  
> > > > > > > > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > > > > > > > ---
> > > > > > > >  qom/cpu.c | 8 ++++++++
> > > > > > > >  1 file changed, 8 insertions(+)
> > > > > > > > 
> > > > > > > > diff --git a/qom/cpu.c b/qom/cpu.c
> > > > > > > > index 751e992de8823..024cda3eb98c8 100644
> > > > > > > > --- a/qom/cpu.c
> > > > > > > > +++ b/qom/cpu.c
> > > > > > > > @@ -28,6 +28,7 @@
> > > > > > > >  #include "exec/log.h"
> > > > > > > >  #include "qemu/error-report.h"
> > > > > > > >  #include "sysemu/sysemu.h"
> > > > > > > > +#include "hw/qdev-properties.h"
> > > > > > > >  
> > > > > > > >  bool cpu_exists(int64_t id)
> > > > > > > >  {
> > > > > > > > @@ -342,6 +343,12 @@ static int64_t cpu_common_get_arch_id(CPUState *cpu)
> > > > > > > >      return cpu->cpu_index;
> > > > > > > >  }
> > > > > > > >  
> > > > > > > > +static Property cpu_common_properties[] = {
> > > > > > > > +    DEFINE_PROP_INT32("nr-cores", CPUState, nr_cores, 1),
> > > > > > > > +    DEFINE_PROP_INT32("nr-threads", CPUState, nr_threads, 1),
> > > > > > > > +    DEFINE_PROP_END_OF_LIST()
> > > > > > > > +};  
> > > > > > > 
> > > > > > > Are you aware of the current CPU hotplug discussion that is going on?  
> > > > > > 
> > > > > > I'm aware of it going on, but haven't been following it.
> > > > > >   
> > > > > > > I'm not very involved there, but I think some of these reworks also move
> > > > > > > "nr_threads" into the CPU state already, e.g. see:  
> > > > > > 
> > > > > > nr_threads (and nr_cores) are already state in CPUState. This patch just
> > > > > > exposes that state via properties.
> > > > > >   
> > > > > > > 
> > > > > > > https://github.com/dgibson/qemu/commit/9d07719784ecbeebea71
> > > > > > > 
> > > > > > > ... so you might want to check these patches first to see whether you
> > > > > > > can base your rework on them?  
> > > > > > 
> > > > > > Every cpu, and thus every machine, uses CPUState for its cpus. I'm
> > > > > > not sure every machine will want to use that new abstract core class
> > > > > > though. If they did, then we could indeed use nr_threads from there
> > > > > > instead (and remove it from CPUState), but we'd still need nr_cores
> > > > > > from the abstract cpu package class (CPUState).  
> > > > > 
> > > > > Hmm.  Since the CPUState object represents just a single thread, it
> > > > > seems weird to me that it would have nr_threads and nr_cores
> > > > > information.  
> > 
> > Agreed it is weird, and I think we should try to move it away
> > from CPUState, not make it part of the TYPE_CPU interface.
> > nr_threads belongs to the actual container of the Thread objects,
> > and nr_cores in the actual container of the Core objects.
> > 
> > The problem is how to implement that in a non-intrusive way that
> > would require changing the object hierarchy of all architectures.
> > 
> >   
> > > > > 
> > > > > Exposing those as properties makes that much worse, because it's now
> > > > > ABI, rather than internal detail we can clean up at some future time.  
> > > > 
> > > > CPUState is supposed to be "State of one CPU core or thread", which
> > > > justifies having nr_threads state, as it may be describing a core.  
> > > 
> > > Um.. does it ever actually represent a (multithread) core in practice?
> > > It would need to have duplicated register state for every thread were
> > > that the case.  
> > 
> > AFAIK, CPUState is still always thread state. Or has this changed
> > in some architectures, already?
> >   
> > >   
> > > > I guess there's no justification for having nr_cores in there though.
> > > > I agree adding the Core class is a good idea, assuming it will get used
> > > > by all machines, and CPUState then gets changed to a Thread class. The
> > > > question then, though, is do we also create a Socket class that contains
> > > > nr_cores?  
> > > 
> > > That was roughly our intention with the way the cross platform hotplug
> > > stuff is evolving.  But the intention was that the Socket objects
> > > would only need to be constructed for machine types where it makes
> > > sense.  So for example on the paravirt pseries platform, we'll only
> > > have Core objects, because the socket distinction isn't really
> > > meaningful.
> > >   
> > > > And how will a Thread method get that information when it
> > > > needs to emulate, e.g. CPUID, that requires it? It's a bit messy, so
> > > > I'm open to all suggestions on it.  
> > > 
> > > So, if the Thread needs this information, I'm not opposed to it having
> > > it internally (presumably populated earlier from the Core object).
> > > But I am opposed to it being a locked in part of the interface by
> > > having it as an exposed property.  
> > 
> > I agree we don't want to make this part of the external
> > interface. In this case, if we don't add the properties, how
> > exactly is the Machine or Core code supposed to pass that
> > information to the Thread object?
> > 
> > Maybe the intermediate steps could be:
> > 
> > * Make the Thread code that uses CPUState::nr_{cores,threads} and
> >   smp_{cores,threads} get that info from MachineState instead.  
> 
> I have some patches already headed down this road.
> 
> > * On the architectures where we already have a reasonable
> >   Socket/Core/Thread hierarchy, let the Thread code simply ask
> >   for that information from its parent.  
> 
> I guess that's just spapr so far, or at least spapr is the closest.
> Indeed this appears to be the cleanest approach, so architectures
> adding support for cpu topology should likely strive to implement it
> this way.
If I recall correctly, the only thing about accessing parent is that
in QOM design accessing parent from child wasn't accepted well,
i.e. child shouldn't be aware nor access parent object.


> 
> Thanks,
> drew
> 
> > 
> > -- 
> > Eduardo
> >   

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

* [Qemu-devel] QOM: best way for parents to pass information to children? (was Re: [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties)
  2016-07-15  9:11                 ` Igor Mammedov
@ 2016-07-15 16:10                   ` Eduardo Habkost
  2016-07-15 16:30                     ` Andreas Färber
  0 siblings, 1 reply; 74+ messages in thread
From: Eduardo Habkost @ 2016-07-15 16:10 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Andrew Jones, David Gibson, peter.maydell, qemu-devel, agraf,
	qemu-arm, qemu-ppc, Bharata B Rao, Thomas Huth, pbonzini,
	dgibson, Andreas Färber

On Fri, Jul 15, 2016 at 11:11:38AM +0200, Igor Mammedov wrote:
> On Fri, 15 Jul 2016 08:35:30 +0200
> Andrew Jones <drjones@redhat.com> wrote:
> > On Thu, Jul 14, 2016 at 05:07:43PM -0300, Eduardo Habkost wrote:
> > > 
> > > First of all, sorry for the horrible delay in replying to this
> > > thread.
> > > 
> > > On Wed, Jun 15, 2016 at 10:56:20AM +1000, David Gibson wrote:  
> > > > On Tue, Jun 14, 2016 at 08:19:49AM +0200, Andrew Jones wrote:  
> > > > > On Tue, Jun 14, 2016 at 12:12:16PM +1000, David Gibson wrote:  
> > > > > > On Sun, Jun 12, 2016 at 03:48:10PM +0200, Andrew Jones wrote:  
[...]
> > > > > > > > > +static Property cpu_common_properties[] = {
> > > > > > > > > +    DEFINE_PROP_INT32("nr-cores", CPUState, nr_cores, 1),
> > > > > > > > > +    DEFINE_PROP_INT32("nr-threads", CPUState, nr_threads, 1),
> > > > > > > > > +    DEFINE_PROP_END_OF_LIST()
> > > > > > > > > +};  
> > > > > > > > 
> > > > > > > > Are you aware of the current CPU hotplug discussion that is going on?  
> > > > > > > 
> > > > > > > I'm aware of it going on, but haven't been following it.
> > > > > > >   
> > > > > > > > I'm not very involved there, but I think some of these reworks also move
> > > > > > > > "nr_threads" into the CPU state already, e.g. see:  
> > > > > > > 
> > > > > > > nr_threads (and nr_cores) are already state in CPUState. This patch just
> > > > > > > exposes that state via properties.
> > > > > > >   
> > > > > > > > 
> > > > > > > > https://github.com/dgibson/qemu/commit/9d07719784ecbeebea71
> > > > > > > > 
> > > > > > > > ... so you might want to check these patches first to see whether you
> > > > > > > > can base your rework on them?  
> > > > > > > 
> > > > > > > Every cpu, and thus every machine, uses CPUState for its cpus. I'm
> > > > > > > not sure every machine will want to use that new abstract core class
> > > > > > > though. If they did, then we could indeed use nr_threads from there
> > > > > > > instead (and remove it from CPUState), but we'd still need nr_cores
> > > > > > > from the abstract cpu package class (CPUState).  
> > > > > > 
> > > > > > Hmm.  Since the CPUState object represents just a single thread, it
> > > > > > seems weird to me that it would have nr_threads and nr_cores
> > > > > > information.  
> > > 
> > > Agreed it is weird, and I think we should try to move it away
> > > from CPUState, not make it part of the TYPE_CPU interface.
> > > nr_threads belongs to the actual container of the Thread objects,
> > > and nr_cores in the actual container of the Core objects.
> > > 
> > > The problem is how to implement that in a non-intrusive way that
> > > would require changing the object hierarchy of all architectures.
> > > 
> > >   
> > > > > > 
> > > > > > Exposing those as properties makes that much worse, because it's now
> > > > > > ABI, rather than internal detail we can clean up at some future time.  
> > > > > 
> > > > > CPUState is supposed to be "State of one CPU core or thread", which
> > > > > justifies having nr_threads state, as it may be describing a core.  
> > > > 
> > > > Um.. does it ever actually represent a (multithread) core in practice?
> > > > It would need to have duplicated register state for every thread were
> > > > that the case.  
> > > 
> > > AFAIK, CPUState is still always thread state. Or has this changed
> > > in some architectures, already?
> > >   
> > > >   
> > > > > I guess there's no justification for having nr_cores in there though.
> > > > > I agree adding the Core class is a good idea, assuming it will get used
> > > > > by all machines, and CPUState then gets changed to a Thread class. The
> > > > > question then, though, is do we also create a Socket class that contains
> > > > > nr_cores?  
> > > > 
> > > > That was roughly our intention with the way the cross platform hotplug
> > > > stuff is evolving.  But the intention was that the Socket objects
> > > > would only need to be constructed for machine types where it makes
> > > > sense.  So for example on the paravirt pseries platform, we'll only
> > > > have Core objects, because the socket distinction isn't really
> > > > meaningful.
> > > >   
> > > > > And how will a Thread method get that information when it
> > > > > needs to emulate, e.g. CPUID, that requires it? It's a bit messy, so
> > > > > I'm open to all suggestions on it.  
> > > > 
> > > > So, if the Thread needs this information, I'm not opposed to it having
> > > > it internally (presumably populated earlier from the Core object).
> > > > But I am opposed to it being a locked in part of the interface by
> > > > having it as an exposed property.  
> > > 
> > > I agree we don't want to make this part of the external
> > > interface. In this case, if we don't add the properties, how
> > > exactly is the Machine or Core code supposed to pass that
> > > information to the Thread object?
> > > 
> > > Maybe the intermediate steps could be:
> > > 
> > > * Make the Thread code that uses CPUState::nr_{cores,threads} and
> > >   smp_{cores,threads} get that info from MachineState instead.  
> > 
> > I have some patches already headed down this road.
> > 
> > > * On the architectures where we already have a reasonable
> > >   Socket/Core/Thread hierarchy, let the Thread code simply ask
> > >   for that information from its parent.  
> > 
> > I guess that's just spapr so far, or at least spapr is the closest.
> > Indeed this appears to be the cleanest approach, so architectures
> > adding support for cpu topology should likely strive to implement it
> > this way.
> If I recall correctly, the only thing about accessing parent is that
> in QOM design accessing parent from child wasn't accepted well,
> i.e. child shouldn't be aware nor access parent object.

Can anybody explain why?

In this case, what's the best way for a parent to pass
information to its children without adding new externally-visible
properties that the user is never supposed to set directly?

Should Thread objects have an additional link to the parent Core
object, just to be able to get the information it needs?

-- 
Eduardo

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

* Re: [Qemu-devel] QOM: best way for parents to pass information to children? (was Re: [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties)
  2016-07-15 16:10                   ` [Qemu-devel] QOM: best way for parents to pass information to children? (was Re: [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties) Eduardo Habkost
@ 2016-07-15 16:30                     ` Andreas Färber
  2016-07-15 17:43                       ` Eduardo Habkost
  0 siblings, 1 reply; 74+ messages in thread
From: Andreas Färber @ 2016-07-15 16:30 UTC (permalink / raw)
  To: Eduardo Habkost, Igor Mammedov
  Cc: Andrew Jones, David Gibson, peter.maydell, qemu-devel, agraf,
	qemu-arm, qemu-ppc, Bharata B Rao, Thomas Huth, pbonzini,
	dgibson

Am 15.07.2016 um 18:10 schrieb Eduardo Habkost:
> On Fri, Jul 15, 2016 at 11:11:38AM +0200, Igor Mammedov wrote:
>> On Fri, 15 Jul 2016 08:35:30 +0200
>> Andrew Jones <drjones@redhat.com> wrote:
>>> On Thu, Jul 14, 2016 at 05:07:43PM -0300, Eduardo Habkost wrote:
>>>>
>>>> First of all, sorry for the horrible delay in replying to this
>>>> thread.
>>>>
>>>> On Wed, Jun 15, 2016 at 10:56:20AM +1000, David Gibson wrote:  
>>>>> On Tue, Jun 14, 2016 at 08:19:49AM +0200, Andrew Jones wrote:  
>>>>>> On Tue, Jun 14, 2016 at 12:12:16PM +1000, David Gibson wrote:  
>>>>>>> On Sun, Jun 12, 2016 at 03:48:10PM +0200, Andrew Jones wrote:  
> [...]
>>>>>>>>>> +static Property cpu_common_properties[] = {
>>>>>>>>>> +    DEFINE_PROP_INT32("nr-cores", CPUState, nr_cores, 1),
>>>>>>>>>> +    DEFINE_PROP_INT32("nr-threads", CPUState, nr_threads, 1),
>>>>>>>>>> +    DEFINE_PROP_END_OF_LIST()
>>>>>>>>>> +};  
>>>>>>>>>
>>>>>>>>> Are you aware of the current CPU hotplug discussion that is going on?  
>>>>>>>>
>>>>>>>> I'm aware of it going on, but haven't been following it.
>>>>>>>>   
>>>>>>>>> I'm not very involved there, but I think some of these reworks also move
>>>>>>>>> "nr_threads" into the CPU state already, e.g. see:  
>>>>>>>>
>>>>>>>> nr_threads (and nr_cores) are already state in CPUState. This patch just
>>>>>>>> exposes that state via properties.
>>>>>>>>   
>>>>>>>>>
>>>>>>>>> https://github.com/dgibson/qemu/commit/9d07719784ecbeebea71
>>>>>>>>>
>>>>>>>>> ... so you might want to check these patches first to see whether you
>>>>>>>>> can base your rework on them?  
>>>>>>>>
>>>>>>>> Every cpu, and thus every machine, uses CPUState for its cpus. I'm
>>>>>>>> not sure every machine will want to use that new abstract core class
>>>>>>>> though. If they did, then we could indeed use nr_threads from there
>>>>>>>> instead (and remove it from CPUState), but we'd still need nr_cores
>>>>>>>> from the abstract cpu package class (CPUState).  
>>>>>>>
>>>>>>> Hmm.  Since the CPUState object represents just a single thread, it
>>>>>>> seems weird to me that it would have nr_threads and nr_cores
>>>>>>> information.  
>>>>
>>>> Agreed it is weird, and I think we should try to move it away
>>>> from CPUState, not make it part of the TYPE_CPU interface.
>>>> nr_threads belongs to the actual container of the Thread objects,
>>>> and nr_cores in the actual container of the Core objects.
>>>>
>>>> The problem is how to implement that in a non-intrusive way that
>>>> would require changing the object hierarchy of all architectures.
>>>>
>>>>   
>>>>>>>
>>>>>>> Exposing those as properties makes that much worse, because it's now
>>>>>>> ABI, rather than internal detail we can clean up at some future time.  
>>>>>>
>>>>>> CPUState is supposed to be "State of one CPU core or thread", which
>>>>>> justifies having nr_threads state, as it may be describing a core.  
>>>>>
>>>>> Um.. does it ever actually represent a (multithread) core in practice?
>>>>> It would need to have duplicated register state for every thread were
>>>>> that the case.  
>>>>
>>>> AFAIK, CPUState is still always thread state. Or has this changed
>>>> in some architectures, already?
>>>>   
>>>>>   
>>>>>> I guess there's no justification for having nr_cores in there though.
>>>>>> I agree adding the Core class is a good idea, assuming it will get used
>>>>>> by all machines, and CPUState then gets changed to a Thread class. The
>>>>>> question then, though, is do we also create a Socket class that contains
>>>>>> nr_cores?  
>>>>>
>>>>> That was roughly our intention with the way the cross platform hotplug
>>>>> stuff is evolving.  But the intention was that the Socket objects
>>>>> would only need to be constructed for machine types where it makes
>>>>> sense.  So for example on the paravirt pseries platform, we'll only
>>>>> have Core objects, because the socket distinction isn't really
>>>>> meaningful.
>>>>>   
>>>>>> And how will a Thread method get that information when it
>>>>>> needs to emulate, e.g. CPUID, that requires it? It's a bit messy, so
>>>>>> I'm open to all suggestions on it.  
>>>>>
>>>>> So, if the Thread needs this information, I'm not opposed to it having
>>>>> it internally (presumably populated earlier from the Core object).
>>>>> But I am opposed to it being a locked in part of the interface by
>>>>> having it as an exposed property.  
>>>>
>>>> I agree we don't want to make this part of the external
>>>> interface. In this case, if we don't add the properties, how
>>>> exactly is the Machine or Core code supposed to pass that
>>>> information to the Thread object?
>>>>
>>>> Maybe the intermediate steps could be:
>>>>
>>>> * Make the Thread code that uses CPUState::nr_{cores,threads} and
>>>>   smp_{cores,threads} get that info from MachineState instead.  
>>>
>>> I have some patches already headed down this road.
>>>
>>>> * On the architectures where we already have a reasonable
>>>>   Socket/Core/Thread hierarchy, let the Thread code simply ask
>>>>   for that information from its parent.  
>>>
>>> I guess that's just spapr so far, or at least spapr is the closest.
>>> Indeed this appears to be the cleanest approach, so architectures
>>> adding support for cpu topology should likely strive to implement it
>>> this way.
>> If I recall correctly, the only thing about accessing parent is that
>> in QOM design accessing parent from child wasn't accepted well,
>> i.e. child shouldn't be aware nor access parent object.
> 
> Can anybody explain why?
> 
> In this case, what's the best way for a parent to pass
> information to its children without adding new externally-visible
> properties that the user is never supposed to set directly?
> 
> Should Thread objects have an additional link to the parent Core
> object, just to be able to get the information it needs?

I am not fully aware either and believe I ignored it in my x86 socket
patchset, part of which it was RFC.

The key thing to consider is that this breaks user instantiation of a
device, so it needs to be disabled.

Note that I'm just replying to this particular question without the full
context.

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)

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

* Re: [Qemu-devel] QOM: best way for parents to pass information to children? (was Re: [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties)
  2016-07-15 16:30                     ` Andreas Färber
@ 2016-07-15 17:43                       ` Eduardo Habkost
  2016-07-15 18:38                         ` Igor Mammedov
  0 siblings, 1 reply; 74+ messages in thread
From: Eduardo Habkost @ 2016-07-15 17:43 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Igor Mammedov, Andrew Jones, David Gibson, peter.maydell,
	qemu-devel, agraf, qemu-arm, qemu-ppc, Bharata B Rao,
	Thomas Huth, pbonzini, dgibson

On Fri, Jul 15, 2016 at 06:30:41PM +0200, Andreas Färber wrote:
> Am 15.07.2016 um 18:10 schrieb Eduardo Habkost:
> > On Fri, Jul 15, 2016 at 11:11:38AM +0200, Igor Mammedov wrote:
> >> On Fri, 15 Jul 2016 08:35:30 +0200
> >> Andrew Jones <drjones@redhat.com> wrote:
> >>> On Thu, Jul 14, 2016 at 05:07:43PM -0300, Eduardo Habkost wrote:
> >>>>
> >>>> First of all, sorry for the horrible delay in replying to this
> >>>> thread.
> >>>>
> >>>> On Wed, Jun 15, 2016 at 10:56:20AM +1000, David Gibson wrote:  
> >>>>> On Tue, Jun 14, 2016 at 08:19:49AM +0200, Andrew Jones wrote:  
> >>>>>> On Tue, Jun 14, 2016 at 12:12:16PM +1000, David Gibson wrote:  
> >>>>>>> On Sun, Jun 12, 2016 at 03:48:10PM +0200, Andrew Jones wrote:  
> > [...]
> >>>>>>>>>> +static Property cpu_common_properties[] = {
> >>>>>>>>>> +    DEFINE_PROP_INT32("nr-cores", CPUState, nr_cores, 1),
> >>>>>>>>>> +    DEFINE_PROP_INT32("nr-threads", CPUState, nr_threads, 1),
> >>>>>>>>>> +    DEFINE_PROP_END_OF_LIST()
> >>>>>>>>>> +};  
> >>>>>>>>>
> >>>>>>>>> Are you aware of the current CPU hotplug discussion that is going on?  
> >>>>>>>>
> >>>>>>>> I'm aware of it going on, but haven't been following it.
> >>>>>>>>   
> >>>>>>>>> I'm not very involved there, but I think some of these reworks also move
> >>>>>>>>> "nr_threads" into the CPU state already, e.g. see:  
> >>>>>>>>
> >>>>>>>> nr_threads (and nr_cores) are already state in CPUState. This patch just
> >>>>>>>> exposes that state via properties.
> >>>>>>>>   
> >>>>>>>>>
> >>>>>>>>> https://github.com/dgibson/qemu/commit/9d07719784ecbeebea71
> >>>>>>>>>
> >>>>>>>>> ... so you might want to check these patches first to see whether you
> >>>>>>>>> can base your rework on them?  
> >>>>>>>>
> >>>>>>>> Every cpu, and thus every machine, uses CPUState for its cpus. I'm
> >>>>>>>> not sure every machine will want to use that new abstract core class
> >>>>>>>> though. If they did, then we could indeed use nr_threads from there
> >>>>>>>> instead (and remove it from CPUState), but we'd still need nr_cores
> >>>>>>>> from the abstract cpu package class (CPUState).  
> >>>>>>>
> >>>>>>> Hmm.  Since the CPUState object represents just a single thread, it
> >>>>>>> seems weird to me that it would have nr_threads and nr_cores
> >>>>>>> information.  
> >>>>
> >>>> Agreed it is weird, and I think we should try to move it away
> >>>> from CPUState, not make it part of the TYPE_CPU interface.
> >>>> nr_threads belongs to the actual container of the Thread objects,
> >>>> and nr_cores in the actual container of the Core objects.
> >>>>
> >>>> The problem is how to implement that in a non-intrusive way that
> >>>> would require changing the object hierarchy of all architectures.
> >>>>
> >>>>   
> >>>>>>>
> >>>>>>> Exposing those as properties makes that much worse, because it's now
> >>>>>>> ABI, rather than internal detail we can clean up at some future time.  
> >>>>>>
> >>>>>> CPUState is supposed to be "State of one CPU core or thread", which
> >>>>>> justifies having nr_threads state, as it may be describing a core.  
> >>>>>
> >>>>> Um.. does it ever actually represent a (multithread) core in practice?
> >>>>> It would need to have duplicated register state for every thread were
> >>>>> that the case.  
> >>>>
> >>>> AFAIK, CPUState is still always thread state. Or has this changed
> >>>> in some architectures, already?
> >>>>   
> >>>>>   
> >>>>>> I guess there's no justification for having nr_cores in there though.
> >>>>>> I agree adding the Core class is a good idea, assuming it will get used
> >>>>>> by all machines, and CPUState then gets changed to a Thread class. The
> >>>>>> question then, though, is do we also create a Socket class that contains
> >>>>>> nr_cores?  
> >>>>>
> >>>>> That was roughly our intention with the way the cross platform hotplug
> >>>>> stuff is evolving.  But the intention was that the Socket objects
> >>>>> would only need to be constructed for machine types where it makes
> >>>>> sense.  So for example on the paravirt pseries platform, we'll only
> >>>>> have Core objects, because the socket distinction isn't really
> >>>>> meaningful.
> >>>>>   
> >>>>>> And how will a Thread method get that information when it
> >>>>>> needs to emulate, e.g. CPUID, that requires it? It's a bit messy, so
> >>>>>> I'm open to all suggestions on it.  
> >>>>>
> >>>>> So, if the Thread needs this information, I'm not opposed to it having
> >>>>> it internally (presumably populated earlier from the Core object).
> >>>>> But I am opposed to it being a locked in part of the interface by
> >>>>> having it as an exposed property.  
> >>>>
> >>>> I agree we don't want to make this part of the external
> >>>> interface. In this case, if we don't add the properties, how
> >>>> exactly is the Machine or Core code supposed to pass that
> >>>> information to the Thread object?
> >>>>
> >>>> Maybe the intermediate steps could be:
> >>>>
> >>>> * Make the Thread code that uses CPUState::nr_{cores,threads} and
> >>>>   smp_{cores,threads} get that info from MachineState instead.  
> >>>
> >>> I have some patches already headed down this road.
> >>>
> >>>> * On the architectures where we already have a reasonable
> >>>>   Socket/Core/Thread hierarchy, let the Thread code simply ask
> >>>>   for that information from its parent.  
> >>>
> >>> I guess that's just spapr so far, or at least spapr is the closest.
> >>> Indeed this appears to be the cleanest approach, so architectures
> >>> adding support for cpu topology should likely strive to implement it
> >>> this way.
> >> If I recall correctly, the only thing about accessing parent is that
> >> in QOM design accessing parent from child wasn't accepted well,
> >> i.e. child shouldn't be aware nor access parent object.
> > 
> > Can anybody explain why?
> > 
> > In this case, what's the best way for a parent to pass
> > information to its children without adding new externally-visible
> > properties that the user is never supposed to set directly?
> > 
> > Should Thread objects have an additional link to the parent Core
> > object, just to be able to get the information it needs?
> 
> I am not fully aware either and believe I ignored it in my x86 socket
> patchset, part of which it was RFC.
> 
> The key thing to consider is that this breaks user instantiation of a
> device, so it needs to be disabled.

Good point, and this is hard to solve without changing the way
device_add works. Setting extra properties, on the other hand,
can be done easily by the hotplug handler if necessary (like we
do with apic-id in PC).

Also, if the properties are not supposed to be set directly by
the user, then the hotplug handler could refuse to hotplug the
device if the user tried to fiddle with them. Then the "external
interface" problem is solved.

Now, depending on how much information is needed, "extra
properties" may be duplicating data that is already available in
other objects (like nr-cores/nr-threads), or just a link property
(e.g. a link to the Core object in the case of spapr). If we
still don't have the right object topology implemented, then we
may need to use individual properties like "nr-cores" and
"nr-threads" (preferably as a temporary solution?).

In other words, maybe "nr-cores" and "nr-threads" properties will
be useful in x86, but only if we reject device creation in case
the user tries to set them manually, and if we do _not_ expose
them on TYPE_CPU.

Anyway, I think all that can be done as a second step. First, we
need to replace existing usage of smp_{threads,cores} globals
with MachineState fields. Later, remaining qdev_get_machine()
calls can be replaced by a more QOM-friendly mechanism.

> 
> Note that I'm just replying to this particular question without the full
> context.

No problem. I wanted it to be a generic question about what are
QOM best practices. Thanks for your feedback.

-- 
Eduardo

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

* Re: [Qemu-devel] QOM: best way for parents to pass information to children? (was Re: [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties)
  2016-07-15 17:43                       ` Eduardo Habkost
@ 2016-07-15 18:38                         ` Igor Mammedov
  2016-07-15 21:33                           ` Eduardo Habkost
  0 siblings, 1 reply; 74+ messages in thread
From: Igor Mammedov @ 2016-07-15 18:38 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: Andreas Färber, peter.maydell, Andrew Jones, pbonzini,
	qemu-devel, agraf, qemu-arm, qemu-ppc, Bharata B Rao,
	Thomas Huth, dgibson, David Gibson

On Fri, 15 Jul 2016 14:43:53 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:

> On Fri, Jul 15, 2016 at 06:30:41PM +0200, Andreas Färber wrote:
> > Am 15.07.2016 um 18:10 schrieb Eduardo Habkost:
> > > On Fri, Jul 15, 2016 at 11:11:38AM +0200, Igor Mammedov wrote:
> > >> On Fri, 15 Jul 2016 08:35:30 +0200
> > >> Andrew Jones <drjones@redhat.com> wrote:
> > >>> On Thu, Jul 14, 2016 at 05:07:43PM -0300, Eduardo Habkost wrote:
> > >>>>
> > >>>> First of all, sorry for the horrible delay in replying to this
> > >>>> thread.
> > >>>>
> > >>>> On Wed, Jun 15, 2016 at 10:56:20AM +1000, David Gibson wrote:  
> > >>>>> On Tue, Jun 14, 2016 at 08:19:49AM +0200, Andrew Jones
> > >>>>> wrote:  
> > >>>>>> On Tue, Jun 14, 2016 at 12:12:16PM +1000, David Gibson
> > >>>>>> wrote:  
> > >>>>>>> On Sun, Jun 12, 2016 at 03:48:10PM +0200, Andrew Jones
> > >>>>>>> wrote:  
> > > [...]
> > >>>>>>>>>> +static Property cpu_common_properties[] = {
> > >>>>>>>>>> +    DEFINE_PROP_INT32("nr-cores", CPUState, nr_cores,
> > >>>>>>>>>> 1),
> > >>>>>>>>>> +    DEFINE_PROP_INT32("nr-threads", CPUState,
> > >>>>>>>>>> nr_threads, 1),
> > >>>>>>>>>> +    DEFINE_PROP_END_OF_LIST()
> > >>>>>>>>>> +};  
> > >>>>>>>>>
> > >>>>>>>>> Are you aware of the current CPU hotplug discussion that
> > >>>>>>>>> is going on?  
> > >>>>>>>>
> > >>>>>>>> I'm aware of it going on, but haven't been following it.
> > >>>>>>>>   
> > >>>>>>>>> I'm not very involved there, but I think some of these
> > >>>>>>>>> reworks also move "nr_threads" into the CPU state
> > >>>>>>>>> already, e.g. see:  
> > >>>>>>>>
> > >>>>>>>> nr_threads (and nr_cores) are already state in CPUState.
> > >>>>>>>> This patch just exposes that state via properties.
> > >>>>>>>>   
> > >>>>>>>>>
> > >>>>>>>>> https://github.com/dgibson/qemu/commit/9d07719784ecbeebea71
> > >>>>>>>>>
> > >>>>>>>>> ... so you might want to check these patches first to see
> > >>>>>>>>> whether you can base your rework on them?  
> > >>>>>>>>
> > >>>>>>>> Every cpu, and thus every machine, uses CPUState for its
> > >>>>>>>> cpus. I'm not sure every machine will want to use that new
> > >>>>>>>> abstract core class though. If they did, then we could
> > >>>>>>>> indeed use nr_threads from there instead (and remove it
> > >>>>>>>> from CPUState), but we'd still need nr_cores from the
> > >>>>>>>> abstract cpu package class (CPUState).  
> > >>>>>>>
> > >>>>>>> Hmm.  Since the CPUState object represents just a single
> > >>>>>>> thread, it seems weird to me that it would have nr_threads
> > >>>>>>> and nr_cores information.  
> > >>>>
> > >>>> Agreed it is weird, and I think we should try to move it away
> > >>>> from CPUState, not make it part of the TYPE_CPU interface.
> > >>>> nr_threads belongs to the actual container of the Thread
> > >>>> objects, and nr_cores in the actual container of the Core
> > >>>> objects.
> > >>>>
> > >>>> The problem is how to implement that in a non-intrusive way
> > >>>> that would require changing the object hierarchy of all
> > >>>> architectures.
> > >>>>
> > >>>>   
> > >>>>>>>
> > >>>>>>> Exposing those as properties makes that much worse, because
> > >>>>>>> it's now ABI, rather than internal detail we can clean up
> > >>>>>>> at some future time.  
> > >>>>>>
> > >>>>>> CPUState is supposed to be "State of one CPU core or
> > >>>>>> thread", which justifies having nr_threads state, as it may
> > >>>>>> be describing a core.  
> > >>>>>
> > >>>>> Um.. does it ever actually represent a (multithread) core in
> > >>>>> practice? It would need to have duplicated register state for
> > >>>>> every thread were that the case.  
> > >>>>
> > >>>> AFAIK, CPUState is still always thread state. Or has this
> > >>>> changed in some architectures, already?
> > >>>>   
> > >>>>>   
> > >>>>>> I guess there's no justification for having nr_cores in
> > >>>>>> there though. I agree adding the Core class is a good idea,
> > >>>>>> assuming it will get used by all machines, and CPUState then
> > >>>>>> gets changed to a Thread class. The question then, though,
> > >>>>>> is do we also create a Socket class that contains nr_cores?  
> > >>>>>
> > >>>>> That was roughly our intention with the way the cross
> > >>>>> platform hotplug stuff is evolving.  But the intention was
> > >>>>> that the Socket objects would only need to be constructed for
> > >>>>> machine types where it makes sense.  So for example on the
> > >>>>> paravirt pseries platform, we'll only have Core objects,
> > >>>>> because the socket distinction isn't really meaningful.
> > >>>>>   
> > >>>>>> And how will a Thread method get that information when it
> > >>>>>> needs to emulate, e.g. CPUID, that requires it? It's a bit
> > >>>>>> messy, so I'm open to all suggestions on it.  
> > >>>>>
> > >>>>> So, if the Thread needs this information, I'm not opposed to
> > >>>>> it having it internally (presumably populated earlier from
> > >>>>> the Core object). But I am opposed to it being a locked in
> > >>>>> part of the interface by having it as an exposed property.  
> > >>>>
> > >>>> I agree we don't want to make this part of the external
> > >>>> interface. In this case, if we don't add the properties, how
> > >>>> exactly is the Machine or Core code supposed to pass that
> > >>>> information to the Thread object?
> > >>>>
> > >>>> Maybe the intermediate steps could be:
> > >>>>
> > >>>> * Make the Thread code that uses CPUState::nr_{cores,threads}
> > >>>> and smp_{cores,threads} get that info from MachineState
> > >>>> instead.  
> > >>>
> > >>> I have some patches already headed down this road.
> > >>>
> > >>>> * On the architectures where we already have a reasonable
> > >>>>   Socket/Core/Thread hierarchy, let the Thread code simply ask
> > >>>>   for that information from its parent.  
> > >>>
> > >>> I guess that's just spapr so far, or at least spapr is the
> > >>> closest. Indeed this appears to be the cleanest approach, so
> > >>> architectures adding support for cpu topology should likely
> > >>> strive to implement it this way.
> > >> If I recall correctly, the only thing about accessing parent is
> > >> that in QOM design accessing parent from child wasn't accepted
> > >> well, i.e. child shouldn't be aware nor access parent object.
> > > 
> > > Can anybody explain why?
> > > 
> > > In this case, what's the best way for a parent to pass
> > > information to its children without adding new externally-visible
> > > properties that the user is never supposed to set directly?
> > > 
> > > Should Thread objects have an additional link to the parent Core
> > > object, just to be able to get the information it needs?
> > 
> > I am not fully aware either and believe I ignored it in my x86
> > socket patchset, part of which it was RFC.
> > 
> > The key thing to consider is that this breaks user instantiation of
> > a device, so it needs to be disabled.
> 
> Good point, and this is hard to solve without changing the way
> device_add works. Setting extra properties, on the other hand,
> can be done easily by the hotplug handler if necessary (like we
> do with apic-id in PC).
> 
> Also, if the properties are not supposed to be set directly by
> the user, then the hotplug handler could refuse to hotplug the
> device if the user tried to fiddle with them. Then the "external
> interface" problem is solved.
> 
> Now, depending on how much information is needed, "extra
> properties" may be duplicating data that is already available in
> other objects (like nr-cores/nr-threads), or just a link property
> (e.g. a link to the Core object in the case of spapr). If we
> still don't have the right object topology implemented, then we
> may need to use individual properties like "nr-cores" and
> "nr-threads" (preferably as a temporary solution?).
> 
> In other words, maybe "nr-cores" and "nr-threads" properties will
> be useful in x86, but only if we reject device creation in case
> the user tries to set them manually, and if we do _not_ expose
> them on TYPE_CPU.
Should be add a QOM API that could mark property as an internal
that would be beneficial in generic as we won't have to be scared
exposing internal stuff to users and be able to hide target specifics
behind properties?

it should be simple enough to do.

> 
> Anyway, I think all that can be done as a second step. First, we
> need to replace existing usage of smp_{threads,cores} globals
> with MachineState fields. Later, remaining qdev_get_machine()
> calls can be replaced by a more QOM-friendly mechanism.
> 
> > 
> > Note that I'm just replying to this particular question without the
> > full context.
> 
> No problem. I wanted it to be a generic question about what are
> QOM best practices. Thanks for your feedback.
> 

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

* Re: [Qemu-devel] QOM: best way for parents to pass information to children? (was Re: [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties)
  2016-07-15 18:38                         ` Igor Mammedov
@ 2016-07-15 21:33                           ` Eduardo Habkost
  2016-07-16 15:30                             ` Andrew Jones
  2016-07-18  7:23                             ` Igor Mammedov
  0 siblings, 2 replies; 74+ messages in thread
From: Eduardo Habkost @ 2016-07-15 21:33 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Andreas Färber, peter.maydell, Andrew Jones, pbonzini,
	qemu-devel, agraf, qemu-arm, qemu-ppc, Bharata B Rao,
	Thomas Huth, dgibson, David Gibson

On Fri, Jul 15, 2016 at 08:38:35PM +0200, Igor Mammedov wrote:
> On Fri, 15 Jul 2016 14:43:53 -0300
> Eduardo Habkost <ehabkost@redhat.com> wrote:
> > On Fri, Jul 15, 2016 at 06:30:41PM +0200, Andreas Färber wrote:
> > > Am 15.07.2016 um 18:10 schrieb Eduardo Habkost:
> > > > On Fri, Jul 15, 2016 at 11:11:38AM +0200, Igor Mammedov wrote:
> > > >> On Fri, 15 Jul 2016 08:35:30 +0200
> > > >> Andrew Jones <drjones@redhat.com> wrote:
> > > >>> On Thu, Jul 14, 2016 at 05:07:43PM -0300, Eduardo Habkost wrote:
> > > >>>>
> > > >>>> First of all, sorry for the horrible delay in replying to this
> > > >>>> thread.
> > > >>>>
> > > >>>> On Wed, Jun 15, 2016 at 10:56:20AM +1000, David Gibson wrote:  
> > > >>>>> On Tue, Jun 14, 2016 at 08:19:49AM +0200, Andrew Jones
> > > >>>>> wrote:  
> > > >>>>>> On Tue, Jun 14, 2016 at 12:12:16PM +1000, David Gibson
> > > >>>>>> wrote:  
> > > >>>>>>> On Sun, Jun 12, 2016 at 03:48:10PM +0200, Andrew Jones
> > > >>>>>>> wrote:  
> > > > [...]
> > > >>>>>>>>>> +static Property cpu_common_properties[] = {
> > > >>>>>>>>>> +    DEFINE_PROP_INT32("nr-cores", CPUState, nr_cores,
> > > >>>>>>>>>> 1),
> > > >>>>>>>>>> +    DEFINE_PROP_INT32("nr-threads", CPUState,
> > > >>>>>>>>>> nr_threads, 1),
> > > >>>>>>>>>> +    DEFINE_PROP_END_OF_LIST()
> > > >>>>>>>>>> +};  
> > > >>>>>>>>>
> > > >>>>>>>>> Are you aware of the current CPU hotplug discussion that
> > > >>>>>>>>> is going on?  
> > > >>>>>>>>
> > > >>>>>>>> I'm aware of it going on, but haven't been following it.
> > > >>>>>>>>   
> > > >>>>>>>>> I'm not very involved there, but I think some of these
> > > >>>>>>>>> reworks also move "nr_threads" into the CPU state
> > > >>>>>>>>> already, e.g. see:  
> > > >>>>>>>>
> > > >>>>>>>> nr_threads (and nr_cores) are already state in CPUState.
> > > >>>>>>>> This patch just exposes that state via properties.
> > > >>>>>>>>   
> > > >>>>>>>>>
> > > >>>>>>>>> https://github.com/dgibson/qemu/commit/9d07719784ecbeebea71
> > > >>>>>>>>>
> > > >>>>>>>>> ... so you might want to check these patches first to see
> > > >>>>>>>>> whether you can base your rework on them?  
> > > >>>>>>>>
> > > >>>>>>>> Every cpu, and thus every machine, uses CPUState for its
> > > >>>>>>>> cpus. I'm not sure every machine will want to use that new
> > > >>>>>>>> abstract core class though. If they did, then we could
> > > >>>>>>>> indeed use nr_threads from there instead (and remove it
> > > >>>>>>>> from CPUState), but we'd still need nr_cores from the
> > > >>>>>>>> abstract cpu package class (CPUState).  
> > > >>>>>>>
> > > >>>>>>> Hmm.  Since the CPUState object represents just a single
> > > >>>>>>> thread, it seems weird to me that it would have nr_threads
> > > >>>>>>> and nr_cores information.  
> > > >>>>
> > > >>>> Agreed it is weird, and I think we should try to move it away
> > > >>>> from CPUState, not make it part of the TYPE_CPU interface.
> > > >>>> nr_threads belongs to the actual container of the Thread
> > > >>>> objects, and nr_cores in the actual container of the Core
> > > >>>> objects.
> > > >>>>
> > > >>>> The problem is how to implement that in a non-intrusive way
> > > >>>> that would require changing the object hierarchy of all
> > > >>>> architectures.
> > > >>>>
> > > >>>>   
> > > >>>>>>>
> > > >>>>>>> Exposing those as properties makes that much worse, because
> > > >>>>>>> it's now ABI, rather than internal detail we can clean up
> > > >>>>>>> at some future time.  
> > > >>>>>>
> > > >>>>>> CPUState is supposed to be "State of one CPU core or
> > > >>>>>> thread", which justifies having nr_threads state, as it may
> > > >>>>>> be describing a core.  
> > > >>>>>
> > > >>>>> Um.. does it ever actually represent a (multithread) core in
> > > >>>>> practice? It would need to have duplicated register state for
> > > >>>>> every thread were that the case.  
> > > >>>>
> > > >>>> AFAIK, CPUState is still always thread state. Or has this
> > > >>>> changed in some architectures, already?
> > > >>>>   
> > > >>>>>   
> > > >>>>>> I guess there's no justification for having nr_cores in
> > > >>>>>> there though. I agree adding the Core class is a good idea,
> > > >>>>>> assuming it will get used by all machines, and CPUState then
> > > >>>>>> gets changed to a Thread class. The question then, though,
> > > >>>>>> is do we also create a Socket class that contains nr_cores?  
> > > >>>>>
> > > >>>>> That was roughly our intention with the way the cross
> > > >>>>> platform hotplug stuff is evolving.  But the intention was
> > > >>>>> that the Socket objects would only need to be constructed for
> > > >>>>> machine types where it makes sense.  So for example on the
> > > >>>>> paravirt pseries platform, we'll only have Core objects,
> > > >>>>> because the socket distinction isn't really meaningful.
> > > >>>>>   
> > > >>>>>> And how will a Thread method get that information when it
> > > >>>>>> needs to emulate, e.g. CPUID, that requires it? It's a bit
> > > >>>>>> messy, so I'm open to all suggestions on it.  
> > > >>>>>
> > > >>>>> So, if the Thread needs this information, I'm not opposed to
> > > >>>>> it having it internally (presumably populated earlier from
> > > >>>>> the Core object). But I am opposed to it being a locked in
> > > >>>>> part of the interface by having it as an exposed property.  
> > > >>>>
> > > >>>> I agree we don't want to make this part of the external
> > > >>>> interface. In this case, if we don't add the properties, how
> > > >>>> exactly is the Machine or Core code supposed to pass that
> > > >>>> information to the Thread object?
> > > >>>>
> > > >>>> Maybe the intermediate steps could be:
> > > >>>>
> > > >>>> * Make the Thread code that uses CPUState::nr_{cores,threads}
> > > >>>> and smp_{cores,threads} get that info from MachineState
> > > >>>> instead.  
> > > >>>
> > > >>> I have some patches already headed down this road.
> > > >>>
> > > >>>> * On the architectures where we already have a reasonable
> > > >>>>   Socket/Core/Thread hierarchy, let the Thread code simply ask
> > > >>>>   for that information from its parent.  
> > > >>>
> > > >>> I guess that's just spapr so far, or at least spapr is the
> > > >>> closest. Indeed this appears to be the cleanest approach, so
> > > >>> architectures adding support for cpu topology should likely
> > > >>> strive to implement it this way.
> > > >> If I recall correctly, the only thing about accessing parent is
> > > >> that in QOM design accessing parent from child wasn't accepted
> > > >> well, i.e. child shouldn't be aware nor access parent object.
> > > > 
> > > > Can anybody explain why?
> > > > 
> > > > In this case, what's the best way for a parent to pass
> > > > information to its children without adding new externally-visible
> > > > properties that the user is never supposed to set directly?
> > > > 
> > > > Should Thread objects have an additional link to the parent Core
> > > > object, just to be able to get the information it needs?
> > > 
> > > I am not fully aware either and believe I ignored it in my x86
> > > socket patchset, part of which it was RFC.
> > > 
> > > The key thing to consider is that this breaks user instantiation of
> > > a device, so it needs to be disabled.
> > 
> > Good point, and this is hard to solve without changing the way
> > device_add works. Setting extra properties, on the other hand,
> > can be done easily by the hotplug handler if necessary (like we
> > do with apic-id in PC).
> > 
> > Also, if the properties are not supposed to be set directly by
> > the user, then the hotplug handler could refuse to hotplug the
> > device if the user tried to fiddle with them. Then the "external
> > interface" problem is solved.
> > 
> > Now, depending on how much information is needed, "extra
> > properties" may be duplicating data that is already available in
> > other objects (like nr-cores/nr-threads), or just a link property
> > (e.g. a link to the Core object in the case of spapr). If we
> > still don't have the right object topology implemented, then we
> > may need to use individual properties like "nr-cores" and
> > "nr-threads" (preferably as a temporary solution?).
> > 
> > In other words, maybe "nr-cores" and "nr-threads" properties will
> > be useful in x86, but only if we reject device creation in case
> > the user tries to set them manually, and if we do _not_ expose
> > them on TYPE_CPU.
> Should be add a QOM API that could mark property as an internal
> that would be beneficial in generic as we won't have to be scared
> exposing internal stuff to users and be able to hide target specifics
> behind properties?
> 
> it should be simple enough to do.

If it's internal, do we have any reason to register a (writeable)
property in the first place? Why not use a plain old
"obj->field = value" C statement? Or, if a simple assignment
isn't enough, why not a simple obj_set_field(value) C function?

-- 
Eduardo

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

* Re: [Qemu-devel] QOM: best way for parents to pass information to children? (was Re: [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties)
  2016-07-15 21:33                           ` Eduardo Habkost
@ 2016-07-16 15:30                             ` Andrew Jones
  2016-07-19 11:54                               ` Eduardo Habkost
  2016-07-18  7:23                             ` Igor Mammedov
  1 sibling, 1 reply; 74+ messages in thread
From: Andrew Jones @ 2016-07-16 15:30 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: Igor Mammedov, peter.maydell, qemu-devel, agraf, qemu-arm,
	qemu-ppc, Bharata B Rao, Thomas Huth, pbonzini, dgibson,
	Andreas Färber, David Gibson

On Fri, Jul 15, 2016 at 06:33:53PM -0300, Eduardo Habkost wrote:
> On Fri, Jul 15, 2016 at 08:38:35PM +0200, Igor Mammedov wrote:
> > On Fri, 15 Jul 2016 14:43:53 -0300
> > Eduardo Habkost <ehabkost@redhat.com> wrote:
> > > On Fri, Jul 15, 2016 at 06:30:41PM +0200, Andreas Färber wrote:
> > > > Am 15.07.2016 um 18:10 schrieb Eduardo Habkost:
> > > > > On Fri, Jul 15, 2016 at 11:11:38AM +0200, Igor Mammedov wrote:
> > > > >> On Fri, 15 Jul 2016 08:35:30 +0200
> > > > >> Andrew Jones <drjones@redhat.com> wrote:
> > > > >>> On Thu, Jul 14, 2016 at 05:07:43PM -0300, Eduardo Habkost wrote:
> > > > >>>>
> > > > >>>> First of all, sorry for the horrible delay in replying to this
> > > > >>>> thread.
> > > > >>>>
> > > > >>>> On Wed, Jun 15, 2016 at 10:56:20AM +1000, David Gibson wrote:  
> > > > >>>>> On Tue, Jun 14, 2016 at 08:19:49AM +0200, Andrew Jones
> > > > >>>>> wrote:  
> > > > >>>>>> On Tue, Jun 14, 2016 at 12:12:16PM +1000, David Gibson
> > > > >>>>>> wrote:  
> > > > >>>>>>> On Sun, Jun 12, 2016 at 03:48:10PM +0200, Andrew Jones
> > > > >>>>>>> wrote:  
> > > > > [...]
> > > > >>>>>>>>>> +static Property cpu_common_properties[] = {
> > > > >>>>>>>>>> +    DEFINE_PROP_INT32("nr-cores", CPUState, nr_cores,
> > > > >>>>>>>>>> 1),
> > > > >>>>>>>>>> +    DEFINE_PROP_INT32("nr-threads", CPUState,
> > > > >>>>>>>>>> nr_threads, 1),
> > > > >>>>>>>>>> +    DEFINE_PROP_END_OF_LIST()
> > > > >>>>>>>>>> +};  
> > > > >>>>>>>>>
> > > > >>>>>>>>> Are you aware of the current CPU hotplug discussion that
> > > > >>>>>>>>> is going on?  
> > > > >>>>>>>>
> > > > >>>>>>>> I'm aware of it going on, but haven't been following it.
> > > > >>>>>>>>   
> > > > >>>>>>>>> I'm not very involved there, but I think some of these
> > > > >>>>>>>>> reworks also move "nr_threads" into the CPU state
> > > > >>>>>>>>> already, e.g. see:  
> > > > >>>>>>>>
> > > > >>>>>>>> nr_threads (and nr_cores) are already state in CPUState.
> > > > >>>>>>>> This patch just exposes that state via properties.
> > > > >>>>>>>>   
> > > > >>>>>>>>>
> > > > >>>>>>>>> https://github.com/dgibson/qemu/commit/9d07719784ecbeebea71
> > > > >>>>>>>>>
> > > > >>>>>>>>> ... so you might want to check these patches first to see
> > > > >>>>>>>>> whether you can base your rework on them?  
> > > > >>>>>>>>
> > > > >>>>>>>> Every cpu, and thus every machine, uses CPUState for its
> > > > >>>>>>>> cpus. I'm not sure every machine will want to use that new
> > > > >>>>>>>> abstract core class though. If they did, then we could
> > > > >>>>>>>> indeed use nr_threads from there instead (and remove it
> > > > >>>>>>>> from CPUState), but we'd still need nr_cores from the
> > > > >>>>>>>> abstract cpu package class (CPUState).  
> > > > >>>>>>>
> > > > >>>>>>> Hmm.  Since the CPUState object represents just a single
> > > > >>>>>>> thread, it seems weird to me that it would have nr_threads
> > > > >>>>>>> and nr_cores information.  
> > > > >>>>
> > > > >>>> Agreed it is weird, and I think we should try to move it away
> > > > >>>> from CPUState, not make it part of the TYPE_CPU interface.
> > > > >>>> nr_threads belongs to the actual container of the Thread
> > > > >>>> objects, and nr_cores in the actual container of the Core
> > > > >>>> objects.
> > > > >>>>
> > > > >>>> The problem is how to implement that in a non-intrusive way
> > > > >>>> that would require changing the object hierarchy of all
> > > > >>>> architectures.
> > > > >>>>
> > > > >>>>   
> > > > >>>>>>>
> > > > >>>>>>> Exposing those as properties makes that much worse, because
> > > > >>>>>>> it's now ABI, rather than internal detail we can clean up
> > > > >>>>>>> at some future time.  
> > > > >>>>>>
> > > > >>>>>> CPUState is supposed to be "State of one CPU core or
> > > > >>>>>> thread", which justifies having nr_threads state, as it may
> > > > >>>>>> be describing a core.  
> > > > >>>>>
> > > > >>>>> Um.. does it ever actually represent a (multithread) core in
> > > > >>>>> practice? It would need to have duplicated register state for
> > > > >>>>> every thread were that the case.  
> > > > >>>>
> > > > >>>> AFAIK, CPUState is still always thread state. Or has this
> > > > >>>> changed in some architectures, already?
> > > > >>>>   
> > > > >>>>>   
> > > > >>>>>> I guess there's no justification for having nr_cores in
> > > > >>>>>> there though. I agree adding the Core class is a good idea,
> > > > >>>>>> assuming it will get used by all machines, and CPUState then
> > > > >>>>>> gets changed to a Thread class. The question then, though,
> > > > >>>>>> is do we also create a Socket class that contains nr_cores?  
> > > > >>>>>
> > > > >>>>> That was roughly our intention with the way the cross
> > > > >>>>> platform hotplug stuff is evolving.  But the intention was
> > > > >>>>> that the Socket objects would only need to be constructed for
> > > > >>>>> machine types where it makes sense.  So for example on the
> > > > >>>>> paravirt pseries platform, we'll only have Core objects,
> > > > >>>>> because the socket distinction isn't really meaningful.
> > > > >>>>>   
> > > > >>>>>> And how will a Thread method get that information when it
> > > > >>>>>> needs to emulate, e.g. CPUID, that requires it? It's a bit
> > > > >>>>>> messy, so I'm open to all suggestions on it.  
> > > > >>>>>
> > > > >>>>> So, if the Thread needs this information, I'm not opposed to
> > > > >>>>> it having it internally (presumably populated earlier from
> > > > >>>>> the Core object). But I am opposed to it being a locked in
> > > > >>>>> part of the interface by having it as an exposed property.  
> > > > >>>>
> > > > >>>> I agree we don't want to make this part of the external
> > > > >>>> interface. In this case, if we don't add the properties, how
> > > > >>>> exactly is the Machine or Core code supposed to pass that
> > > > >>>> information to the Thread object?
> > > > >>>>
> > > > >>>> Maybe the intermediate steps could be:
> > > > >>>>
> > > > >>>> * Make the Thread code that uses CPUState::nr_{cores,threads}
> > > > >>>> and smp_{cores,threads} get that info from MachineState
> > > > >>>> instead.  
> > > > >>>
> > > > >>> I have some patches already headed down this road.
> > > > >>>
> > > > >>>> * On the architectures where we already have a reasonable
> > > > >>>>   Socket/Core/Thread hierarchy, let the Thread code simply ask
> > > > >>>>   for that information from its parent.  
> > > > >>>
> > > > >>> I guess that's just spapr so far, or at least spapr is the
> > > > >>> closest. Indeed this appears to be the cleanest approach, so
> > > > >>> architectures adding support for cpu topology should likely
> > > > >>> strive to implement it this way.
> > > > >> If I recall correctly, the only thing about accessing parent is
> > > > >> that in QOM design accessing parent from child wasn't accepted
> > > > >> well, i.e. child shouldn't be aware nor access parent object.
> > > > > 
> > > > > Can anybody explain why?
> > > > > 
> > > > > In this case, what's the best way for a parent to pass
> > > > > information to its children without adding new externally-visible
> > > > > properties that the user is never supposed to set directly?
> > > > > 
> > > > > Should Thread objects have an additional link to the parent Core
> > > > > object, just to be able to get the information it needs?
> > > > 
> > > > I am not fully aware either and believe I ignored it in my x86
> > > > socket patchset, part of which it was RFC.
> > > > 
> > > > The key thing to consider is that this breaks user instantiation of
> > > > a device, so it needs to be disabled.
> > > 
> > > Good point, and this is hard to solve without changing the way
> > > device_add works. Setting extra properties, on the other hand,
> > > can be done easily by the hotplug handler if necessary (like we
> > > do with apic-id in PC).
> > > 
> > > Also, if the properties are not supposed to be set directly by
> > > the user, then the hotplug handler could refuse to hotplug the
> > > device if the user tried to fiddle with them. Then the "external
> > > interface" problem is solved.
> > > 
> > > Now, depending on how much information is needed, "extra
> > > properties" may be duplicating data that is already available in
> > > other objects (like nr-cores/nr-threads), or just a link property
> > > (e.g. a link to the Core object in the case of spapr). If we
> > > still don't have the right object topology implemented, then we
> > > may need to use individual properties like "nr-cores" and
> > > "nr-threads" (preferably as a temporary solution?).
> > > 
> > > In other words, maybe "nr-cores" and "nr-threads" properties will
> > > be useful in x86, but only if we reject device creation in case
> > > the user tries to set them manually, and if we do _not_ expose
> > > them on TYPE_CPU.
> > Should be add a QOM API that could mark property as an internal
> > that would be beneficial in generic as we won't have to be scared
> > exposing internal stuff to users and be able to hide target specifics
> > behind properties?
> > 
> > it should be simple enough to do.
> 
> If it's internal, do we have any reason to register a (writeable)
> property in the first place? Why not use a plain old
> "obj->field = value" C statement? Or, if a simple assignment
> isn't enough, why not a simple obj_set_field(value) C function?

Being able to use qdev_prop_register_global was the motivation for
making nr-cores,nr-threads properties. If we can create something
like that for a "field", without too much code duplication, then
that'd work. If we end up duplicating much of the property code,
though, then I think extending the property code with a set-as-internal
feature, as Igor proposes, may be the better way to go.

Thanks,
drew

> 
> -- 
> Eduardo
> 

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

* Re: [Qemu-devel] QOM: best way for parents to pass information to children? (was Re: [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties)
  2016-07-15 21:33                           ` Eduardo Habkost
  2016-07-16 15:30                             ` Andrew Jones
@ 2016-07-18  7:23                             ` Igor Mammedov
  2016-07-19 11:59                               ` Eduardo Habkost
  1 sibling, 1 reply; 74+ messages in thread
From: Igor Mammedov @ 2016-07-18  7:23 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: peter.maydell, Andrew Jones, qemu-devel, agraf, qemu-arm,
	qemu-ppc, Bharata B Rao, Thomas Huth, pbonzini, dgibson,
	Andreas Färber, David Gibson

On Fri, 15 Jul 2016 18:33:53 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:

> On Fri, Jul 15, 2016 at 08:38:35PM +0200, Igor Mammedov wrote:
> > On Fri, 15 Jul 2016 14:43:53 -0300
> > Eduardo Habkost <ehabkost@redhat.com> wrote:  
> > > On Fri, Jul 15, 2016 at 06:30:41PM +0200, Andreas Färber wrote:  
> > > > Am 15.07.2016 um 18:10 schrieb Eduardo Habkost:  
> > > > > On Fri, Jul 15, 2016 at 11:11:38AM +0200, Igor Mammedov wrote:  
> > > > >> On Fri, 15 Jul 2016 08:35:30 +0200
> > > > >> Andrew Jones <drjones@redhat.com> wrote:  
> > > > >>> On Thu, Jul 14, 2016 at 05:07:43PM -0300, Eduardo Habkost wrote:  
> > > > >>>>
> > > > >>>> First of all, sorry for the horrible delay in replying to this
> > > > >>>> thread.
> > > > >>>>
> > > > >>>> On Wed, Jun 15, 2016 at 10:56:20AM +1000, David Gibson wrote:    
> > > > >>>>> On Tue, Jun 14, 2016 at 08:19:49AM +0200, Andrew Jones
> > > > >>>>> wrote:    
> > > > >>>>>> On Tue, Jun 14, 2016 at 12:12:16PM +1000, David Gibson
> > > > >>>>>> wrote:    
> > > > >>>>>>> On Sun, Jun 12, 2016 at 03:48:10PM +0200, Andrew Jones
> > > > >>>>>>> wrote:    
> > > > > [...]  
> > > > >>>>>>>>>> +static Property cpu_common_properties[] = {
> > > > >>>>>>>>>> +    DEFINE_PROP_INT32("nr-cores", CPUState, nr_cores,
> > > > >>>>>>>>>> 1),
> > > > >>>>>>>>>> +    DEFINE_PROP_INT32("nr-threads", CPUState,
> > > > >>>>>>>>>> nr_threads, 1),
> > > > >>>>>>>>>> +    DEFINE_PROP_END_OF_LIST()
> > > > >>>>>>>>>> +};    
> > > > >>>>>>>>>
> > > > >>>>>>>>> Are you aware of the current CPU hotplug discussion that
> > > > >>>>>>>>> is going on?    
> > > > >>>>>>>>
> > > > >>>>>>>> I'm aware of it going on, but haven't been following it.
> > > > >>>>>>>>     
> > > > >>>>>>>>> I'm not very involved there, but I think some of these
> > > > >>>>>>>>> reworks also move "nr_threads" into the CPU state
> > > > >>>>>>>>> already, e.g. see:    
> > > > >>>>>>>>
> > > > >>>>>>>> nr_threads (and nr_cores) are already state in CPUState.
> > > > >>>>>>>> This patch just exposes that state via properties.
> > > > >>>>>>>>     
> > > > >>>>>>>>>
> > > > >>>>>>>>> https://github.com/dgibson/qemu/commit/9d07719784ecbeebea71
> > > > >>>>>>>>>
> > > > >>>>>>>>> ... so you might want to check these patches first to see
> > > > >>>>>>>>> whether you can base your rework on them?    
> > > > >>>>>>>>
> > > > >>>>>>>> Every cpu, and thus every machine, uses CPUState for its
> > > > >>>>>>>> cpus. I'm not sure every machine will want to use that new
> > > > >>>>>>>> abstract core class though. If they did, then we could
> > > > >>>>>>>> indeed use nr_threads from there instead (and remove it
> > > > >>>>>>>> from CPUState), but we'd still need nr_cores from the
> > > > >>>>>>>> abstract cpu package class (CPUState).    
> > > > >>>>>>>
> > > > >>>>>>> Hmm.  Since the CPUState object represents just a single
> > > > >>>>>>> thread, it seems weird to me that it would have nr_threads
> > > > >>>>>>> and nr_cores information.    
> > > > >>>>
> > > > >>>> Agreed it is weird, and I think we should try to move it away
> > > > >>>> from CPUState, not make it part of the TYPE_CPU interface.
> > > > >>>> nr_threads belongs to the actual container of the Thread
> > > > >>>> objects, and nr_cores in the actual container of the Core
> > > > >>>> objects.
> > > > >>>>
> > > > >>>> The problem is how to implement that in a non-intrusive way
> > > > >>>> that would require changing the object hierarchy of all
> > > > >>>> architectures.
> > > > >>>>
> > > > >>>>     
> > > > >>>>>>>
> > > > >>>>>>> Exposing those as properties makes that much worse, because
> > > > >>>>>>> it's now ABI, rather than internal detail we can clean up
> > > > >>>>>>> at some future time.    
> > > > >>>>>>
> > > > >>>>>> CPUState is supposed to be "State of one CPU core or
> > > > >>>>>> thread", which justifies having nr_threads state, as it may
> > > > >>>>>> be describing a core.    
> > > > >>>>>
> > > > >>>>> Um.. does it ever actually represent a (multithread) core in
> > > > >>>>> practice? It would need to have duplicated register state for
> > > > >>>>> every thread were that the case.    
> > > > >>>>
> > > > >>>> AFAIK, CPUState is still always thread state. Or has this
> > > > >>>> changed in some architectures, already?
> > > > >>>>     
> > > > >>>>>     
> > > > >>>>>> I guess there's no justification for having nr_cores in
> > > > >>>>>> there though. I agree adding the Core class is a good idea,
> > > > >>>>>> assuming it will get used by all machines, and CPUState then
> > > > >>>>>> gets changed to a Thread class. The question then, though,
> > > > >>>>>> is do we also create a Socket class that contains nr_cores?    
> > > > >>>>>
> > > > >>>>> That was roughly our intention with the way the cross
> > > > >>>>> platform hotplug stuff is evolving.  But the intention was
> > > > >>>>> that the Socket objects would only need to be constructed for
> > > > >>>>> machine types where it makes sense.  So for example on the
> > > > >>>>> paravirt pseries platform, we'll only have Core objects,
> > > > >>>>> because the socket distinction isn't really meaningful.
> > > > >>>>>     
> > > > >>>>>> And how will a Thread method get that information when it
> > > > >>>>>> needs to emulate, e.g. CPUID, that requires it? It's a bit
> > > > >>>>>> messy, so I'm open to all suggestions on it.    
> > > > >>>>>
> > > > >>>>> So, if the Thread needs this information, I'm not opposed to
> > > > >>>>> it having it internally (presumably populated earlier from
> > > > >>>>> the Core object). But I am opposed to it being a locked in
> > > > >>>>> part of the interface by having it as an exposed property.    
> > > > >>>>
> > > > >>>> I agree we don't want to make this part of the external
> > > > >>>> interface. In this case, if we don't add the properties, how
> > > > >>>> exactly is the Machine or Core code supposed to pass that
> > > > >>>> information to the Thread object?
> > > > >>>>
> > > > >>>> Maybe the intermediate steps could be:
> > > > >>>>
> > > > >>>> * Make the Thread code that uses CPUState::nr_{cores,threads}
> > > > >>>> and smp_{cores,threads} get that info from MachineState
> > > > >>>> instead.    
> > > > >>>
> > > > >>> I have some patches already headed down this road.
> > > > >>>  
> > > > >>>> * On the architectures where we already have a reasonable
> > > > >>>>   Socket/Core/Thread hierarchy, let the Thread code simply ask
> > > > >>>>   for that information from its parent.    
> > > > >>>
> > > > >>> I guess that's just spapr so far, or at least spapr is the
> > > > >>> closest. Indeed this appears to be the cleanest approach, so
> > > > >>> architectures adding support for cpu topology should likely
> > > > >>> strive to implement it this way.  
> > > > >> If I recall correctly, the only thing about accessing parent is
> > > > >> that in QOM design accessing parent from child wasn't accepted
> > > > >> well, i.e. child shouldn't be aware nor access parent object.  
> > > > > 
> > > > > Can anybody explain why?
> > > > > 
> > > > > In this case, what's the best way for a parent to pass
> > > > > information to its children without adding new externally-visible
> > > > > properties that the user is never supposed to set directly?
> > > > > 
> > > > > Should Thread objects have an additional link to the parent Core
> > > > > object, just to be able to get the information it needs?  
> > > > 
> > > > I am not fully aware either and believe I ignored it in my x86
> > > > socket patchset, part of which it was RFC.
> > > > 
> > > > The key thing to consider is that this breaks user instantiation of
> > > > a device, so it needs to be disabled.  
> > > 
> > > Good point, and this is hard to solve without changing the way
> > > device_add works. Setting extra properties, on the other hand,
> > > can be done easily by the hotplug handler if necessary (like we
> > > do with apic-id in PC).
> > > 
> > > Also, if the properties are not supposed to be set directly by
> > > the user, then the hotplug handler could refuse to hotplug the
> > > device if the user tried to fiddle with them. Then the "external
> > > interface" problem is solved.
> > > 
> > > Now, depending on how much information is needed, "extra
> > > properties" may be duplicating data that is already available in
> > > other objects (like nr-cores/nr-threads), or just a link property
> > > (e.g. a link to the Core object in the case of spapr). If we
> > > still don't have the right object topology implemented, then we
> > > may need to use individual properties like "nr-cores" and
> > > "nr-threads" (preferably as a temporary solution?).
> > > 
> > > In other words, maybe "nr-cores" and "nr-threads" properties will
> > > be useful in x86, but only if we reject device creation in case
> > > the user tries to set them manually, and if we do _not_ expose
> > > them on TYPE_CPU.  
> > Should be add a QOM API that could mark property as an internal
> > that would be beneficial in generic as we won't have to be scared
> > exposing internal stuff to users and be able to hide target specifics
> > behind properties?
> > 
> > it should be simple enough to do.  
> 
> If it's internal, do we have any reason to register a (writeable)
> property in the first place? Why not use a plain old
> "obj->field = value" C statement? Or, if a simple assignment
> isn't enough, why not a simple obj_set_field(value) C function?
So that arch neutral code won't have to pull obj type definition
and we would be able to reuse all machinery that uses properties
instead of inventing yet another API or ad-hoc function calls.

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

* Re: [Qemu-devel] QOM: best way for parents to pass information to children? (was Re: [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties)
  2016-07-16 15:30                             ` Andrew Jones
@ 2016-07-19 11:54                               ` Eduardo Habkost
  0 siblings, 0 replies; 74+ messages in thread
From: Eduardo Habkost @ 2016-07-19 11:54 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Igor Mammedov, peter.maydell, qemu-devel, agraf, qemu-arm,
	qemu-ppc, Bharata B Rao, Thomas Huth, pbonzini, dgibson,
	Andreas Färber, David Gibson

On Sat, Jul 16, 2016 at 05:30:04PM +0200, Andrew Jones wrote:
> On Fri, Jul 15, 2016 at 06:33:53PM -0300, Eduardo Habkost wrote:
> > On Fri, Jul 15, 2016 at 08:38:35PM +0200, Igor Mammedov wrote:
> > > On Fri, 15 Jul 2016 14:43:53 -0300
> > > Eduardo Habkost <ehabkost@redhat.com> wrote:
> > > > On Fri, Jul 15, 2016 at 06:30:41PM +0200, Andreas Färber wrote:
> > > > > Am 15.07.2016 um 18:10 schrieb Eduardo Habkost:
> > > > > > On Fri, Jul 15, 2016 at 11:11:38AM +0200, Igor Mammedov wrote:
> > > > > >> On Fri, 15 Jul 2016 08:35:30 +0200
> > > > > >> Andrew Jones <drjones@redhat.com> wrote:
> > > > > >>> On Thu, Jul 14, 2016 at 05:07:43PM -0300, Eduardo Habkost wrote:
> > > > > >>>>
> > > > > >>>> First of all, sorry for the horrible delay in replying to this
> > > > > >>>> thread.
> > > > > >>>>
> > > > > >>>> On Wed, Jun 15, 2016 at 10:56:20AM +1000, David Gibson wrote:  
> > > > > >>>>> On Tue, Jun 14, 2016 at 08:19:49AM +0200, Andrew Jones
> > > > > >>>>> wrote:  
> > > > > >>>>>> On Tue, Jun 14, 2016 at 12:12:16PM +1000, David Gibson
> > > > > >>>>>> wrote:  
> > > > > >>>>>>> On Sun, Jun 12, 2016 at 03:48:10PM +0200, Andrew Jones
> > > > > >>>>>>> wrote:  
> > > > > > [...]
> > > > > >>>>>>>>>> +static Property cpu_common_properties[] = {
> > > > > >>>>>>>>>> +    DEFINE_PROP_INT32("nr-cores", CPUState, nr_cores,
> > > > > >>>>>>>>>> 1),
> > > > > >>>>>>>>>> +    DEFINE_PROP_INT32("nr-threads", CPUState,
> > > > > >>>>>>>>>> nr_threads, 1),
> > > > > >>>>>>>>>> +    DEFINE_PROP_END_OF_LIST()
> > > > > >>>>>>>>>> +};  
> > > > > >>>>>>>>>
> > > > > >>>>>>>>> Are you aware of the current CPU hotplug discussion that
> > > > > >>>>>>>>> is going on?  
> > > > > >>>>>>>>
> > > > > >>>>>>>> I'm aware of it going on, but haven't been following it.
> > > > > >>>>>>>>   
> > > > > >>>>>>>>> I'm not very involved there, but I think some of these
> > > > > >>>>>>>>> reworks also move "nr_threads" into the CPU state
> > > > > >>>>>>>>> already, e.g. see:  
> > > > > >>>>>>>>
> > > > > >>>>>>>> nr_threads (and nr_cores) are already state in CPUState.
> > > > > >>>>>>>> This patch just exposes that state via properties.
> > > > > >>>>>>>>   
> > > > > >>>>>>>>>
> > > > > >>>>>>>>> https://github.com/dgibson/qemu/commit/9d07719784ecbeebea71
> > > > > >>>>>>>>>
> > > > > >>>>>>>>> ... so you might want to check these patches first to see
> > > > > >>>>>>>>> whether you can base your rework on them?  
> > > > > >>>>>>>>
> > > > > >>>>>>>> Every cpu, and thus every machine, uses CPUState for its
> > > > > >>>>>>>> cpus. I'm not sure every machine will want to use that new
> > > > > >>>>>>>> abstract core class though. If they did, then we could
> > > > > >>>>>>>> indeed use nr_threads from there instead (and remove it
> > > > > >>>>>>>> from CPUState), but we'd still need nr_cores from the
> > > > > >>>>>>>> abstract cpu package class (CPUState).  
> > > > > >>>>>>>
> > > > > >>>>>>> Hmm.  Since the CPUState object represents just a single
> > > > > >>>>>>> thread, it seems weird to me that it would have nr_threads
> > > > > >>>>>>> and nr_cores information.  
> > > > > >>>>
> > > > > >>>> Agreed it is weird, and I think we should try to move it away
> > > > > >>>> from CPUState, not make it part of the TYPE_CPU interface.
> > > > > >>>> nr_threads belongs to the actual container of the Thread
> > > > > >>>> objects, and nr_cores in the actual container of the Core
> > > > > >>>> objects.
> > > > > >>>>
> > > > > >>>> The problem is how to implement that in a non-intrusive way
> > > > > >>>> that would require changing the object hierarchy of all
> > > > > >>>> architectures.
> > > > > >>>>
> > > > > >>>>   
> > > > > >>>>>>>
> > > > > >>>>>>> Exposing those as properties makes that much worse, because
> > > > > >>>>>>> it's now ABI, rather than internal detail we can clean up
> > > > > >>>>>>> at some future time.  
> > > > > >>>>>>
> > > > > >>>>>> CPUState is supposed to be "State of one CPU core or
> > > > > >>>>>> thread", which justifies having nr_threads state, as it may
> > > > > >>>>>> be describing a core.  
> > > > > >>>>>
> > > > > >>>>> Um.. does it ever actually represent a (multithread) core in
> > > > > >>>>> practice? It would need to have duplicated register state for
> > > > > >>>>> every thread were that the case.  
> > > > > >>>>
> > > > > >>>> AFAIK, CPUState is still always thread state. Or has this
> > > > > >>>> changed in some architectures, already?
> > > > > >>>>   
> > > > > >>>>>   
> > > > > >>>>>> I guess there's no justification for having nr_cores in
> > > > > >>>>>> there though. I agree adding the Core class is a good idea,
> > > > > >>>>>> assuming it will get used by all machines, and CPUState then
> > > > > >>>>>> gets changed to a Thread class. The question then, though,
> > > > > >>>>>> is do we also create a Socket class that contains nr_cores?  
> > > > > >>>>>
> > > > > >>>>> That was roughly our intention with the way the cross
> > > > > >>>>> platform hotplug stuff is evolving.  But the intention was
> > > > > >>>>> that the Socket objects would only need to be constructed for
> > > > > >>>>> machine types where it makes sense.  So for example on the
> > > > > >>>>> paravirt pseries platform, we'll only have Core objects,
> > > > > >>>>> because the socket distinction isn't really meaningful.
> > > > > >>>>>   
> > > > > >>>>>> And how will a Thread method get that information when it
> > > > > >>>>>> needs to emulate, e.g. CPUID, that requires it? It's a bit
> > > > > >>>>>> messy, so I'm open to all suggestions on it.  
> > > > > >>>>>
> > > > > >>>>> So, if the Thread needs this information, I'm not opposed to
> > > > > >>>>> it having it internally (presumably populated earlier from
> > > > > >>>>> the Core object). But I am opposed to it being a locked in
> > > > > >>>>> part of the interface by having it as an exposed property.  
> > > > > >>>>
> > > > > >>>> I agree we don't want to make this part of the external
> > > > > >>>> interface. In this case, if we don't add the properties, how
> > > > > >>>> exactly is the Machine or Core code supposed to pass that
> > > > > >>>> information to the Thread object?
> > > > > >>>>
> > > > > >>>> Maybe the intermediate steps could be:
> > > > > >>>>
> > > > > >>>> * Make the Thread code that uses CPUState::nr_{cores,threads}
> > > > > >>>> and smp_{cores,threads} get that info from MachineState
> > > > > >>>> instead.  
> > > > > >>>
> > > > > >>> I have some patches already headed down this road.
> > > > > >>>
> > > > > >>>> * On the architectures where we already have a reasonable
> > > > > >>>>   Socket/Core/Thread hierarchy, let the Thread code simply ask
> > > > > >>>>   for that information from its parent.  
> > > > > >>>
> > > > > >>> I guess that's just spapr so far, or at least spapr is the
> > > > > >>> closest. Indeed this appears to be the cleanest approach, so
> > > > > >>> architectures adding support for cpu topology should likely
> > > > > >>> strive to implement it this way.
> > > > > >> If I recall correctly, the only thing about accessing parent is
> > > > > >> that in QOM design accessing parent from child wasn't accepted
> > > > > >> well, i.e. child shouldn't be aware nor access parent object.
> > > > > > 
> > > > > > Can anybody explain why?
> > > > > > 
> > > > > > In this case, what's the best way for a parent to pass
> > > > > > information to its children without adding new externally-visible
> > > > > > properties that the user is never supposed to set directly?
> > > > > > 
> > > > > > Should Thread objects have an additional link to the parent Core
> > > > > > object, just to be able to get the information it needs?
> > > > > 
> > > > > I am not fully aware either and believe I ignored it in my x86
> > > > > socket patchset, part of which it was RFC.
> > > > > 
> > > > > The key thing to consider is that this breaks user instantiation of
> > > > > a device, so it needs to be disabled.
> > > > 
> > > > Good point, and this is hard to solve without changing the way
> > > > device_add works. Setting extra properties, on the other hand,
> > > > can be done easily by the hotplug handler if necessary (like we
> > > > do with apic-id in PC).
> > > > 
> > > > Also, if the properties are not supposed to be set directly by
> > > > the user, then the hotplug handler could refuse to hotplug the
> > > > device if the user tried to fiddle with them. Then the "external
> > > > interface" problem is solved.
> > > > 
> > > > Now, depending on how much information is needed, "extra
> > > > properties" may be duplicating data that is already available in
> > > > other objects (like nr-cores/nr-threads), or just a link property
> > > > (e.g. a link to the Core object in the case of spapr). If we
> > > > still don't have the right object topology implemented, then we
> > > > may need to use individual properties like "nr-cores" and
> > > > "nr-threads" (preferably as a temporary solution?).
> > > > 
> > > > In other words, maybe "nr-cores" and "nr-threads" properties will
> > > > be useful in x86, but only if we reject device creation in case
> > > > the user tries to set them manually, and if we do _not_ expose
> > > > them on TYPE_CPU.
> > > Should be add a QOM API that could mark property as an internal
> > > that would be beneficial in generic as we won't have to be scared
> > > exposing internal stuff to users and be able to hide target specifics
> > > behind properties?
> > > 
> > > it should be simple enough to do.
> > 
> > If it's internal, do we have any reason to register a (writeable)
> > property in the first place? Why not use a plain old
> > "obj->field = value" C statement? Or, if a simple assignment
> > isn't enough, why not a simple obj_set_field(value) C function?
> 
> Being able to use qdev_prop_register_global was the motivation for
> making nr-cores,nr-threads properties. If we can create something
> like that for a "field", without too much code duplication, then
> that'd work. If we end up duplicating much of the property code,
> though, then I think extending the property code with a set-as-internal
> feature, as Igor proposes, may be the better way to go.

In the case of -smp, I don't think we should use global
properties: we just need to set the right MachineState fields.
But you have a point: compat_props (which are registered as
global properties) are probably the main reason we have been
adding QOM properties for internal stuff.

But maybe that's a feature? If we want to make something
different depending on the machine-type, it's better to make the
difference visible to the user and management software.

-- 
Eduardo

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

* Re: [Qemu-devel] QOM: best way for parents to pass information to children? (was Re: [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties)
  2016-07-18  7:23                             ` Igor Mammedov
@ 2016-07-19 11:59                               ` Eduardo Habkost
  2016-07-19 12:21                                 ` Paolo Bonzini
  0 siblings, 1 reply; 74+ messages in thread
From: Eduardo Habkost @ 2016-07-19 11:59 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, Andrew Jones, qemu-devel, agraf, qemu-arm,
	qemu-ppc, Bharata B Rao, Thomas Huth, pbonzini, dgibson,
	Andreas Färber, David Gibson

On Mon, Jul 18, 2016 at 09:23:04AM +0200, Igor Mammedov wrote:
> On Fri, 15 Jul 2016 18:33:53 -0300
> Eduardo Habkost <ehabkost@redhat.com> wrote:
> 
> > On Fri, Jul 15, 2016 at 08:38:35PM +0200, Igor Mammedov wrote:
> > > On Fri, 15 Jul 2016 14:43:53 -0300
> > > Eduardo Habkost <ehabkost@redhat.com> wrote:  
> > > > On Fri, Jul 15, 2016 at 06:30:41PM +0200, Andreas Färber wrote:  
> > > > > Am 15.07.2016 um 18:10 schrieb Eduardo Habkost:  
> > > > > > On Fri, Jul 15, 2016 at 11:11:38AM +0200, Igor Mammedov wrote:  
> > > > > >> On Fri, 15 Jul 2016 08:35:30 +0200
> > > > > >> Andrew Jones <drjones@redhat.com> wrote:  
> > > > > >>> On Thu, Jul 14, 2016 at 05:07:43PM -0300, Eduardo Habkost wrote:  
> > > > > >>>>
> > > > > >>>> First of all, sorry for the horrible delay in replying to this
> > > > > >>>> thread.
> > > > > >>>>
> > > > > >>>> On Wed, Jun 15, 2016 at 10:56:20AM +1000, David Gibson wrote:    
> > > > > >>>>> On Tue, Jun 14, 2016 at 08:19:49AM +0200, Andrew Jones
> > > > > >>>>> wrote:    
> > > > > >>>>>> On Tue, Jun 14, 2016 at 12:12:16PM +1000, David Gibson
> > > > > >>>>>> wrote:    
> > > > > >>>>>>> On Sun, Jun 12, 2016 at 03:48:10PM +0200, Andrew Jones
> > > > > >>>>>>> wrote:    
> > > > > > [...]  
> > > > > >>>>>>>>>> +static Property cpu_common_properties[] = {
> > > > > >>>>>>>>>> +    DEFINE_PROP_INT32("nr-cores", CPUState, nr_cores,
> > > > > >>>>>>>>>> 1),
> > > > > >>>>>>>>>> +    DEFINE_PROP_INT32("nr-threads", CPUState,
> > > > > >>>>>>>>>> nr_threads, 1),
> > > > > >>>>>>>>>> +    DEFINE_PROP_END_OF_LIST()
> > > > > >>>>>>>>>> +};    
> > > > > >>>>>>>>>
> > > > > >>>>>>>>> Are you aware of the current CPU hotplug discussion that
> > > > > >>>>>>>>> is going on?    
> > > > > >>>>>>>>
> > > > > >>>>>>>> I'm aware of it going on, but haven't been following it.
> > > > > >>>>>>>>     
> > > > > >>>>>>>>> I'm not very involved there, but I think some of these
> > > > > >>>>>>>>> reworks also move "nr_threads" into the CPU state
> > > > > >>>>>>>>> already, e.g. see:    
> > > > > >>>>>>>>
> > > > > >>>>>>>> nr_threads (and nr_cores) are already state in CPUState.
> > > > > >>>>>>>> This patch just exposes that state via properties.
> > > > > >>>>>>>>     
> > > > > >>>>>>>>>
> > > > > >>>>>>>>> https://github.com/dgibson/qemu/commit/9d07719784ecbeebea71
> > > > > >>>>>>>>>
> > > > > >>>>>>>>> ... so you might want to check these patches first to see
> > > > > >>>>>>>>> whether you can base your rework on them?    
> > > > > >>>>>>>>
> > > > > >>>>>>>> Every cpu, and thus every machine, uses CPUState for its
> > > > > >>>>>>>> cpus. I'm not sure every machine will want to use that new
> > > > > >>>>>>>> abstract core class though. If they did, then we could
> > > > > >>>>>>>> indeed use nr_threads from there instead (and remove it
> > > > > >>>>>>>> from CPUState), but we'd still need nr_cores from the
> > > > > >>>>>>>> abstract cpu package class (CPUState).    
> > > > > >>>>>>>
> > > > > >>>>>>> Hmm.  Since the CPUState object represents just a single
> > > > > >>>>>>> thread, it seems weird to me that it would have nr_threads
> > > > > >>>>>>> and nr_cores information.    
> > > > > >>>>
> > > > > >>>> Agreed it is weird, and I think we should try to move it away
> > > > > >>>> from CPUState, not make it part of the TYPE_CPU interface.
> > > > > >>>> nr_threads belongs to the actual container of the Thread
> > > > > >>>> objects, and nr_cores in the actual container of the Core
> > > > > >>>> objects.
> > > > > >>>>
> > > > > >>>> The problem is how to implement that in a non-intrusive way
> > > > > >>>> that would require changing the object hierarchy of all
> > > > > >>>> architectures.
> > > > > >>>>
> > > > > >>>>     
> > > > > >>>>>>>
> > > > > >>>>>>> Exposing those as properties makes that much worse, because
> > > > > >>>>>>> it's now ABI, rather than internal detail we can clean up
> > > > > >>>>>>> at some future time.    
> > > > > >>>>>>
> > > > > >>>>>> CPUState is supposed to be "State of one CPU core or
> > > > > >>>>>> thread", which justifies having nr_threads state, as it may
> > > > > >>>>>> be describing a core.    
> > > > > >>>>>
> > > > > >>>>> Um.. does it ever actually represent a (multithread) core in
> > > > > >>>>> practice? It would need to have duplicated register state for
> > > > > >>>>> every thread were that the case.    
> > > > > >>>>
> > > > > >>>> AFAIK, CPUState is still always thread state. Or has this
> > > > > >>>> changed in some architectures, already?
> > > > > >>>>     
> > > > > >>>>>     
> > > > > >>>>>> I guess there's no justification for having nr_cores in
> > > > > >>>>>> there though. I agree adding the Core class is a good idea,
> > > > > >>>>>> assuming it will get used by all machines, and CPUState then
> > > > > >>>>>> gets changed to a Thread class. The question then, though,
> > > > > >>>>>> is do we also create a Socket class that contains nr_cores?    
> > > > > >>>>>
> > > > > >>>>> That was roughly our intention with the way the cross
> > > > > >>>>> platform hotplug stuff is evolving.  But the intention was
> > > > > >>>>> that the Socket objects would only need to be constructed for
> > > > > >>>>> machine types where it makes sense.  So for example on the
> > > > > >>>>> paravirt pseries platform, we'll only have Core objects,
> > > > > >>>>> because the socket distinction isn't really meaningful.
> > > > > >>>>>     
> > > > > >>>>>> And how will a Thread method get that information when it
> > > > > >>>>>> needs to emulate, e.g. CPUID, that requires it? It's a bit
> > > > > >>>>>> messy, so I'm open to all suggestions on it.    
> > > > > >>>>>
> > > > > >>>>> So, if the Thread needs this information, I'm not opposed to
> > > > > >>>>> it having it internally (presumably populated earlier from
> > > > > >>>>> the Core object). But I am opposed to it being a locked in
> > > > > >>>>> part of the interface by having it as an exposed property.    
> > > > > >>>>
> > > > > >>>> I agree we don't want to make this part of the external
> > > > > >>>> interface. In this case, if we don't add the properties, how
> > > > > >>>> exactly is the Machine or Core code supposed to pass that
> > > > > >>>> information to the Thread object?
> > > > > >>>>
> > > > > >>>> Maybe the intermediate steps could be:
> > > > > >>>>
> > > > > >>>> * Make the Thread code that uses CPUState::nr_{cores,threads}
> > > > > >>>> and smp_{cores,threads} get that info from MachineState
> > > > > >>>> instead.    
> > > > > >>>
> > > > > >>> I have some patches already headed down this road.
> > > > > >>>  
> > > > > >>>> * On the architectures where we already have a reasonable
> > > > > >>>>   Socket/Core/Thread hierarchy, let the Thread code simply ask
> > > > > >>>>   for that information from its parent.    
> > > > > >>>
> > > > > >>> I guess that's just spapr so far, or at least spapr is the
> > > > > >>> closest. Indeed this appears to be the cleanest approach, so
> > > > > >>> architectures adding support for cpu topology should likely
> > > > > >>> strive to implement it this way.  
> > > > > >> If I recall correctly, the only thing about accessing parent is
> > > > > >> that in QOM design accessing parent from child wasn't accepted
> > > > > >> well, i.e. child shouldn't be aware nor access parent object.  
> > > > > > 
> > > > > > Can anybody explain why?
> > > > > > 
> > > > > > In this case, what's the best way for a parent to pass
> > > > > > information to its children without adding new externally-visible
> > > > > > properties that the user is never supposed to set directly?
> > > > > > 
> > > > > > Should Thread objects have an additional link to the parent Core
> > > > > > object, just to be able to get the information it needs?  
> > > > > 
> > > > > I am not fully aware either and believe I ignored it in my x86
> > > > > socket patchset, part of which it was RFC.
> > > > > 
> > > > > The key thing to consider is that this breaks user instantiation of
> > > > > a device, so it needs to be disabled.  
> > > > 
> > > > Good point, and this is hard to solve without changing the way
> > > > device_add works. Setting extra properties, on the other hand,
> > > > can be done easily by the hotplug handler if necessary (like we
> > > > do with apic-id in PC).
> > > > 
> > > > Also, if the properties are not supposed to be set directly by
> > > > the user, then the hotplug handler could refuse to hotplug the
> > > > device if the user tried to fiddle with them. Then the "external
> > > > interface" problem is solved.
> > > > 
> > > > Now, depending on how much information is needed, "extra
> > > > properties" may be duplicating data that is already available in
> > > > other objects (like nr-cores/nr-threads), or just a link property
> > > > (e.g. a link to the Core object in the case of spapr). If we
> > > > still don't have the right object topology implemented, then we
> > > > may need to use individual properties like "nr-cores" and
> > > > "nr-threads" (preferably as a temporary solution?).
> > > > 
> > > > In other words, maybe "nr-cores" and "nr-threads" properties will
> > > > be useful in x86, but only if we reject device creation in case
> > > > the user tries to set them manually, and if we do _not_ expose
> > > > them on TYPE_CPU.  
> > > Should be add a QOM API that could mark property as an internal
> > > that would be beneficial in generic as we won't have to be scared
> > > exposing internal stuff to users and be able to hide target specifics
> > > behind properties?
> > > 
> > > it should be simple enough to do.  
> > 
> > If it's internal, do we have any reason to register a (writeable)
> > property in the first place? Why not use a plain old
> > "obj->field = value" C statement? Or, if a simple assignment
> > isn't enough, why not a simple obj_set_field(value) C function?
> So that arch neutral code won't have to pull obj type definition

I don't get it. If arch neutral code uses it, it should be
available in an arch-neutral header.

> and we would be able to reuse all machinery that uses properties
> instead of inventing yet another API or ad-hoc function calls.

Why is adding a new C function or setting a struct field worse
than adding a new property name? I actually prefer the former,
because it makes code review easier and allows the compiler to
detect more mistakes.

-- 
Eduardo

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

* Re: [Qemu-devel] QOM: best way for parents to pass information to children? (was Re: [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties)
  2016-07-19 11:59                               ` Eduardo Habkost
@ 2016-07-19 12:21                                 ` Paolo Bonzini
  2016-07-19 13:29                                   ` Igor Mammedov
  0 siblings, 1 reply; 74+ messages in thread
From: Paolo Bonzini @ 2016-07-19 12:21 UTC (permalink / raw)
  To: Eduardo Habkost, Igor Mammedov
  Cc: peter.maydell, Andrew Jones, qemu-devel, agraf, qemu-arm,
	qemu-ppc, Bharata B Rao, Thomas Huth, dgibson,
	Andreas Färber, David Gibson



On 19/07/2016 13:59, Eduardo Habkost wrote:
>>> > > If it's internal, do we have any reason to register a (writeable)
>>> > > property in the first place? Why not use a plain old
>>> > > "obj->field = value" C statement? Or, if a simple assignment
>>> > > isn't enough, why not a simple obj_set_field(value) C function?
>> > So that arch neutral code won't have to pull obj type definition
> 
> I don't get it. If arch neutral code uses it, it should be
> available in an arch-neutral header.

I agree.  If arch-neutral code uses it, the method should be in CPUClass.

Paolo

>> > and we would be able to reuse all machinery that uses properties
>> > instead of inventing yet another API or ad-hoc function calls.
> Why is adding a new C function or setting a struct field worse
> than adding a new property name? I actually prefer the former,
> because it makes code review easier and allows the compiler to
> detect more mistakes.

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

* Re: [Qemu-devel] QOM: best way for parents to pass information to children? (was Re: [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties)
  2016-07-19 12:21                                 ` Paolo Bonzini
@ 2016-07-19 13:29                                   ` Igor Mammedov
  2016-07-19 13:39                                     ` Paolo Bonzini
  0 siblings, 1 reply; 74+ messages in thread
From: Igor Mammedov @ 2016-07-19 13:29 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Eduardo Habkost, peter.maydell, Andrew Jones, qemu-devel, agraf,
	qemu-arm, qemu-ppc, Bharata B Rao, Thomas Huth, dgibson,
	Andreas Färber, David Gibson

On Tue, 19 Jul 2016 14:21:05 +0200
Paolo Bonzini <pbonzini@redhat.com> wrote:

> On 19/07/2016 13:59, Eduardo Habkost wrote:
> >>> > > If it's internal, do we have any reason to register a (writeable)
> >>> > > property in the first place? Why not use a plain old
> >>> > > "obj->field = value" C statement? Or, if a simple assignment
> >>> > > isn't enough, why not a simple obj_set_field(value) C function?  
> >> > So that arch neutral code won't have to pull obj type definition  
> > 
> > I don't get it. If arch neutral code uses it, it should be
> > available in an arch-neutral header.  
> 
> I agree.  If arch-neutral code uses it, the method should be in CPUClass.
it looks a bit like deQOMification, but if it's preferred
we can do following for -smp.

1. Add machine::{nr_cores,nr_threads,nr_sockets} fields
2. Add to concrete cpus classes that use above data (as globals currently)
     a duplicate fields ex: X86CPU:{nr_cores,nr_threads}
3: Have X86CPU:{nr_cores,nr_threads} fields set buy PCMachine::pre_plug{} handler

That way we'd have a bit of data duplication in X86CPU:{nr_cores,nr_threads}
but still maintain role separation where CPUs won't have to to poke into
its parent containers (machine). The sort of what we are doing currently with apic-id.


> 
> Paolo
> 
> >> > and we would be able to reuse all machinery that uses properties
> >> > instead of inventing yet another API or ad-hoc function calls.  
> > Why is adding a new C function or setting a struct field worse
> > than adding a new property name? I actually prefer the former,
> > because it makes code review easier and allows the compiler to
> > detect more mistakes.  

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

* Re: [Qemu-devel] QOM: best way for parents to pass information to children? (was Re: [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties)
  2016-07-19 13:29                                   ` Igor Mammedov
@ 2016-07-19 13:39                                     ` Paolo Bonzini
  0 siblings, 0 replies; 74+ messages in thread
From: Paolo Bonzini @ 2016-07-19 13:39 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Eduardo Habkost, peter.maydell, Andrew Jones, qemu-devel, agraf,
	qemu-arm, qemu-ppc, Bharata B Rao, Thomas Huth, dgibson,
	Andreas Färber, David Gibson



On 19/07/2016 15:29, Igor Mammedov wrote:
> On Tue, 19 Jul 2016 14:21:05 +0200
> Paolo Bonzini <pbonzini@redhat.com> wrote:
> 
>> On 19/07/2016 13:59, Eduardo Habkost wrote:
>>>>>>> If it's internal, do we have any reason to register a (writeable)
>>>>>>> property in the first place? Why not use a plain old
>>>>>>> "obj->field = value" C statement? Or, if a simple assignment
>>>>>>> isn't enough, why not a simple obj_set_field(value) C function?  
>>>>> So that arch neutral code won't have to pull obj type definition  
>>>
>>> I don't get it. If arch neutral code uses it, it should be
>>> available in an arch-neutral header.  
>>
>> I agree.  If arch-neutral code uses it, the method should be in CPUClass.
>
> it looks a bit like deQOMification, but if it's preferred
> we can do following for -smp.

Properties are primarily an interface for users.  Sometimes we use them
internally when they are anyway inaccessible to users, but if you want
to hide things from users there's already a suitable mechanism which is
class and interface methods.

Paolo

> 1. Add machine::{nr_cores,nr_threads,nr_sockets} fields
> 2. Add to concrete cpus classes that use above data (as globals currently)
>      a duplicate fields ex: X86CPU:{nr_cores,nr_threads}
> 3: Have X86CPU:{nr_cores,nr_threads} fields set buy PCMachine::pre_plug{} handler
> 
> That way we'd have a bit of data duplication in X86CPU:{nr_cores,nr_threads}
> but still maintain role separation where CPUs won't have to to poke into
> its parent containers (machine). The sort of what we are doing currently with apic-id.
> 
> 
>>
>> Paolo
>>
>>>>> and we would be able to reuse all machinery that uses properties
>>>>> instead of inventing yet another API or ad-hoc function calls.  
>>> Why is adding a new C function or setting a struct field worse
>>> than adding a new property name? I actually prefer the former,
>>> because it makes code review easier and allows the compiler to
>>> detect more mistakes.  
> 

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

end of thread, other threads:[~2016-07-19 13:40 UTC | newest]

Thread overview: 74+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-10 17:40 [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Andrew Jones
2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 01/16] vl: smp_parse: cleanups Andrew Jones
2016-06-14  1:15   ` David Gibson
2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 02/16] vl: smp: add checks for maxcpus based topologies Andrew Jones
2016-06-14  1:28   ` David Gibson
2016-06-14  6:43     ` Andrew Jones
2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 03/16] hw/smbios/smbios: fix number of sockets calculation Andrew Jones
2016-07-11 14:23   ` Igor Mammedov
2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 04/16] hw/core/machine: Introduce pre_init Andrew Jones
2016-06-14  1:30   ` David Gibson
2016-06-14  5:58     ` Andrew Jones
2016-07-14 20:10       ` Eduardo Habkost
2016-07-15  6:26         ` Andrew Jones
2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 05/16] hw/core/machine: add smp properites Andrew Jones
2016-06-14  2:00   ` David Gibson
2016-06-14  6:08     ` Andrew Jones
2016-06-15  0:37       ` David Gibson
2016-06-15  7:11         ` Andrew Jones
2016-07-14 20:18           ` Eduardo Habkost
2016-07-15  6:29             ` Andrew Jones
2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 06/16] vl: move smp parsing to machine pre_init Andrew Jones
2016-06-13 17:04   ` Paolo Bonzini
2016-06-13 20:35     ` Andrew Jones
2016-06-14  8:17       ` Paolo Bonzini
2016-06-14 11:39         ` Andrew Jones
2016-06-14 11:53           ` Paolo Bonzini
2016-06-14 14:03             ` Andrew Jones
2016-06-14 14:05               ` Paolo Bonzini
2016-06-15  0:51               ` David Gibson
2016-06-15  7:19                 ` Andrew Jones
2016-06-15  0:43         ` David Gibson
2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties Andrew Jones
2016-06-11  6:54   ` Thomas Huth
2016-06-12 13:48     ` Andrew Jones
2016-06-14  2:12       ` David Gibson
2016-06-14  6:19         ` Andrew Jones
2016-06-15  0:56           ` David Gibson
2016-07-14 20:07             ` Eduardo Habkost
2016-07-15  6:35               ` Andrew Jones
2016-07-15  9:11                 ` Igor Mammedov
2016-07-15 16:10                   ` [Qemu-devel] QOM: best way for parents to pass information to children? (was Re: [PATCH RFC 07/16] qom/cpu: make nr-cores, nr-threads real properties) Eduardo Habkost
2016-07-15 16:30                     ` Andreas Färber
2016-07-15 17:43                       ` Eduardo Habkost
2016-07-15 18:38                         ` Igor Mammedov
2016-07-15 21:33                           ` Eduardo Habkost
2016-07-16 15:30                             ` Andrew Jones
2016-07-19 11:54                               ` Eduardo Habkost
2016-07-18  7:23                             ` Igor Mammedov
2016-07-19 11:59                               ` Eduardo Habkost
2016-07-19 12:21                                 ` Paolo Bonzini
2016-07-19 13:29                                   ` Igor Mammedov
2016-07-19 13:39                                     ` Paolo Bonzini
2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 08/16] hw/core/machine: set cpu global nr_cores, nr_threads in pre_init Andrew Jones
2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 09/16] hw/i386/pc: don't use smp_cores, smp_threads Andrew Jones
2016-07-14 20:33   ` Eduardo Habkost
2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 10/16] hw/ppc/spapr: " Andrew Jones
2016-06-14  3:03   ` David Gibson
2016-06-14  6:23     ` Andrew Jones
2016-06-15  0:59       ` David Gibson
2016-06-15  7:34         ` Andrew Jones
2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 11/16] target-ppc: don't use smp_threads Andrew Jones
2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 12/16] hw/arm/virt: rename *.smp_cpus to *.cpus Andrew Jones
2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 13/16] hw/arm/virt: don't use smp_cpus, max_cpus Andrew Jones
2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 14/16] hw/arm/virt: stash cpu topo info in VirtGuestInfo Andrew Jones
2016-07-14 20:43   ` Eduardo Habkost
2016-07-15  6:40     ` Andrew Jones
2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 15/16] smbios: don't use smp_cores, smp_threads Andrew Jones
2016-07-14 20:51   ` Eduardo Habkost
2016-07-15  6:45     ` Andrew Jones
2016-06-10 17:40 ` [Qemu-devel] [PATCH RFC 16/16] sysemu/cpus: bye, bye " Andrew Jones
2016-06-11  6:42 ` [Qemu-devel] [PATCH RFC 00/16] Rework SMP parameters Thomas Huth
2016-06-12 13:58   ` Andrew Jones
2016-06-12 14:03 ` Andrew Jones
2016-07-14  9:16 ` Andrew Jones

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.