* [Qemu-devel] [PATCH 00/11] pc: allow to use -device/device_add for CPUs
@ 2016-06-23 14:54 Igor Mammedov
2016-06-23 14:54 ` [Qemu-devel] [PATCH 01/11] target-i386: cpu: use uint32_t for X86CPU.apic_id Igor Mammedov
` (10 more replies)
0 siblings, 11 replies; 27+ messages in thread
From: Igor Mammedov @ 2016-06-23 14:54 UTC (permalink / raw)
To: qemu-devel
Cc: pbonzini, rth, ehabkost, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
Series enabling usage of -device/device_add for adding CPUs
as devices. Using -device/device_add in combination with
query-hotpluggable-cpus QMP command allows to hotplug CPUs
at any not used possition and then safely migrate QEMU
instance by specifying hotadded CPUs on target with help
of -device CLI option like with any other device.
Having been able to hotadd arbitrary CPUs and migrate also
opens poosibility to hot-remove arbitrary CPUs, which will
be a separate series on top of this one.
Series depends on following not yet commited patchsets:
1: [PATCH v2 00/10] ACPI CPU hotplug refactoring to support unplug and more than 255 CPUs
https://lists.gnu.org/archive/html/qemu-devel/2016-06/msg04671.html
2: [PATCH v2 0/6] cpus: make "-cpu cpux, features" global properties
https://lists.gnu.org/archive/html/qemu-devel/2016-06/msg02579.html
3: [PATCH v2 00/10] globals: Clean up validation and error checking
https://lists.gnu.org/archive/html/qemu-devel/2016-06/msg05662.html
git tree for testing:
https://github.com/imammedo/qemu.git dev_add_cpu_v1
for viewing:
https://github.com/imammedo/qemu/commits/dev_add_cpu_v1
Igor Mammedov (11):
target-i386: cpu: use uint32_t for X86CPU.apic_id
pc: add x86_topo_ids_from_apicid()
pc: extract CPU lookup into a separate function
pc: cpu: consolidate apic-id validity checks in pc_cpu_pre_plug()
target-i386: cpu: replace custom apic-id setter/getter with static
property
target-i386: add socket/core/thread properties to X86CPU
pc: set APIC ID based on socket/core/thread ids if it's not been set
yet
pc: implement query-hotpluggable-cpus callback
pc: register created initial and hotpluged CPUs in one place
pc_cpu_plug()
pc: delay setting number of boot CPUs to machine_done time
pc: cpu: allow device_add to be used with x86 cpu
hw/i386/pc.c | 170 +++++++++++++++++++++++++++++++++++----------
include/hw/i386/topology.h | 15 ++++
qmp-commands.hx | 15 ++++
target-i386/cpu.c | 64 +++--------------
target-i386/cpu.h | 8 ++-
5 files changed, 180 insertions(+), 92 deletions(-)
--
1.8.3.1
^ permalink raw reply [flat|nested] 27+ messages in thread
* [Qemu-devel] [PATCH 01/11] target-i386: cpu: use uint32_t for X86CPU.apic_id
2016-06-23 14:54 [Qemu-devel] [PATCH 00/11] pc: allow to use -device/device_add for CPUs Igor Mammedov
@ 2016-06-23 14:54 ` Igor Mammedov
2016-06-23 14:54 ` [Qemu-devel] [PATCH 02/11] pc: add x86_topo_ids_from_apicid() Igor Mammedov
` (9 subsequent siblings)
10 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2016-06-23 14:54 UTC (permalink / raw)
To: qemu-devel
Cc: pbonzini, rth, ehabkost, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
redo
9886e834 target-i386: Require APIC ID to be explicitly set before CPU realize
in another way that doesn't use int64_t to detect
if apic-id property was set.
Use the fact that 0xFFFFFFFF is the broadcast
value that a CPU can't have and set default
uint32_t apic_id to it instead of using int64_t.
Later uint32_t apic_id will be used to drop custom
property setter/getter in favor of static property.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
target-i386/cpu.c | 4 ++--
target-i386/cpu.h | 4 +++-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 5c69c43..e7319e3 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2883,7 +2883,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
goto out;
}
- if (cpu->apic_id < 0) {
+ if (cpu->apic_id == UNASSIGNED_APIC_ID) {
error_setg(errp, "apic-id property was not initialized properly");
return;
}
@@ -3154,7 +3154,7 @@ static void x86_cpu_initfn(Object *obj)
#ifndef CONFIG_USER_ONLY
/* Any code creating new X86CPU objects have to set apic-id explicitly */
- cpu->apic_id = -1;
+ cpu->apic_id = UNASSIGNED_APIC_ID;
#endif
for (w = 0; w < FEATURE_WORDS; w++) {
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index f4f65ce..8b09cfa 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -835,6 +835,8 @@ typedef struct {
#define NB_OPMASK_REGS 8
+#define UNASSIGNED_APIC_ID UINT32_MAX
+
typedef union X86LegacyXSaveArea {
struct {
uint16_t fcw;
@@ -1163,7 +1165,7 @@ struct X86CPU {
bool expose_kvm;
bool migratable;
bool host_features;
- int64_t apic_id;
+ uint32_t apic_id;
/* if true the CPUID code directly forward host cache leaves to the guest */
bool cache_info_passthrough;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PATCH 02/11] pc: add x86_topo_ids_from_apicid()
2016-06-23 14:54 [Qemu-devel] [PATCH 00/11] pc: allow to use -device/device_add for CPUs Igor Mammedov
2016-06-23 14:54 ` [Qemu-devel] [PATCH 01/11] target-i386: cpu: use uint32_t for X86CPU.apic_id Igor Mammedov
@ 2016-06-23 14:54 ` Igor Mammedov
2016-06-23 14:54 ` [Qemu-devel] [PATCH 03/11] pc: extract CPU lookup into a separate function Igor Mammedov
` (8 subsequent siblings)
10 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2016-06-23 14:54 UTC (permalink / raw)
To: qemu-devel
Cc: pbonzini, rth, ehabkost, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
it's reverse of apicid_from_topo_ids() and will be used in follow up
patches to fill in data structures for query-hotpluggable-cpus and
for user friendly error reporting
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
include/hw/i386/topology.h | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h
index fc95572..1ebaee0 100644
--- a/include/hw/i386/topology.h
+++ b/include/hw/i386/topology.h
@@ -117,6 +117,21 @@ static inline void x86_topo_ids_from_idx(unsigned nr_cores,
topo->pkg_id = core_index / nr_cores;
}
+/* Calculate thread/core/package IDs for a specific topology,
+ * based on APIC ID
+ */
+static inline void x86_topo_ids_from_apicid(apic_id_t apicid,
+ unsigned nr_cores,
+ unsigned nr_threads,
+ X86CPUTopoInfo *topo)
+{
+ topo->smt_id = apicid &
+ ~(0xFFFFFFFFUL << apicid_smt_width(nr_cores, nr_threads));
+ topo->core_id = (apicid >> apicid_core_offset(nr_cores, nr_threads)) &
+ ~(0xFFFFFFFFUL << apicid_core_width(nr_cores, nr_threads));
+ topo->pkg_id = apicid >> apicid_pkg_offset(nr_cores, nr_threads);
+}
+
/* Make APIC ID for the CPU 'cpu_index'
*
* 'cpu_index' is a sequential, contiguous ID for the CPU.
--
1.8.3.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PATCH 03/11] pc: extract CPU lookup into a separate function
2016-06-23 14:54 [Qemu-devel] [PATCH 00/11] pc: allow to use -device/device_add for CPUs Igor Mammedov
2016-06-23 14:54 ` [Qemu-devel] [PATCH 01/11] target-i386: cpu: use uint32_t for X86CPU.apic_id Igor Mammedov
2016-06-23 14:54 ` [Qemu-devel] [PATCH 02/11] pc: add x86_topo_ids_from_apicid() Igor Mammedov
@ 2016-06-23 14:54 ` Igor Mammedov
2016-06-23 17:32 ` Eduardo Habkost
2016-06-23 14:54 ` [Qemu-devel] [PATCH 04/11] pc: cpu: consolidate apic-id validity checks in pc_cpu_pre_plug() Igor Mammedov
` (7 subsequent siblings)
10 siblings, 1 reply; 27+ messages in thread
From: Igor Mammedov @ 2016-06-23 14:54 UTC (permalink / raw)
To: qemu-devel
Cc: pbonzini, rth, ehabkost, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
it will be reused in the next patch at pre_plug time
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
hw/i386/pc.c | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 07a3b82..ec9b14b 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1675,11 +1675,25 @@ static int pc_apic_cmp(const void *a, const void *b)
return apic_a->arch_id - apic_b->arch_id;
}
+static CPUArchId *pc_find_cpu(PCMachineState *pcms, CPUState *cpu, int *idx)
+{
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+ CPUArchId apic_id, *found_cpu;
+
+ apic_id.arch_id = cc->get_arch_id(CPU(cpu));
+ found_cpu = bsearch(&apic_id, pcms->possible_cpus->cpus,
+ pcms->possible_cpus->len, sizeof(*pcms->possible_cpus->cpus),
+ pc_apic_cmp);
+ if (found_cpu && idx) {
+ *idx = found_cpu - pcms->possible_cpus->cpus;
+ }
+ return found_cpu;
+}
+
static void pc_cpu_plug(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
- CPUClass *cc = CPU_GET_CLASS(dev);
- CPUArchId apic_id, *found_cpu;
+ CPUArchId *found_cpu;
HotplugHandlerClass *hhc;
Error *local_err = NULL;
PCMachineState *pcms = PC_MACHINE(hotplug_dev);
@@ -1703,11 +1717,7 @@ static void pc_cpu_plug(HotplugHandler *hotplug_dev,
/* increment the number of CPUs */
rtc_set_memory(pcms->rtc, 0x5f, rtc_get_memory(pcms->rtc, 0x5f) + 1);
- apic_id.arch_id = cc->get_arch_id(CPU(dev));
- found_cpu = bsearch(&apic_id, pcms->possible_cpus->cpus,
- pcms->possible_cpus->len, sizeof(*pcms->possible_cpus->cpus),
- pc_apic_cmp);
- assert(found_cpu);
+ found_cpu = pc_find_cpu(pcms, CPU(dev), NULL);
found_cpu->cpu = CPU(dev);
out:
error_propagate(errp, local_err);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PATCH 04/11] pc: cpu: consolidate apic-id validity checks in pc_cpu_pre_plug()
2016-06-23 14:54 [Qemu-devel] [PATCH 00/11] pc: allow to use -device/device_add for CPUs Igor Mammedov
` (2 preceding siblings ...)
2016-06-23 14:54 ` [Qemu-devel] [PATCH 03/11] pc: extract CPU lookup into a separate function Igor Mammedov
@ 2016-06-23 14:54 ` Igor Mammedov
2016-06-23 14:54 ` [Qemu-devel] [PATCH 05/11] target-i386: cpu: replace custom apic-id setter/getter with static property Igor Mammedov
` (6 subsequent siblings)
10 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2016-06-23 14:54 UTC (permalink / raw)
To: qemu-devel
Cc: pbonzini, rth, ehabkost, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
Machine code knows about all possible APIC IDs so use that
instead of hack which does O(n^2) complexity duplicate
checks, interating over global CPUs list.
As result duplicate check is done only once with O(log n) complexity.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
hw/i386/pc.c | 44 ++++++++++++++++++++++++++++++++------------
target-i386/cpu.c | 13 -------------
2 files changed, 32 insertions(+), 25 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index ec9b14b..6ba6343 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1071,18 +1071,6 @@ void pc_hot_add_cpu(const int64_t id, Error **errp)
return;
}
- if (cpu_exists(apic_id)) {
- error_setg(errp, "Unable to add CPU: %" PRIi64
- ", it already exists", id);
- return;
- }
-
- if (id >= max_cpus) {
- error_setg(errp, "Unable to add CPU: %" PRIi64
- ", max allowed: %d", id, max_cpus - 1);
- return;
- }
-
if (apic_id >= ACPI_CPU_HOTPLUG_ID_LIMIT) {
error_setg(errp, "Unable to add CPU: %" PRIi64
", resulting APIC ID (%" PRIi64 ") is too large",
@@ -1766,6 +1754,37 @@ static void pc_cpu_unplug_cb(HotplugHandler *hotplug_dev,
error_propagate(errp, local_err);
}
+static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ int idx;
+ X86CPU *cpu = X86_CPU(dev);
+ PCMachineState *pcms = PC_MACHINE(hotplug_dev);
+ CPUArchId *cpu_slot = pc_find_cpu(pcms, CPU(dev), &idx);
+
+ if (!cpu_slot) {
+ error_setg(errp, "Invalid CPU index with APIC ID (%" PRIu32
+ "), valid range 0:%d", cpu->apic_id,
+ pcms->possible_cpus->len - 1);
+ return;
+ }
+
+ if (cpu_slot->cpu) {
+ error_setg(errp, "CPU[%ld] with APIC ID %" PRIu32 " exists",
+ cpu_slot - pcms->possible_cpus->cpus,
+ cpu->apic_id);
+ return;
+ }
+}
+
+static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+ pc_cpu_pre_plug(hotplug_dev, dev, errp);
+ }
+}
+
static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
@@ -2063,6 +2082,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
mc->hot_add_cpu = pc_hot_add_cpu;
mc->max_cpus = 255;
mc->reset = pc_machine_reset;
+ hc->pre_plug = pc_machine_device_pre_plug_cb;
hc->plug = pc_machine_device_plug_cb;
hc->unplug_request = pc_machine_device_unplug_request_cb;
hc->unplug = pc_machine_device_unplug_cb;
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index e7319e3..9511474 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1838,8 +1838,6 @@ static void x86_cpuid_set_apic_id(Object *obj, Visitor *v, const char *name,
{
X86CPU *cpu = X86_CPU(obj);
DeviceState *dev = DEVICE(obj);
- const int64_t min = 0;
- const int64_t max = UINT32_MAX;
Error *error = NULL;
int64_t value;
@@ -1854,17 +1852,6 @@ static void x86_cpuid_set_apic_id(Object *obj, Visitor *v, const char *name,
error_propagate(errp, error);
return;
}
- if (value < min || value > max) {
- error_setg(errp, "Property %s.%s doesn't take value %" PRId64
- " (minimum: %" PRId64 ", maximum: %" PRId64 ")" ,
- object_get_typename(obj), name, value, min, max);
- return;
- }
-
- if ((value != cpu->apic_id) && cpu_exists(value)) {
- error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
- return;
- }
cpu->apic_id = value;
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PATCH 05/11] target-i386: cpu: replace custom apic-id setter/getter with static property
2016-06-23 14:54 [Qemu-devel] [PATCH 00/11] pc: allow to use -device/device_add for CPUs Igor Mammedov
` (3 preceding siblings ...)
2016-06-23 14:54 ` [Qemu-devel] [PATCH 04/11] pc: cpu: consolidate apic-id validity checks in pc_cpu_pre_plug() Igor Mammedov
@ 2016-06-23 14:54 ` Igor Mammedov
2016-06-27 17:55 ` Eduardo Habkost
2016-06-23 14:54 ` [Qemu-devel] [PATCH 06/11] target-i386: add socket/core/thread properties to X86CPU Igor Mammedov
` (5 subsequent siblings)
10 siblings, 1 reply; 27+ messages in thread
From: Igor Mammedov @ 2016-06-23 14:54 UTC (permalink / raw)
To: qemu-devel
Cc: pbonzini, rth, ehabkost, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
custom apic-id setter/getter doesn't do any property specific
checks anymorer, so clean it up and use more compact static
property DEFINE_PROP_UINT32 instead.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
target-i386/cpu.c | 45 ++++++---------------------------------------
1 file changed, 6 insertions(+), 39 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 9511474..9294b3d 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1824,37 +1824,6 @@ static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, const char *name,
cpu->env.tsc_khz = cpu->env.user_tsc_khz = value / 1000;
}
-static void x86_cpuid_get_apic_id(Object *obj, Visitor *v, const char *name,
- void *opaque, Error **errp)
-{
- X86CPU *cpu = X86_CPU(obj);
- int64_t value = cpu->apic_id;
-
- visit_type_int(v, name, &value, errp);
-}
-
-static void x86_cpuid_set_apic_id(Object *obj, Visitor *v, const char *name,
- void *opaque, Error **errp)
-{
- X86CPU *cpu = X86_CPU(obj);
- DeviceState *dev = DEVICE(obj);
- Error *error = NULL;
- int64_t value;
-
- if (dev->realized) {
- error_setg(errp, "Attempt to set property '%s' on '%s' after "
- "it was realized", name, object_get_typename(obj));
- return;
- }
-
- visit_type_int(v, name, &value, &error);
- if (error) {
- error_propagate(errp, error);
- return;
- }
- cpu->apic_id = value;
-}
-
/* Generic getter for "feature-words" and "filtered-features" properties */
static void x86_cpu_get_feature_words(Object *obj, Visitor *v,
const char *name, void *opaque,
@@ -3127,9 +3096,6 @@ static void x86_cpu_initfn(Object *obj)
object_property_add(obj, "tsc-frequency", "int",
x86_cpuid_get_tsc_freq,
x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
- object_property_add(obj, "apic-id", "int",
- x86_cpuid_get_apic_id,
- x86_cpuid_set_apic_id, NULL, NULL, NULL);
object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
x86_cpu_get_feature_words,
NULL, NULL, (void *)env->features, NULL);
@@ -3139,11 +3105,6 @@ static void x86_cpu_initfn(Object *obj)
cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
-#ifndef CONFIG_USER_ONLY
- /* Any code creating new X86CPU objects have to set apic-id explicitly */
- cpu->apic_id = UNASSIGNED_APIC_ID;
-#endif
-
for (w = 0; w < FEATURE_WORDS; w++) {
int bitnr;
@@ -3200,6 +3161,12 @@ static bool x86_cpu_has_work(CPUState *cs)
}
static Property x86_cpu_properties[] = {
+#ifdef CONFIG_USER_ONLY
+ /* apic_id = 0 by default for *-user, see commit 9886e834 */
+ DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, 0),
+#else
+ DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, UNASSIGNED_APIC_ID),
+#endif
DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false),
{ .name = "hv-spinlocks", .info = &qdev_prop_spinlocks },
DEFINE_PROP_BOOL("hv-relaxed", X86CPU, hyperv_relaxed_timing, false),
--
1.8.3.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PATCH 06/11] target-i386: add socket/core/thread properties to X86CPU
2016-06-23 14:54 [Qemu-devel] [PATCH 00/11] pc: allow to use -device/device_add for CPUs Igor Mammedov
` (4 preceding siblings ...)
2016-06-23 14:54 ` [Qemu-devel] [PATCH 05/11] target-i386: cpu: replace custom apic-id setter/getter with static property Igor Mammedov
@ 2016-06-23 14:54 ` Igor Mammedov
2016-06-23 17:44 ` Eduardo Habkost
2016-06-23 14:54 ` [Qemu-devel] [PATCH 07/11] pc: set APIC ID based on socket/core/thread ids if it's not been set yet Igor Mammedov
` (4 subsequent siblings)
10 siblings, 1 reply; 27+ messages in thread
From: Igor Mammedov @ 2016-06-23 14:54 UTC (permalink / raw)
To: qemu-devel
Cc: pbonzini, rth, ehabkost, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
these properties will be used by as address where to plug
CPU with help -device/device_add commands.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
hw/i386/pc.c | 12 ++++++++++++
target-i386/cpu.c | 3 +++
target-i386/cpu.h | 4 ++++
3 files changed, 19 insertions(+)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 6ba6343..87352ae 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1775,6 +1775,18 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
cpu->apic_id);
return;
}
+
+ /* set 'address' properties socket/core/thread for initial and cpu-add
+ * added CPUs so that query_hotpluggable_cpus would show correct values
+ */
+ if (cpu->thread == -1 || cpu->core == -1 || cpu->socket == -1) {
+ X86CPUTopoInfo topo;
+
+ x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads, &topo);
+ cpu->thread = topo.smt_id;
+ cpu->core = topo.core_id;
+ cpu->socket = topo.pkg_id;
+ }
}
static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 9294b3d..8c651f2 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -3186,6 +3186,9 @@ static Property x86_cpu_properties[] = {
DEFINE_PROP_UINT32("xlevel2", X86CPU, env.cpuid_xlevel2, 0),
DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor_id),
DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true),
+ DEFINE_PROP_INT32("thread", X86CPU, thread, -1),
+ DEFINE_PROP_INT32("core", X86CPU, core, -1),
+ DEFINE_PROP_INT32("socket", X86CPU, socket, -1),
DEFINE_PROP_END_OF_LIST()
};
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 8b09cfa..a04d334 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1190,6 +1190,10 @@ struct X86CPU {
Notifier machine_done;
struct kvm_msrs *kvm_msr_buf;
+
+ int32_t socket;
+ int32_t core;
+ int32_t thread;
};
static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
--
1.8.3.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PATCH 07/11] pc: set APIC ID based on socket/core/thread ids if it's not been set yet
2016-06-23 14:54 [Qemu-devel] [PATCH 00/11] pc: allow to use -device/device_add for CPUs Igor Mammedov
` (5 preceding siblings ...)
2016-06-23 14:54 ` [Qemu-devel] [PATCH 06/11] target-i386: add socket/core/thread properties to X86CPU Igor Mammedov
@ 2016-06-23 14:54 ` Igor Mammedov
2016-06-23 17:19 ` Eduardo Habkost
2016-06-23 14:54 ` [Qemu-devel] [PATCH 08/11] pc: implement query-hotpluggable-cpus callback Igor Mammedov
` (3 subsequent siblings)
10 siblings, 1 reply; 27+ messages in thread
From: Igor Mammedov @ 2016-06-23 14:54 UTC (permalink / raw)
To: qemu-devel
Cc: pbonzini, rth, ehabkost, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
CPU added with device_add help won't have APIC ID set,
so set it according to socket/core/thread ids provided
with device_add command.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
hw/i386/pc.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 87352ae..63e9bb6 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1758,13 +1758,23 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
int idx;
+ CPUArchId *cpu_slot;
+ X86CPUTopoInfo topo;
X86CPU *cpu = X86_CPU(dev);
PCMachineState *pcms = PC_MACHINE(hotplug_dev);
- CPUArchId *cpu_slot = pc_find_cpu(pcms, CPU(dev), &idx);
+ if (cpu->apic_id == 0xFFFFFFFF) {
+ /* APIC ID not set, set it based on socket/core/thread properties */
+ X86CPUTopoInfo topo = { cpu->socket, cpu->core, cpu->thread };
+ cpu->apic_id = apicid_from_topo_ids(smp_cores, smp_threads, &topo);
+ }
+
+ cpu_slot = pc_find_cpu(pcms, CPU(dev), &idx);
if (!cpu_slot) {
- error_setg(errp, "Invalid CPU index with APIC ID (%" PRIu32
- "), valid range 0:%d", cpu->apic_id,
+ x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads, &topo);
+ error_setg(errp, "Invalid CPU[socket: %d, core: %d, thread: %d] with"
+ " APIC ID (%" PRIu32 "), valid index range 0:%d",
+ topo.pkg_id, topo.core_id, topo.smt_id, cpu->apic_id,
pcms->possible_cpus->len - 1);
return;
}
@@ -1780,8 +1790,6 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
* added CPUs so that query_hotpluggable_cpus would show correct values
*/
if (cpu->thread == -1 || cpu->core == -1 || cpu->socket == -1) {
- X86CPUTopoInfo topo;
-
x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads, &topo);
cpu->thread = topo.smt_id;
cpu->core = topo.core_id;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PATCH 08/11] pc: implement query-hotpluggable-cpus callback
2016-06-23 14:54 [Qemu-devel] [PATCH 00/11] pc: allow to use -device/device_add for CPUs Igor Mammedov
` (6 preceding siblings ...)
2016-06-23 14:54 ` [Qemu-devel] [PATCH 07/11] pc: set APIC ID based on socket/core/thread ids if it's not been set yet Igor Mammedov
@ 2016-06-23 14:54 ` Igor Mammedov
2016-06-23 14:54 ` [Qemu-devel] [PATCH 09/11] pc: register created initial and hotpluged CPUs in one place pc_cpu_plug() Igor Mammedov
` (2 subsequent siblings)
10 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2016-06-23 14:54 UTC (permalink / raw)
To: qemu-devel
Cc: pbonzini, rth, ehabkost, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
it returns a list of present/possible to hotplug CPU
objects with a list of properties to use with
device_add.
in PC case returned list would looks like:
-> { "execute": "query-hotpluggable-cpus" }
<- {"return": [
{
"type": "qemu64-x86_64-cpu", "vcpus-count": 1,
"props": {"core": 0, "socket": 1, "thread": 0}
},
{
"qom-path": "/machine/unattached/device[0]",
"type": "qemu64-x86_64-cpu", "vcpus-count": 1,
"props": {"core": 0, "socket": 0, "thread": 0}
}
]}
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
hw/i386/pc.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
qmp-commands.hx | 15 +++++++++++++++
2 files changed, 60 insertions(+)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 63e9bb6..3bd52f6 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -2058,6 +2058,50 @@ static CPUArchIdList *pc_possible_cpu_arch_ids(MachineState *machine)
return list;
}
+static HotpluggableCPUList *pc_query_hotpluggable_cpus(MachineState *machine)
+{
+ int i;
+ CPUState *cpu;
+ HotpluggableCPUList *head = NULL;
+ PCMachineState *pcms = PC_MACHINE(machine);
+ const char *cpu_type;
+
+ cpu = pcms->possible_cpus->cpus[0].cpu;
+ assert(cpu); /* BSP is always present */
+ cpu_type = object_class_get_name(OBJECT_CLASS(CPU_GET_CLASS(cpu)));
+
+ for (i = 0; i < pcms->possible_cpus->len; i++) {
+ X86CPUTopoInfo topo;
+ HotpluggableCPUList *list_item = g_new0(typeof(*list_item), 1);
+ HotpluggableCPU *cpu_item = g_new0(typeof(*cpu_item), 1);
+ CpuInstanceProperties *cpu_props = g_new0(typeof(*cpu_props), 1);
+ const uint32_t apic_id = pcms->possible_cpus->cpus[i].arch_id;
+
+ x86_topo_ids_from_apicid(apic_id, smp_cores, smp_threads, &topo);
+
+ cpu_item->type = g_strdup(cpu_type);
+ cpu_item->vcpus_count = 1;
+ cpu_props->has_socket = true;
+ cpu_props->socket = topo.pkg_id;
+ cpu_props->has_core = true;
+ cpu_props->core = topo.core_id;
+ cpu_props->has_thread = true;
+ cpu_props->thread = topo.smt_id;
+ cpu_item->props = cpu_props;
+
+ cpu = pcms->possible_cpus->cpus[i].cpu;
+ if (cpu) {
+ cpu_item->has_qom_path = true;
+ cpu_item->qom_path = object_get_canonical_path(OBJECT(cpu));
+ }
+
+ list_item->value = cpu_item;
+ list_item->next = head;
+ head = list_item;
+ }
+ return head;
+}
+
static void x86_nmi(NMIState *n, int cpu_index, Error **errp)
{
/* cpu index isn't used */
@@ -2098,6 +2142,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
mc->get_hotplug_handler = pc_get_hotpug_handler;
mc->cpu_index_to_socket_id = pc_cpu_index_to_socket_id;
mc->possible_cpu_arch_ids = pc_possible_cpu_arch_ids;
+ mc->query_hotpluggable_cpus = pc_query_hotpluggable_cpus;
mc->default_boot_order = "cad";
mc->hot_add_cpu = pc_hot_add_cpu;
mc->max_cpus = 255;
diff --git a/qmp-commands.hx b/qmp-commands.hx
index b444c20..380e110 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -4983,3 +4983,18 @@ Example for pseries machine type started with
{ "props": { "core": 0 }, "type": "POWER8-spapr-cpu-core",
"vcpus-count": 1, "qom-path": "/machine/unattached/device[0]"}
]}'
+
+Example for pc machine type started with
+-smp 1,maxcpus=2:
+ -> { "execute": "query-hotpluggable-cpus" }
+ <- {"return": [
+ {
+ "type": "qemu64-x86_64-cpu", "vcpus-count": 1,
+ "props": {"core": 0, "socket": 1, "thread": 0}
+ },
+ {
+ "qom-path": "/machine/unattached/device[0]",
+ "type": "qemu64-x86_64-cpu", "vcpus-count": 1,
+ "props": {"core": 0, "socket": 0, "thread": 0}
+ }
+ ]}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PATCH 09/11] pc: register created initial and hotpluged CPUs in one place pc_cpu_plug()
2016-06-23 14:54 [Qemu-devel] [PATCH 00/11] pc: allow to use -device/device_add for CPUs Igor Mammedov
` (7 preceding siblings ...)
2016-06-23 14:54 ` [Qemu-devel] [PATCH 08/11] pc: implement query-hotpluggable-cpus callback Igor Mammedov
@ 2016-06-23 14:54 ` Igor Mammedov
2016-06-23 14:54 ` [Qemu-devel] [PATCH 10/11] pc: delay setting number of boot CPUs to machine_done time Igor Mammedov
2016-06-23 14:54 ` [Qemu-devel] [PATCH 11/11] pc: cpu: allow device_add to be used with x86 cpu Igor Mammedov
10 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2016-06-23 14:54 UTC (permalink / raw)
To: qemu-devel
Cc: pbonzini, rth, ehabkost, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
consolidate possible_cpus array management in pc_cpu_plug()
for smp_cpus, coldplugged with -device and hotplugged with
device_add.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
hw/i386/pc.c | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 3bd52f6..b6b9acc 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1145,7 +1145,6 @@ void pc_cpus_init(PCMachineState *pcms)
if (i < smp_cpus) {
cpu = pc_new_cpu(typename, x86_cpu_apic_id_from_index(i),
&error_fatal);
- pcms->possible_cpus->cpus[i].cpu = CPU(cpu);
object_unref(OBJECT(cpu));
}
}
@@ -1686,25 +1685,19 @@ static void pc_cpu_plug(HotplugHandler *hotplug_dev,
Error *local_err = NULL;
PCMachineState *pcms = PC_MACHINE(hotplug_dev);
- if (!dev->hotplugged) {
- goto out;
- }
-
- if (!pcms->acpi_dev) {
- error_setg(&local_err,
- "cpu hotplug is not enabled: missing acpi device");
- goto out;
+ if (pcms->acpi_dev) {
+ hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
+ hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
+ if (local_err) {
+ goto out;
+ }
}
- hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
- hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
- if (local_err) {
- goto out;
+ if (dev->hotplugged) {
+ /* increment the number of CPUs */
+ rtc_set_memory(pcms->rtc, 0x5f, rtc_get_memory(pcms->rtc, 0x5f) + 1);
}
- /* increment the number of CPUs */
- rtc_set_memory(pcms->rtc, 0x5f, rtc_get_memory(pcms->rtc, 0x5f) + 1);
-
found_cpu = pc_find_cpu(pcms, CPU(dev), NULL);
found_cpu->cpu = CPU(dev);
out:
--
1.8.3.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PATCH 10/11] pc: delay setting number of boot CPUs to machine_done time
2016-06-23 14:54 [Qemu-devel] [PATCH 00/11] pc: allow to use -device/device_add for CPUs Igor Mammedov
` (8 preceding siblings ...)
2016-06-23 14:54 ` [Qemu-devel] [PATCH 09/11] pc: register created initial and hotpluged CPUs in one place pc_cpu_plug() Igor Mammedov
@ 2016-06-23 14:54 ` Igor Mammedov
2016-06-23 14:54 ` [Qemu-devel] [PATCH 11/11] pc: cpu: allow device_add to be used with x86 cpu Igor Mammedov
10 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2016-06-23 14:54 UTC (permalink / raw)
To: qemu-devel
Cc: pbonzini, rth, ehabkost, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
currently present CPUs counter in CMOS only contains
smp_cpus (i.e. initial CPUs specified with -smp X) and
doesn't account for CPUs created with -device.
If VM is started with additional CPUs added with
-device, it will hang in BIOS waiting for condition
smp_cpus == counted_cpus
forever as counted_cpus will include -device CPUs as well
and be more than smp_cpus.
make present CPUs counter in CMOS to count all CPUs
(initial and coldplugged with -device) by delaying
it to machine done time when it possible to count
CPUs added with -device.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
hw/i386/pc.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index b6b9acc..0b3baf0 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -471,9 +471,6 @@ void pc_cmos_init(PCMachineState *pcms,
rtc_set_memory(s, 0x5c, val >> 8);
rtc_set_memory(s, 0x5d, val >> 16);
- /* set the number of CPU */
- rtc_set_memory(s, 0x5f, smp_cpus - 1);
-
object_property_add_link(OBJECT(pcms), "rtc_state",
TYPE_ISA_DEVICE,
(Object **)&pcms->rtc,
@@ -1156,10 +1153,19 @@ void pc_cpus_init(PCMachineState *pcms)
static
void pc_machine_done(Notifier *notifier, void *data)
{
+ int i, boot_cpus = 0;
PCMachineState *pcms = container_of(notifier,
PCMachineState, machine_done);
PCIBus *bus = pcms->bus;
+ for (i = 0; i < pcms->possible_cpus->len; i++) {
+ if (pcms->possible_cpus->cpus[i].cpu) {
+ boot_cpus++;
+ }
+ }
+ /* set the number of CPUs */
+ rtc_set_memory(pcms->rtc, 0x5f, boot_cpus - 1);
+
if (bus) {
int extra_hosts = 0;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [PATCH 11/11] pc: cpu: allow device_add to be used with x86 cpu
2016-06-23 14:54 [Qemu-devel] [PATCH 00/11] pc: allow to use -device/device_add for CPUs Igor Mammedov
` (9 preceding siblings ...)
2016-06-23 14:54 ` [Qemu-devel] [PATCH 10/11] pc: delay setting number of boot CPUs to machine_done time Igor Mammedov
@ 2016-06-23 14:54 ` Igor Mammedov
10 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2016-06-23 14:54 UTC (permalink / raw)
To: qemu-devel
Cc: pbonzini, rth, ehabkost, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
target-i386/cpu.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 8c651f2..a67e551 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -3236,6 +3236,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
cc->cpu_exec_enter = x86_cpu_exec_enter;
cc->cpu_exec_exit = x86_cpu_exec_exit;
+ dc->cannot_instantiate_with_device_add_yet = false;
/*
* Reason: x86_cpu_initfn() calls cpu_exec_init(), which saves the
* object in cpus -> dangling pointer after final object_unref().
--
1.8.3.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PATCH 07/11] pc: set APIC ID based on socket/core/thread ids if it's not been set yet
2016-06-23 14:54 ` [Qemu-devel] [PATCH 07/11] pc: set APIC ID based on socket/core/thread ids if it's not been set yet Igor Mammedov
@ 2016-06-23 17:19 ` Eduardo Habkost
2016-06-23 17:48 ` Igor Mammedov
0 siblings, 1 reply; 27+ messages in thread
From: Eduardo Habkost @ 2016-06-23 17:19 UTC (permalink / raw)
To: Igor Mammedov
Cc: qemu-devel, pbonzini, rth, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
On Thu, Jun 23, 2016 at 04:54:25PM +0200, Igor Mammedov wrote:
> CPU added with device_add help won't have APIC ID set,
> so set it according to socket/core/thread ids provided
> with device_add command.
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
> hw/i386/pc.c | 18 +++++++++++++-----
> 1 file changed, 13 insertions(+), 5 deletions(-)
>
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 87352ae..63e9bb6 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -1758,13 +1758,23 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
> DeviceState *dev, Error **errp)
> {
> int idx;
> + CPUArchId *cpu_slot;
> + X86CPUTopoInfo topo;
> X86CPU *cpu = X86_CPU(dev);
> PCMachineState *pcms = PC_MACHINE(hotplug_dev);
> - CPUArchId *cpu_slot = pc_find_cpu(pcms, CPU(dev), &idx);
>
> + if (cpu->apic_id == 0xFFFFFFFF) {
> + /* APIC ID not set, set it based on socket/core/thread properties */
> + X86CPUTopoInfo topo = { cpu->socket, cpu->core, cpu->thread };
> + cpu->apic_id = apicid_from_topo_ids(smp_cores, smp_threads, &topo);
> + }
What happens if neither apic-id or socket/core/thread are set?
apicid_from_topo_ids() needs the caller to ensure
core_id < nr_cores && smt_id < nr_threads. Do you do that?
> +
> + cpu_slot = pc_find_cpu(pcms, CPU(dev), &idx);
> if (!cpu_slot) {
> - error_setg(errp, "Invalid CPU index with APIC ID (%" PRIu32
> - "), valid range 0:%d", cpu->apic_id,
> + x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads, &topo);
> + error_setg(errp, "Invalid CPU[socket: %d, core: %d, thread: %d] with"
> + " APIC ID (%" PRIu32 "), valid index range 0:%d",
> + topo.pkg_id, topo.core_id, topo.smt_id, cpu->apic_id,
> pcms->possible_cpus->len - 1);
The error message is a bit confusing: the interface is not based
on CPU index anymore, but it still says "valid index range 0:%d".
> return;
> }
> @@ -1780,8 +1790,6 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
> * added CPUs so that query_hotpluggable_cpus would show correct values
> */
> if (cpu->thread == -1 || cpu->core == -1 || cpu->socket == -1) {
> - X86CPUTopoInfo topo;
> -
> x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads, &topo);
> cpu->thread = topo.smt_id;
> cpu->core = topo.core_id;
> --
> 1.8.3.1
>
--
Eduardo
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PATCH 03/11] pc: extract CPU lookup into a separate function
2016-06-23 14:54 ` [Qemu-devel] [PATCH 03/11] pc: extract CPU lookup into a separate function Igor Mammedov
@ 2016-06-23 17:32 ` Eduardo Habkost
2016-06-23 17:41 ` Igor Mammedov
0 siblings, 1 reply; 27+ messages in thread
From: Eduardo Habkost @ 2016-06-23 17:32 UTC (permalink / raw)
To: Igor Mammedov
Cc: qemu-devel, pbonzini, rth, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
On Thu, Jun 23, 2016 at 04:54:21PM +0200, Igor Mammedov wrote:
> it will be reused in the next patch at pre_plug time
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
> hw/i386/pc.c | 24 +++++++++++++++++-------
> 1 file changed, 17 insertions(+), 7 deletions(-)
>
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 07a3b82..ec9b14b 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -1675,11 +1675,25 @@ static int pc_apic_cmp(const void *a, const void *b)
> return apic_a->arch_id - apic_b->arch_id;
> }
>
> +static CPUArchId *pc_find_cpu(PCMachineState *pcms, CPUState *cpu, int *idx)
A short comment explaining what it does (and what does the return
value actually means) would't be bad.
The function name confused me when reviewing patch 07/11, as:
1) returning non-NULL means a CPU "slot"[1] exists, not
necessarily that a CPU exists; 2) returning NULL means that a CPU
doesn't exist _and_ that the ID/slot is not available for
plugging.
I would call it pc_find_cpu_slot() or pc_find_possible_cpu_id().
[1] Or whatever name we choose to call a "possible ID/address for
a CPU".
> +{
> + CPUClass *cc = CPU_GET_CLASS(cpu);
> + CPUArchId apic_id, *found_cpu;
> +
> + apic_id.arch_id = cc->get_arch_id(CPU(cpu));
> + found_cpu = bsearch(&apic_id, pcms->possible_cpus->cpus,
> + pcms->possible_cpus->len, sizeof(*pcms->possible_cpus->cpus),
> + pc_apic_cmp);
> + if (found_cpu && idx) {
> + *idx = found_cpu - pcms->possible_cpus->cpus;
> + }
> + return found_cpu;
> +}
> +
> static void pc_cpu_plug(HotplugHandler *hotplug_dev,
> DeviceState *dev, Error **errp)
> {
> - CPUClass *cc = CPU_GET_CLASS(dev);
> - CPUArchId apic_id, *found_cpu;
> + CPUArchId *found_cpu;
> HotplugHandlerClass *hhc;
> Error *local_err = NULL;
> PCMachineState *pcms = PC_MACHINE(hotplug_dev);
> @@ -1703,11 +1717,7 @@ static void pc_cpu_plug(HotplugHandler *hotplug_dev,
> /* increment the number of CPUs */
> rtc_set_memory(pcms->rtc, 0x5f, rtc_get_memory(pcms->rtc, 0x5f) + 1);
>
> - apic_id.arch_id = cc->get_arch_id(CPU(dev));
> - found_cpu = bsearch(&apic_id, pcms->possible_cpus->cpus,
> - pcms->possible_cpus->len, sizeof(*pcms->possible_cpus->cpus),
> - pc_apic_cmp);
> - assert(found_cpu);
> + found_cpu = pc_find_cpu(pcms, CPU(dev), NULL);
> found_cpu->cpu = CPU(dev);
> out:
> error_propagate(errp, local_err);
> --
> 1.8.3.1
>
--
Eduardo
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PATCH 03/11] pc: extract CPU lookup into a separate function
2016-06-23 17:32 ` Eduardo Habkost
@ 2016-06-23 17:41 ` Igor Mammedov
0 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2016-06-23 17:41 UTC (permalink / raw)
To: Eduardo Habkost
Cc: qemu-devel, pbonzini, rth, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
On Thu, 23 Jun 2016 14:32:10 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:
> On Thu, Jun 23, 2016 at 04:54:21PM +0200, Igor Mammedov wrote:
> > it will be reused in the next patch at pre_plug time
> >
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> > hw/i386/pc.c | 24 +++++++++++++++++-------
> > 1 file changed, 17 insertions(+), 7 deletions(-)
> >
> > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > index 07a3b82..ec9b14b 100644
> > --- a/hw/i386/pc.c
> > +++ b/hw/i386/pc.c
> > @@ -1675,11 +1675,25 @@ static int pc_apic_cmp(const void *a, const
> > void *b) return apic_a->arch_id - apic_b->arch_id;
> > }
> >
> > +static CPUArchId *pc_find_cpu(PCMachineState *pcms, CPUState *cpu,
> > int *idx)
>
> A short comment explaining what it does (and what does the return
> value actually means) would't be bad.
>
> The function name confused me when reviewing patch 07/11, as:
> 1) returning non-NULL means a CPU "slot"[1] exists, not
> necessarily that a CPU exists; 2) returning NULL means that a CPU
> doesn't exist _and_ that the ID/slot is not available for
> plugging.
>
> I would call it pc_find_cpu_slot() or
> pc_find_possible_cpu_id().
Ok, I'll rename it to pc_find_cpu_slot() and add comment
>
> [1] Or whatever name we choose to call a "possible ID/address for
> a CPU".
>
>
> > +{
> > + CPUClass *cc = CPU_GET_CLASS(cpu);
> > + CPUArchId apic_id, *found_cpu;
> > +
> > + apic_id.arch_id = cc->get_arch_id(CPU(cpu));
> > + found_cpu = bsearch(&apic_id, pcms->possible_cpus->cpus,
> > + pcms->possible_cpus->len,
> > sizeof(*pcms->possible_cpus->cpus),
> > + pc_apic_cmp);
> > + if (found_cpu && idx) {
> > + *idx = found_cpu - pcms->possible_cpus->cpus;
> > + }
> > + return found_cpu;
> > +}
> > +
> > static void pc_cpu_plug(HotplugHandler *hotplug_dev,
> > DeviceState *dev, Error **errp)
> > {
> > - CPUClass *cc = CPU_GET_CLASS(dev);
> > - CPUArchId apic_id, *found_cpu;
> > + CPUArchId *found_cpu;
> > HotplugHandlerClass *hhc;
> > Error *local_err = NULL;
> > PCMachineState *pcms = PC_MACHINE(hotplug_dev);
> > @@ -1703,11 +1717,7 @@ static void pc_cpu_plug(HotplugHandler
> > *hotplug_dev, /* increment the number of CPUs */
> > rtc_set_memory(pcms->rtc, 0x5f, rtc_get_memory(pcms->rtc,
> > 0x5f) + 1);
> > - apic_id.arch_id = cc->get_arch_id(CPU(dev));
> > - found_cpu = bsearch(&apic_id, pcms->possible_cpus->cpus,
> > - pcms->possible_cpus->len,
> > sizeof(*pcms->possible_cpus->cpus),
> > - pc_apic_cmp);
> > - assert(found_cpu);
> > + found_cpu = pc_find_cpu(pcms, CPU(dev), NULL);
> > found_cpu->cpu = CPU(dev);
> > out:
> > error_propagate(errp, local_err);
> > --
> > 1.8.3.1
> >
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PATCH 06/11] target-i386: add socket/core/thread properties to X86CPU
2016-06-23 14:54 ` [Qemu-devel] [PATCH 06/11] target-i386: add socket/core/thread properties to X86CPU Igor Mammedov
@ 2016-06-23 17:44 ` Eduardo Habkost
2016-06-23 19:18 ` Igor Mammedov
0 siblings, 1 reply; 27+ messages in thread
From: Eduardo Habkost @ 2016-06-23 17:44 UTC (permalink / raw)
To: Igor Mammedov
Cc: qemu-devel, pbonzini, rth, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
On Thu, Jun 23, 2016 at 04:54:24PM +0200, Igor Mammedov wrote:
> these properties will be used by as address where to plug
> CPU with help -device/device_add commands.
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
> hw/i386/pc.c | 12 ++++++++++++
> target-i386/cpu.c | 3 +++
> target-i386/cpu.h | 4 ++++
> 3 files changed, 19 insertions(+)
>
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 6ba6343..87352ae 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -1775,6 +1775,18 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
> cpu->apic_id);
> return;
> }
> +
> + /* set 'address' properties socket/core/thread for initial and cpu-add
> + * added CPUs so that query_hotpluggable_cpus would show correct values
> + */
> + if (cpu->thread == -1 || cpu->core == -1 || cpu->socket == -1) {
> + X86CPUTopoInfo topo;
> +
> + x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads, &topo);
> + cpu->thread = topo.smt_id;
> + cpu->core = topo.core_id;
> + cpu->socket = topo.pkg_id;
> + }
What if both apic-id and socket/core/thread are set?
I suggest validating the properties, and setting them in case
they are not set:
x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads, &topo);
if (cpu->socket != -1 && cpu->socket != topo.socket_id) {
error_setg(errp, "CPU socket ID mismatch: ...");
return;
}
cpu->socket = topo.socket_id;
if (cpu->core != -1 && cpu->core != topo.core_id) {
error_setg(errp, "CPU core ID mismatch: ...");
return;
}
cpu->core = topo.core_id;
if (cpu->thread != -1 && cpu->thread != topo.smt_id) {
error_setg(errp, "CPU thread ID mismatch: ...");
return;
}
cpu->thread = topo.smt_id;
We could do that inside x86_cpu_realizefn(), so that
socket/core/thread would be always set in all CPUs.
> }
>
> static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> index 9294b3d..8c651f2 100644
> --- a/target-i386/cpu.c
> +++ b/target-i386/cpu.c
> @@ -3186,6 +3186,9 @@ static Property x86_cpu_properties[] = {
> DEFINE_PROP_UINT32("xlevel2", X86CPU, env.cpuid_xlevel2, 0),
> DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor_id),
> DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true),
> + DEFINE_PROP_INT32("thread", X86CPU, thread, -1),
> + DEFINE_PROP_INT32("core", X86CPU, core, -1),
> + DEFINE_PROP_INT32("socket", X86CPU, socket, -1),
> DEFINE_PROP_END_OF_LIST()
> };
>
> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> index 8b09cfa..a04d334 100644
> --- a/target-i386/cpu.h
> +++ b/target-i386/cpu.h
> @@ -1190,6 +1190,10 @@ struct X86CPU {
> Notifier machine_done;
>
> struct kvm_msrs *kvm_msr_buf;
> +
> + int32_t socket;
> + int32_t core;
> + int32_t thread;
> };
>
> static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
> --
> 1.8.3.1
>
--
Eduardo
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PATCH 07/11] pc: set APIC ID based on socket/core/thread ids if it's not been set yet
2016-06-23 17:19 ` Eduardo Habkost
@ 2016-06-23 17:48 ` Igor Mammedov
2016-06-23 19:27 ` Eduardo Habkost
0 siblings, 1 reply; 27+ messages in thread
From: Igor Mammedov @ 2016-06-23 17:48 UTC (permalink / raw)
To: Eduardo Habkost
Cc: qemu-devel, pbonzini, rth, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
On Thu, 23 Jun 2016 14:19:16 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:
> On Thu, Jun 23, 2016 at 04:54:25PM +0200, Igor Mammedov wrote:
> > CPU added with device_add help won't have APIC ID set,
> > so set it according to socket/core/thread ids provided
> > with device_add command.
> >
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> > hw/i386/pc.c | 18 +++++++++++++-----
> > 1 file changed, 13 insertions(+), 5 deletions(-)
> >
> > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > index 87352ae..63e9bb6 100644
> > --- a/hw/i386/pc.c
> > +++ b/hw/i386/pc.c
> > @@ -1758,13 +1758,23 @@ static void pc_cpu_pre_plug(HotplugHandler
> > *hotplug_dev, DeviceState *dev, Error **errp)
> > {
> > int idx;
> > + CPUArchId *cpu_slot;
> > + X86CPUTopoInfo topo;
> > X86CPU *cpu = X86_CPU(dev);
> > PCMachineState *pcms = PC_MACHINE(hotplug_dev);
> > - CPUArchId *cpu_slot = pc_find_cpu(pcms, CPU(dev), &idx);
> >
> > + if (cpu->apic_id == 0xFFFFFFFF) {
> > + /* APIC ID not set, set it based on socket/core/thread
> > properties */
> > + X86CPUTopoInfo topo = { cpu->socket, cpu->core,
> > cpu->thread };
> > + cpu->apic_id = apicid_from_topo_ids(smp_cores,
> > smp_threads, &topo);
> > + }
>
> What happens if neither apic-id or socket/core/thread are set?
>
> apicid_from_topo_ids() needs the caller to ensure
> core_id < nr_cores && smt_id < nr_threads. Do you do that?
it will get wrong apic_id and error in "if (!cpu_slot)" will trigger,
I can explicitly check for unset values report error saying that
they must be set if you prefer.
>
> > +
> > + cpu_slot = pc_find_cpu(pcms, CPU(dev), &idx);
> > if (!cpu_slot) {
> > - error_setg(errp, "Invalid CPU index with APIC ID (%" PRIu32
> > - "), valid range 0:%d", cpu->apic_id,
> > + x86_topo_ids_from_apicid(cpu->apic_id, smp_cores,
> > smp_threads, &topo);
> > + error_setg(errp, "Invalid CPU[socket: %d, core: %d,
> > thread: %d] with"
> > + " APIC ID (%" PRIu32 "), valid index range 0:%d",
> > + topo.pkg_id, topo.core_id, topo.smt_id,
> > cpu->apic_id, pcms->possible_cpus->len - 1);
>
> The error message is a bit confusing: the interface is not based
> on CPU index anymore, but it still says "valid index range 0:%d".
it's still based on CPU index for cpu-add and -numa cpus,
so until we get rid of index in there it still should be printed.
>
> > return;
> > }
> > @@ -1780,8 +1790,6 @@ static void pc_cpu_pre_plug(HotplugHandler
> > *hotplug_dev,
> > * added CPUs so that query_hotpluggable_cpus would show
> > correct values */
> > if (cpu->thread == -1 || cpu->core == -1 || cpu->socket == -1)
> > {
> > - X86CPUTopoInfo topo;
> > -
> > x86_topo_ids_from_apicid(cpu->apic_id, smp_cores,
> > smp_threads, &topo); cpu->thread = topo.smt_id;
> > cpu->core = topo.core_id;
> > --
> > 1.8.3.1
> >
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PATCH 06/11] target-i386: add socket/core/thread properties to X86CPU
2016-06-23 17:44 ` Eduardo Habkost
@ 2016-06-23 19:18 ` Igor Mammedov
2016-06-23 20:18 ` Eduardo Habkost
0 siblings, 1 reply; 27+ messages in thread
From: Igor Mammedov @ 2016-06-23 19:18 UTC (permalink / raw)
To: Eduardo Habkost
Cc: zhugh.fnst, mst, qemu-devel, armbru, eduardo.otubo, pbonzini, rth
On Thu, 23 Jun 2016 14:44:53 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:
> On Thu, Jun 23, 2016 at 04:54:24PM +0200, Igor Mammedov wrote:
> > these properties will be used by as address where to plug
> > CPU with help -device/device_add commands.
> >
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> > hw/i386/pc.c | 12 ++++++++++++
> > target-i386/cpu.c | 3 +++
> > target-i386/cpu.h | 4 ++++
> > 3 files changed, 19 insertions(+)
> >
> > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > index 6ba6343..87352ae 100644
> > --- a/hw/i386/pc.c
> > +++ b/hw/i386/pc.c
> > @@ -1775,6 +1775,18 @@ static void pc_cpu_pre_plug(HotplugHandler
> > *hotplug_dev, cpu->apic_id);
> > return;
> > }
> > +
> > + /* set 'address' properties socket/core/thread for initial and
> > cpu-add
> > + * added CPUs so that query_hotpluggable_cpus would show
> > correct values
> > + */
> > + if (cpu->thread == -1 || cpu->core == -1 || cpu->socket == -1)
> > {
> > + X86CPUTopoInfo topo;
> > +
> > + x86_topo_ids_from_apicid(cpu->apic_id, smp_cores,
> > smp_threads, &topo);
> > + cpu->thread = topo.smt_id;
> > + cpu->core = topo.core_id;
> > + cpu->socket = topo.pkg_id;
> > + }
>
> What if both apic-id and socket/core/thread are set?
they shouldn't since query_hotpluggable_cpus doesn't have apic_id
attribute so apic_id isn't supposed to be on user provided,
but of cause user could add it manually on device_add command to create
confusion, in that case apic_id would take precedence and
socket/core/thread ignored.
>
> I suggest validating the properties, and setting them in case
> they are not set:
>
> x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads,
> &topo);
>
> if (cpu->socket != -1 && cpu->socket != topo.socket_id) {
> error_setg(errp, "CPU socket ID mismatch: ...");
> return;
> }
> cpu->socket = topo.socket_id;
>
> if (cpu->core != -1 && cpu->core != topo.core_id) {
> error_setg(errp, "CPU core ID mismatch: ...");
> return;
> }
> cpu->core = topo.core_id;
>
> if (cpu->thread != -1 && cpu->thread != topo.smt_id) {
> error_setg(errp, "CPU thread ID mismatch: ...");
> return;
> }
> cpu->thread = topo.smt_id;
>
> We could do that inside x86_cpu_realizefn(), so that
> socket/core/thread would be always set in all CPUs.
all CPUs pass through pc_cpu_pre_plug() before cpu.relizefn()
so I'd rather do it here at board level responsible for
setting apic_id or socket/core/thread info is not set.
>
> > }
> >
> > static void pc_machine_device_pre_plug_cb(HotplugHandler
> > *hotplug_dev, diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> > index 9294b3d..8c651f2 100644
> > --- a/target-i386/cpu.c
> > +++ b/target-i386/cpu.c
> > @@ -3186,6 +3186,9 @@ static Property x86_cpu_properties[] = {
> > DEFINE_PROP_UINT32("xlevel2", X86CPU, env.cpuid_xlevel2, 0),
> > DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor_id),
> > DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true),
> > + DEFINE_PROP_INT32("thread", X86CPU, thread, -1),
> > + DEFINE_PROP_INT32("core", X86CPU, core, -1),
> > + DEFINE_PROP_INT32("socket", X86CPU, socket, -1),
> > DEFINE_PROP_END_OF_LIST()
> > };
> >
> > diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> > index 8b09cfa..a04d334 100644
> > --- a/target-i386/cpu.h
> > +++ b/target-i386/cpu.h
> > @@ -1190,6 +1190,10 @@ struct X86CPU {
> > Notifier machine_done;
> >
> > struct kvm_msrs *kvm_msr_buf;
> > +
> > + int32_t socket;
> > + int32_t core;
> > + int32_t thread;
> > };
> >
> > static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
> > --
> > 1.8.3.1
> >
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PATCH 07/11] pc: set APIC ID based on socket/core/thread ids if it's not been set yet
2016-06-23 17:48 ` Igor Mammedov
@ 2016-06-23 19:27 ` Eduardo Habkost
2016-06-23 20:50 ` Igor Mammedov
0 siblings, 1 reply; 27+ messages in thread
From: Eduardo Habkost @ 2016-06-23 19:27 UTC (permalink / raw)
To: Igor Mammedov
Cc: qemu-devel, pbonzini, rth, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
On Thu, Jun 23, 2016 at 07:48:24PM +0200, Igor Mammedov wrote:
> On Thu, 23 Jun 2016 14:19:16 -0300
> Eduardo Habkost <ehabkost@redhat.com> wrote:
>
> > On Thu, Jun 23, 2016 at 04:54:25PM +0200, Igor Mammedov wrote:
> > > CPU added with device_add help won't have APIC ID set,
> > > so set it according to socket/core/thread ids provided
> > > with device_add command.
> > >
> > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > ---
> > > hw/i386/pc.c | 18 +++++++++++++-----
> > > 1 file changed, 13 insertions(+), 5 deletions(-)
> > >
> > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > > index 87352ae..63e9bb6 100644
> > > --- a/hw/i386/pc.c
> > > +++ b/hw/i386/pc.c
> > > @@ -1758,13 +1758,23 @@ static void pc_cpu_pre_plug(HotplugHandler
> > > *hotplug_dev, DeviceState *dev, Error **errp)
> > > {
> > > int idx;
> > > + CPUArchId *cpu_slot;
> > > + X86CPUTopoInfo topo;
> > > X86CPU *cpu = X86_CPU(dev);
> > > PCMachineState *pcms = PC_MACHINE(hotplug_dev);
> > > - CPUArchId *cpu_slot = pc_find_cpu(pcms, CPU(dev), &idx);
> > >
> > > + if (cpu->apic_id == 0xFFFFFFFF) {
> > > + /* APIC ID not set, set it based on socket/core/thread
> > > properties */
> > > + X86CPUTopoInfo topo = { cpu->socket, cpu->core,
> > > cpu->thread };
> > > + cpu->apic_id = apicid_from_topo_ids(smp_cores,
> > > smp_threads, &topo);
> > > + }
> >
> > What happens if neither apic-id or socket/core/thread are set?
> >
> > apicid_from_topo_ids() needs the caller to ensure
> > core_id < nr_cores && smt_id < nr_threads. Do you do that?
> it will get wrong apic_id and error in "if (!cpu_slot)" will trigger,
> I can explicitly check for unset values report error saying that
> they must be set if you prefer.
Will it? If smp_cores=2 and smp_threads=2,
socket=0,core=0,thread=3 will generate a valid APIC ID
(corresponding to socket=0,core=1,thread=1).
About unset/invalid values: apicid_from_topo_ids() documentation
explicitly requires core_id < nr_cores && smt_id < nr_threads,
and may generate a valid APIC ID if only some of the
socket/core/thread values are set to -1.
(Also, if you don't check for missing/invalid values explicitly
you will generate a very confusing error message for the user).
>
> >
> > > +
> > > + cpu_slot = pc_find_cpu(pcms, CPU(dev), &idx);
> > > if (!cpu_slot) {
> > > - error_setg(errp, "Invalid CPU index with APIC ID (%" PRIu32
> > > - "), valid range 0:%d", cpu->apic_id,
> > > + x86_topo_ids_from_apicid(cpu->apic_id, smp_cores,
> > > smp_threads, &topo);
> > > + error_setg(errp, "Invalid CPU[socket: %d, core: %d,
> > > thread: %d] with"
> > > + " APIC ID (%" PRIu32 "), valid index range 0:%d",
> > > + topo.pkg_id, topo.core_id, topo.smt_id,
> > > cpu->apic_id, pcms->possible_cpus->len - 1);
> >
> > The error message is a bit confusing: the interface is not based
> > on CPU index anymore, but it still says "valid index range 0:%d".
> it's still based on CPU index for cpu-add and -numa cpus,
> so until we get rid of index in there it still should be printed.
OK.
>
> >
> > > return;
> > > }
> > > @@ -1780,8 +1790,6 @@ static void pc_cpu_pre_plug(HotplugHandler
> > > *hotplug_dev,
> > > * added CPUs so that query_hotpluggable_cpus would show
> > > correct values */
> > > if (cpu->thread == -1 || cpu->core == -1 || cpu->socket == -1)
> > > {
> > > - X86CPUTopoInfo topo;
> > > -
> > > x86_topo_ids_from_apicid(cpu->apic_id, smp_cores,
> > > smp_threads, &topo); cpu->thread = topo.smt_id;
> > > cpu->core = topo.core_id;
> > > --
> > > 1.8.3.1
> > >
> >
>
--
Eduardo
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PATCH 06/11] target-i386: add socket/core/thread properties to X86CPU
2016-06-23 19:18 ` Igor Mammedov
@ 2016-06-23 20:18 ` Eduardo Habkost
2016-06-23 20:46 ` Igor Mammedov
0 siblings, 1 reply; 27+ messages in thread
From: Eduardo Habkost @ 2016-06-23 20:18 UTC (permalink / raw)
To: Igor Mammedov
Cc: zhugh.fnst, mst, qemu-devel, armbru, eduardo.otubo, pbonzini, rth
On Thu, Jun 23, 2016 at 09:18:38PM +0200, Igor Mammedov wrote:
> On Thu, 23 Jun 2016 14:44:53 -0300
> Eduardo Habkost <ehabkost@redhat.com> wrote:
>
> > On Thu, Jun 23, 2016 at 04:54:24PM +0200, Igor Mammedov wrote:
> > > these properties will be used by as address where to plug
> > > CPU with help -device/device_add commands.
> > >
> > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > ---
> > > hw/i386/pc.c | 12 ++++++++++++
> > > target-i386/cpu.c | 3 +++
> > > target-i386/cpu.h | 4 ++++
> > > 3 files changed, 19 insertions(+)
> > >
> > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > > index 6ba6343..87352ae 100644
> > > --- a/hw/i386/pc.c
> > > +++ b/hw/i386/pc.c
> > > @@ -1775,6 +1775,18 @@ static void pc_cpu_pre_plug(HotplugHandler
> > > *hotplug_dev, cpu->apic_id);
> > > return;
> > > }
> > > +
> > > + /* set 'address' properties socket/core/thread for initial and
> > > cpu-add
> > > + * added CPUs so that query_hotpluggable_cpus would show
> > > correct values
> > > + */
> > > + if (cpu->thread == -1 || cpu->core == -1 || cpu->socket == -1)
> > > {
> > > + X86CPUTopoInfo topo;
> > > +
> > > + x86_topo_ids_from_apicid(cpu->apic_id, smp_cores,
> > > smp_threads, &topo);
> > > + cpu->thread = topo.smt_id;
> > > + cpu->core = topo.core_id;
> > > + cpu->socket = topo.pkg_id;
> > > + }
> >
> > What if both apic-id and socket/core/thread are set?
> they shouldn't since query_hotpluggable_cpus doesn't have apic_id
> attribute so apic_id isn't supposed to be on user provided,
> but of cause user could add it manually on device_add command to create
> confusion, in that case apic_id would take precedence and
> socket/core/thread ignored.
I would like to reject obviously invalid input instead of having
unclear precedence rules.
>
> >
> > I suggest validating the properties, and setting them in case
> > they are not set:
> >
> > x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads,
> > &topo);
> >
> > if (cpu->socket != -1 && cpu->socket != topo.socket_id) {
> > error_setg(errp, "CPU socket ID mismatch: ...");
> > return;
> > }
> > cpu->socket = topo.socket_id;
> >
> > if (cpu->core != -1 && cpu->core != topo.core_id) {
> > error_setg(errp, "CPU core ID mismatch: ...");
> > return;
> > }
> > cpu->core = topo.core_id;
> >
> > if (cpu->thread != -1 && cpu->thread != topo.smt_id) {
> > error_setg(errp, "CPU thread ID mismatch: ...");
> > return;
> > }
> > cpu->thread = topo.smt_id;
> >
> > We could do that inside x86_cpu_realizefn(), so that
> > socket/core/thread would be always set in all CPUs.
> all CPUs pass through pc_cpu_pre_plug() before cpu.relizefn()
> so I'd rather do it here at board level responsible for
> setting apic_id or socket/core/thread info is not set.
Then *-user will be inconsistent, and will always have invalid
values in socket/core/thread. If one day we add any logic using
the socket/core/thread properties in cpu.c, it will break on
*-user.
All those properties are X86CPU properties, meaning they are
input to the X86CPU code. I don't see why we should move logic
related to them outside cpu.c unless really necessary.
(The apic-id calculation at patch 07/11, for example, is more
difficult to move to cpu.c, because the PC code needs the APIC ID
before calling realize. We could move it to the apic-id getter,
but I dislike having magic getter/setters and like that you made
it a static property.)
--
Eduardo
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PATCH 06/11] target-i386: add socket/core/thread properties to X86CPU
2016-06-23 20:18 ` Eduardo Habkost
@ 2016-06-23 20:46 ` Igor Mammedov
2016-06-23 21:43 ` Eduardo Habkost
0 siblings, 1 reply; 27+ messages in thread
From: Igor Mammedov @ 2016-06-23 20:46 UTC (permalink / raw)
To: Eduardo Habkost
Cc: zhugh.fnst, mst, qemu-devel, armbru, eduardo.otubo, pbonzini, rth
On Thu, 23 Jun 2016 17:18:46 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:
> On Thu, Jun 23, 2016 at 09:18:38PM +0200, Igor Mammedov wrote:
> > On Thu, 23 Jun 2016 14:44:53 -0300
> > Eduardo Habkost <ehabkost@redhat.com> wrote:
> >
> > > On Thu, Jun 23, 2016 at 04:54:24PM +0200, Igor Mammedov wrote:
> > > > these properties will be used by as address where to plug
> > > > CPU with help -device/device_add commands.
> > > >
> > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > > ---
> > > > hw/i386/pc.c | 12 ++++++++++++
> > > > target-i386/cpu.c | 3 +++
> > > > target-i386/cpu.h | 4 ++++
> > > > 3 files changed, 19 insertions(+)
> > > >
> > > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > > > index 6ba6343..87352ae 100644
> > > > --- a/hw/i386/pc.c
> > > > +++ b/hw/i386/pc.c
> > > > @@ -1775,6 +1775,18 @@ static void
> > > > pc_cpu_pre_plug(HotplugHandler *hotplug_dev, cpu->apic_id);
> > > > return;
> > > > }
> > > > +
> > > > + /* set 'address' properties socket/core/thread for initial
> > > > and cpu-add
> > > > + * added CPUs so that query_hotpluggable_cpus would show
> > > > correct values
> > > > + */
> > > > + if (cpu->thread == -1 || cpu->core == -1 || cpu->socket ==
> > > > -1) {
> > > > + X86CPUTopoInfo topo;
> > > > +
> > > > + x86_topo_ids_from_apicid(cpu->apic_id, smp_cores,
> > > > smp_threads, &topo);
> > > > + cpu->thread = topo.smt_id;
> > > > + cpu->core = topo.core_id;
> > > > + cpu->socket = topo.pkg_id;
> > > > + }
> > >
> > > What if both apic-id and socket/core/thread are set?
> > they shouldn't since query_hotpluggable_cpus doesn't have apic_id
> > attribute so apic_id isn't supposed to be on user provided,
> > but of cause user could add it manually on device_add command to
> > create confusion, in that case apic_id would take precedence and
> > socket/core/thread ignored.
>
> I would like to reject obviously invalid input instead of having
> unclear precedence rules.
ok
> >
> > >
> > > I suggest validating the properties, and setting them in case
> > > they are not set:
> > >
> > > x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads,
> > > &topo);
> > >
> > > if (cpu->socket != -1 && cpu->socket != topo.socket_id) {
> > > error_setg(errp, "CPU socket ID mismatch: ...");
> > > return;
> > > }
> > > cpu->socket = topo.socket_id;
> > >
> > > if (cpu->core != -1 && cpu->core != topo.core_id) {
> > > error_setg(errp, "CPU core ID mismatch: ...");
> > > return;
> > > }
> > > cpu->core = topo.core_id;
> > >
> > > if (cpu->thread != -1 && cpu->thread != topo.smt_id) {
> > > error_setg(errp, "CPU thread ID mismatch: ...");
> > > return;
> > > }
> > > cpu->thread = topo.smt_id;
> > >
> > > We could do that inside x86_cpu_realizefn(), so that
> > > socket/core/thread would be always set in all CPUs.
> > all CPUs pass through pc_cpu_pre_plug() before cpu.relizefn()
> > so I'd rather do it here at board level responsible for
> > setting apic_id or socket/core/thread info is not set.
>
> Then *-user will be inconsistent, and will always have invalid
> values in socket/core/thread. If one day we add any logic using
> the socket/core/thread properties in cpu.c, it will break on
> *-user.
>
> All those properties are X86CPU properties, meaning they are
> input to the X86CPU code. I don't see why we should move logic
> related to them outside cpu.c unless really necessary.
>
> (The apic-id calculation at patch 07/11, for example, is more
> difficult to move to cpu.c, because the PC code needs the APIC ID
> before calling realize. We could move it to the apic-id getter,
> but I dislike having magic getter/setters and like that you made
> it a static property.)
set of socket/core/thread is a synonym for apic_id and it's board that
manages and knows valid values for them. Putting above snippet into
cpu.relizefn() would make CPU access globals smp_cores, smp_threads
which are essentially machine_state and Drew working on moving them
there and eliminating globals. So suddenly CPU would need to poke into
machine object, and we return to the same state wrt *-user only with
hack in cpu.c.
I'd worry about -smp and *-user when it comes into that target as it
will probably need apic_id and maybe socket/core/thread as well.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PATCH 07/11] pc: set APIC ID based on socket/core/thread ids if it's not been set yet
2016-06-23 19:27 ` Eduardo Habkost
@ 2016-06-23 20:50 ` Igor Mammedov
0 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2016-06-23 20:50 UTC (permalink / raw)
To: Eduardo Habkost
Cc: qemu-devel, pbonzini, rth, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
On Thu, 23 Jun 2016 16:27:46 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:
> On Thu, Jun 23, 2016 at 07:48:24PM +0200, Igor Mammedov wrote:
> > On Thu, 23 Jun 2016 14:19:16 -0300
> > Eduardo Habkost <ehabkost@redhat.com> wrote:
> >
> > > On Thu, Jun 23, 2016 at 04:54:25PM +0200, Igor Mammedov wrote:
> > > > CPU added with device_add help won't have APIC ID set,
> > > > so set it according to socket/core/thread ids provided
> > > > with device_add command.
> > > >
> > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > > ---
> > > > hw/i386/pc.c | 18 +++++++++++++-----
> > > > 1 file changed, 13 insertions(+), 5 deletions(-)
> > > >
> > > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > > > index 87352ae..63e9bb6 100644
> > > > --- a/hw/i386/pc.c
> > > > +++ b/hw/i386/pc.c
> > > > @@ -1758,13 +1758,23 @@ static void
> > > > pc_cpu_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
> > > > Error **errp) {
> > > > int idx;
> > > > + CPUArchId *cpu_slot;
> > > > + X86CPUTopoInfo topo;
> > > > X86CPU *cpu = X86_CPU(dev);
> > > > PCMachineState *pcms = PC_MACHINE(hotplug_dev);
> > > > - CPUArchId *cpu_slot = pc_find_cpu(pcms, CPU(dev), &idx);
> > > >
> > > > + if (cpu->apic_id == 0xFFFFFFFF) {
> > > > + /* APIC ID not set, set it based on socket/core/thread
> > > > properties */
> > > > + X86CPUTopoInfo topo = { cpu->socket, cpu->core,
> > > > cpu->thread };
> > > > + cpu->apic_id = apicid_from_topo_ids(smp_cores,
> > > > smp_threads, &topo);
> > > > + }
> > >
> > > What happens if neither apic-id or socket/core/thread are set?
> > >
> > > apicid_from_topo_ids() needs the caller to ensure
> > > core_id < nr_cores && smt_id < nr_threads. Do you do that?
> > it will get wrong apic_id and error in "if (!cpu_slot)" will
> > trigger, I can explicitly check for unset values report error
> > saying that they must be set if you prefer.
>
> Will it? If smp_cores=2 and smp_threads=2,
> socket=0,core=0,thread=3 will generate a valid APIC ID
> (corresponding to socket=0,core=1,thread=1).
>
> About unset/invalid values: apicid_from_topo_ids() documentation
> explicitly requires core_id < nr_cores && smt_id < nr_threads,
> and may generate a valid APIC ID if only some of the
> socket/core/thread values are set to -1.
>
> (Also, if you don't check for missing/invalid values explicitly
> you will generate a very confusing error message for the user).
ok, I'll add explicit checks for unset/invalid values here
as you suggested in previous patch.
>
> >
> > >
> > > > +
> > > > + cpu_slot = pc_find_cpu(pcms, CPU(dev), &idx);
> > > > if (!cpu_slot) {
> > > > - error_setg(errp, "Invalid CPU index with APIC ID (%"
> > > > PRIu32
> > > > - "), valid range 0:%d", cpu->apic_id,
> > > > + x86_topo_ids_from_apicid(cpu->apic_id, smp_cores,
> > > > smp_threads, &topo);
> > > > + error_setg(errp, "Invalid CPU[socket: %d, core: %d,
> > > > thread: %d] with"
> > > > + " APIC ID (%" PRIu32 "), valid index range
> > > > 0:%d",
> > > > + topo.pkg_id, topo.core_id, topo.smt_id,
> > > > cpu->apic_id, pcms->possible_cpus->len - 1);
> > >
> > > The error message is a bit confusing: the interface is not based
> > > on CPU index anymore, but it still says "valid index range 0:%d".
> > it's still based on CPU index for cpu-add and -numa cpus,
> > so until we get rid of index in there it still should be printed.
>
> OK.
>
> >
> > >
> > > > return;
> > > > }
> > > > @@ -1780,8 +1790,6 @@ static void pc_cpu_pre_plug(HotplugHandler
> > > > *hotplug_dev,
> > > > * added CPUs so that query_hotpluggable_cpus would show
> > > > correct values */
> > > > if (cpu->thread == -1 || cpu->core == -1 || cpu->socket ==
> > > > -1) {
> > > > - X86CPUTopoInfo topo;
> > > > -
> > > > x86_topo_ids_from_apicid(cpu->apic_id, smp_cores,
> > > > smp_threads, &topo); cpu->thread = topo.smt_id;
> > > > cpu->core = topo.core_id;
> > > > --
> > > > 1.8.3.1
> > > >
> > >
> >
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PATCH 06/11] target-i386: add socket/core/thread properties to X86CPU
2016-06-23 20:46 ` Igor Mammedov
@ 2016-06-23 21:43 ` Eduardo Habkost
2016-06-24 5:23 ` Igor Mammedov
0 siblings, 1 reply; 27+ messages in thread
From: Eduardo Habkost @ 2016-06-23 21:43 UTC (permalink / raw)
To: Igor Mammedov
Cc: zhugh.fnst, mst, qemu-devel, armbru, eduardo.otubo, pbonzini, rth,
Andrew Jones
On Thu, Jun 23, 2016 at 10:46:36PM +0200, Igor Mammedov wrote:
> On Thu, 23 Jun 2016 17:18:46 -0300
> Eduardo Habkost <ehabkost@redhat.com> wrote:
[...]
> > >
> > > >
> > > > I suggest validating the properties, and setting them in case
> > > > they are not set:
> > > >
> > > > x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads,
> > > > &topo);
> > > >
> > > > if (cpu->socket != -1 && cpu->socket != topo.socket_id) {
> > > > error_setg(errp, "CPU socket ID mismatch: ...");
> > > > return;
> > > > }
> > > > cpu->socket = topo.socket_id;
> > > >
> > > > if (cpu->core != -1 && cpu->core != topo.core_id) {
> > > > error_setg(errp, "CPU core ID mismatch: ...");
> > > > return;
> > > > }
> > > > cpu->core = topo.core_id;
> > > >
> > > > if (cpu->thread != -1 && cpu->thread != topo.smt_id) {
> > > > error_setg(errp, "CPU thread ID mismatch: ...");
> > > > return;
> > > > }
> > > > cpu->thread = topo.smt_id;
> > > >
> > > > We could do that inside x86_cpu_realizefn(), so that
> > > > socket/core/thread would be always set in all CPUs.
> > > all CPUs pass through pc_cpu_pre_plug() before cpu.relizefn()
> > > so I'd rather do it here at board level responsible for
> > > setting apic_id or socket/core/thread info is not set.
> >
> > Then *-user will be inconsistent, and will always have invalid
> > values in socket/core/thread. If one day we add any logic using
> > the socket/core/thread properties in cpu.c, it will break on
> > *-user.
> >
> > All those properties are X86CPU properties, meaning they are
> > input to the X86CPU code. I don't see why we should move logic
> > related to them outside cpu.c unless really necessary.
> >
> > (The apic-id calculation at patch 07/11, for example, is more
> > difficult to move to cpu.c, because the PC code needs the APIC ID
> > before calling realize. We could move it to the apic-id getter,
> > but I dislike having magic getter/setters and like that you made
> > it a static property.)
> set of socket/core/thread is a synonym for apic_id and it's board that
> manages and knows valid values for them.
The CPU already knows exactly what the bits inside APIC ID mean,
because it has to report topology information through CPUID.
> Putting above snippet into
> cpu.relizefn() would make CPU access globals smp_cores, smp_threads
> which are essentially machine_state and Drew working on moving them
> there and eliminating globals. So suddenly CPU would need to poke into
> machine object, and we return to the same state wrt *-user only with
> hack in cpu.c.
After Drew's code is included, we can simply use
CPUState::nr_cores and CPUState::nr_threads.
>
> I'd worry about -smp and *-user when it comes into that target as it
> will probably need apic_id and maybe socket/core/thread as well.
The point is to not even have to worry about *-user later, by
keeping both softmmu and *-user consistent. People reviewing
patches a few years from now probably wouldn't even notice that
code using the socket/core/thread fields will break in *-user.
I wouldn't mind about having the code in pc.c at all, if it
didn't make *-user inconsistent, or if the CPU object didn't had
all the required information yet. But I don't think it is
reasonable to intentionally leave X86CPU fields inconsistent in
*-user if we can easily fix it by moving initialization to
realizefn.
But if you are really strongly against that, I can propose that
as a follow-up later (after Drew's series is included).
--
Eduardo
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PATCH 06/11] target-i386: add socket/core/thread properties to X86CPU
2016-06-23 21:43 ` Eduardo Habkost
@ 2016-06-24 5:23 ` Igor Mammedov
0 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2016-06-24 5:23 UTC (permalink / raw)
To: Eduardo Habkost
Cc: zhugh.fnst, Andrew Jones, mst, armbru, qemu-devel, eduardo.otubo,
pbonzini, rth
On Thu, 23 Jun 2016 18:43:53 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:
> On Thu, Jun 23, 2016 at 10:46:36PM +0200, Igor Mammedov wrote:
> > On Thu, 23 Jun 2016 17:18:46 -0300
> > Eduardo Habkost <ehabkost@redhat.com> wrote:
> [...]
> > > >
> > > > >
> > > > > I suggest validating the properties, and setting them in case
> > > > > they are not set:
> > > > >
> > > > > x86_topo_ids_from_apicid(cpu->apic_id, smp_cores,
> > > > > smp_threads, &topo);
> > > > >
> > > > > if (cpu->socket != -1 && cpu->socket != topo.socket_id) {
> > > > > error_setg(errp, "CPU socket ID mismatch: ...");
> > > > > return;
> > > > > }
> > > > > cpu->socket = topo.socket_id;
> > > > >
> > > > > if (cpu->core != -1 && cpu->core != topo.core_id) {
> > > > > error_setg(errp, "CPU core ID mismatch: ...");
> > > > > return;
> > > > > }
> > > > > cpu->core = topo.core_id;
> > > > >
> > > > > if (cpu->thread != -1 && cpu->thread != topo.smt_id) {
> > > > > error_setg(errp, "CPU thread ID mismatch: ...");
> > > > > return;
> > > > > }
> > > > > cpu->thread = topo.smt_id;
> > > > >
> > > > > We could do that inside x86_cpu_realizefn(), so that
> > > > > socket/core/thread would be always set in all CPUs.
> > > > all CPUs pass through pc_cpu_pre_plug() before cpu.relizefn()
> > > > so I'd rather do it here at board level responsible for
> > > > setting apic_id or socket/core/thread info is not set.
> > >
> > > Then *-user will be inconsistent, and will always have invalid
> > > values in socket/core/thread. If one day we add any logic using
> > > the socket/core/thread properties in cpu.c, it will break on
> > > *-user.
> > >
> > > All those properties are X86CPU properties, meaning they are
> > > input to the X86CPU code. I don't see why we should move logic
> > > related to them outside cpu.c unless really necessary.
> > >
> > > (The apic-id calculation at patch 07/11, for example, is more
> > > difficult to move to cpu.c, because the PC code needs the APIC ID
> > > before calling realize. We could move it to the apic-id getter,
> > > but I dislike having magic getter/setters and like that you made
> > > it a static property.)
> > set of socket/core/thread is a synonym for apic_id and it's board
> > that manages and knows valid values for them.
>
> The CPU already knows exactly what the bits inside APIC ID mean,
> because it has to report topology information through CPUID.
>
> > Putting above snippet into
> > cpu.relizefn() would make CPU access globals smp_cores, smp_threads
> > which are essentially machine_state and Drew working on moving them
> > there and eliminating globals. So suddenly CPU would need to poke
> > into machine object, and we return to the same state wrt *-user
> > only with hack in cpu.c.
>
> After Drew's code is included, we can simply use
> CPUState::nr_cores and CPUState::nr_threads.
>
> >
> > I'd worry about -smp and *-user when it comes into that target as it
> > will probably need apic_id and maybe socket/core/thread as well.
>
> The point is to not even have to worry about *-user later, by
> keeping both softmmu and *-user consistent. People reviewing
> patches a few years from now probably wouldn't even notice that
> code using the socket/core/thread fields will break in *-user.
>
> I wouldn't mind about having the code in pc.c at all, if it
> didn't make *-user inconsistent, or if the CPU object didn't had
> all the required information yet. But I don't think it is
> reasonable to intentionally leave X86CPU fields inconsistent in
> *-user if we can easily fix it by moving initialization to
> realizefn.
>
> But if you are really strongly against that, I can propose that
> as a follow-up later (after Drew's series is included).
Lets do it as follow-up after Drew's -smp refactoring is in.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PATCH 05/11] target-i386: cpu: replace custom apic-id setter/getter with static property
2016-06-23 14:54 ` [Qemu-devel] [PATCH 05/11] target-i386: cpu: replace custom apic-id setter/getter with static property Igor Mammedov
@ 2016-06-27 17:55 ` Eduardo Habkost
2016-06-28 6:43 ` Igor Mammedov
0 siblings, 1 reply; 27+ messages in thread
From: Eduardo Habkost @ 2016-06-27 17:55 UTC (permalink / raw)
To: Igor Mammedov
Cc: qemu-devel, pbonzini, rth, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
On Thu, Jun 23, 2016 at 04:54:23PM +0200, Igor Mammedov wrote:
> custom apic-id setter/getter doesn't do any property specific
> checks anymorer, so clean it up and use more compact static
> property DEFINE_PROP_UINT32 instead.
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
> target-i386/cpu.c | 45 ++++++---------------------------------------
> 1 file changed, 6 insertions(+), 39 deletions(-)
>
> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> index 9511474..9294b3d 100644
> --- a/target-i386/cpu.c
> +++ b/target-i386/cpu.c
> @@ -1824,37 +1824,6 @@ static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, const char *name,
> cpu->env.tsc_khz = cpu->env.user_tsc_khz = value / 1000;
> }
>
> -static void x86_cpuid_get_apic_id(Object *obj, Visitor *v, const char *name,
> - void *opaque, Error **errp)
> -{
> - X86CPU *cpu = X86_CPU(obj);
> - int64_t value = cpu->apic_id;
> -
> - visit_type_int(v, name, &value, errp);
> -}
> -
> -static void x86_cpuid_set_apic_id(Object *obj, Visitor *v, const char *name,
> - void *opaque, Error **errp)
> -{
> - X86CPU *cpu = X86_CPU(obj);
> - DeviceState *dev = DEVICE(obj);
> - Error *error = NULL;
> - int64_t value;
> -
> - if (dev->realized) {
> - error_setg(errp, "Attempt to set property '%s' on '%s' after "
> - "it was realized", name, object_get_typename(obj));
> - return;
> - }
> -
> - visit_type_int(v, name, &value, &error);
> - if (error) {
> - error_propagate(errp, error);
> - return;
> - }
> - cpu->apic_id = value;
> -}
> -
> /* Generic getter for "feature-words" and "filtered-features" properties */
> static void x86_cpu_get_feature_words(Object *obj, Visitor *v,
> const char *name, void *opaque,
> @@ -3127,9 +3096,6 @@ static void x86_cpu_initfn(Object *obj)
> object_property_add(obj, "tsc-frequency", "int",
> x86_cpuid_get_tsc_freq,
> x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
> - object_property_add(obj, "apic-id", "int",
> - x86_cpuid_get_apic_id,
> - x86_cpuid_set_apic_id, NULL, NULL, NULL);
> object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
> x86_cpu_get_feature_words,
> NULL, NULL, (void *)env->features, NULL);
> @@ -3139,11 +3105,6 @@ static void x86_cpu_initfn(Object *obj)
>
> cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
>
> -#ifndef CONFIG_USER_ONLY
> - /* Any code creating new X86CPU objects have to set apic-id explicitly */
> - cpu->apic_id = UNASSIGNED_APIC_ID;
> -#endif
> -
> for (w = 0; w < FEATURE_WORDS; w++) {
> int bitnr;
>
> @@ -3200,6 +3161,12 @@ static bool x86_cpu_has_work(CPUState *cs)
> }
>
> static Property x86_cpu_properties[] = {
> +#ifdef CONFIG_USER_ONLY
> + /* apic_id = 0 by default for *-user, see commit 9886e834 */
> + DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, 0),
> +#else
> + DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, UNASSIGNED_APIC_ID),
> +#endif
Suggestion for a follow-up patch: setting the default to
UNASSIGNED_APIC_ID unconditionally, and just adding this to
x86_cpu_realizefn().
#ifdef CONFIG_USER_ONLY
if (cpu->apic_id == UNASSIGNED_APIC_ID) {
cpu->apic_id = 0;
}
#endif
--
Eduardo
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PATCH 05/11] target-i386: cpu: replace custom apic-id setter/getter with static property
2016-06-27 17:55 ` Eduardo Habkost
@ 2016-06-28 6:43 ` Igor Mammedov
2016-06-28 13:35 ` Eduardo Habkost
0 siblings, 1 reply; 27+ messages in thread
From: Igor Mammedov @ 2016-06-28 6:43 UTC (permalink / raw)
To: Eduardo Habkost
Cc: qemu-devel, pbonzini, rth, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
On Mon, 27 Jun 2016 14:55:24 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:
> On Thu, Jun 23, 2016 at 04:54:23PM +0200, Igor Mammedov wrote:
> > custom apic-id setter/getter doesn't do any property specific
> > checks anymorer, so clean it up and use more compact static
> > property DEFINE_PROP_UINT32 instead.
> >
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> > target-i386/cpu.c | 45 ++++++---------------------------------------
> > 1 file changed, 6 insertions(+), 39 deletions(-)
> >
> > diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> > index 9511474..9294b3d 100644
> > --- a/target-i386/cpu.c
> > +++ b/target-i386/cpu.c
> > @@ -1824,37 +1824,6 @@ static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, const char *name,
> > cpu->env.tsc_khz = cpu->env.user_tsc_khz = value / 1000;
> > }
> >
> > -static void x86_cpuid_get_apic_id(Object *obj, Visitor *v, const char *name,
> > - void *opaque, Error **errp)
> > -{
> > - X86CPU *cpu = X86_CPU(obj);
> > - int64_t value = cpu->apic_id;
> > -
> > - visit_type_int(v, name, &value, errp);
> > -}
> > -
> > -static void x86_cpuid_set_apic_id(Object *obj, Visitor *v, const char *name,
> > - void *opaque, Error **errp)
> > -{
> > - X86CPU *cpu = X86_CPU(obj);
> > - DeviceState *dev = DEVICE(obj);
> > - Error *error = NULL;
> > - int64_t value;
> > -
> > - if (dev->realized) {
> > - error_setg(errp, "Attempt to set property '%s' on '%s' after "
> > - "it was realized", name, object_get_typename(obj));
> > - return;
> > - }
> > -
> > - visit_type_int(v, name, &value, &error);
> > - if (error) {
> > - error_propagate(errp, error);
> > - return;
> > - }
> > - cpu->apic_id = value;
> > -}
> > -
> > /* Generic getter for "feature-words" and "filtered-features" properties */
> > static void x86_cpu_get_feature_words(Object *obj, Visitor *v,
> > const char *name, void *opaque,
> > @@ -3127,9 +3096,6 @@ static void x86_cpu_initfn(Object *obj)
> > object_property_add(obj, "tsc-frequency", "int",
> > x86_cpuid_get_tsc_freq,
> > x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
> > - object_property_add(obj, "apic-id", "int",
> > - x86_cpuid_get_apic_id,
> > - x86_cpuid_set_apic_id, NULL, NULL, NULL);
> > object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
> > x86_cpu_get_feature_words,
> > NULL, NULL, (void *)env->features, NULL);
> > @@ -3139,11 +3105,6 @@ static void x86_cpu_initfn(Object *obj)
> >
> > cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
> >
> > -#ifndef CONFIG_USER_ONLY
> > - /* Any code creating new X86CPU objects have to set apic-id explicitly */
> > - cpu->apic_id = UNASSIGNED_APIC_ID;
> > -#endif
> > -
> > for (w = 0; w < FEATURE_WORDS; w++) {
> > int bitnr;
> >
> > @@ -3200,6 +3161,12 @@ static bool x86_cpu_has_work(CPUState *cs)
> > }
> >
> > static Property x86_cpu_properties[] = {
> > +#ifdef CONFIG_USER_ONLY
> > + /* apic_id = 0 by default for *-user, see commit 9886e834 */
> > + DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, 0),
> > +#else
> > + DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, UNASSIGNED_APIC_ID),
> > +#endif
>
> Suggestion for a follow-up patch: setting the default to
> UNASSIGNED_APIC_ID unconditionally, and just adding this to
> x86_cpu_realizefn().
>
> #ifdef CONFIG_USER_ONLY
> if (cpu->apic_id == UNASSIGNED_APIC_ID) {
> cpu->apic_id = 0;
> }
> #endif
Putting default along with property definition seemed cleaner to me,
considering that we want do similar thing for socket/core/thread-ids
it still seems a better way.
BTW:
there is a v2 on list already, in case you missed it.
[PATCH v2 00/18] pc: add CPU hot-add/hot-remove with device_add/device_del
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PATCH 05/11] target-i386: cpu: replace custom apic-id setter/getter with static property
2016-06-28 6:43 ` Igor Mammedov
@ 2016-06-28 13:35 ` Eduardo Habkost
0 siblings, 0 replies; 27+ messages in thread
From: Eduardo Habkost @ 2016-06-28 13:35 UTC (permalink / raw)
To: Igor Mammedov
Cc: qemu-devel, pbonzini, rth, mst, armbru, eduardo.otubo, zhugh.fnst,
eblake
On Tue, Jun 28, 2016 at 08:43:59AM +0200, Igor Mammedov wrote:
> On Mon, 27 Jun 2016 14:55:24 -0300
> Eduardo Habkost <ehabkost@redhat.com> wrote:
>
> > On Thu, Jun 23, 2016 at 04:54:23PM +0200, Igor Mammedov wrote:
> > > custom apic-id setter/getter doesn't do any property specific
> > > checks anymorer, so clean it up and use more compact static
> > > property DEFINE_PROP_UINT32 instead.
> > >
> > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > ---
> > > target-i386/cpu.c | 45 ++++++---------------------------------------
> > > 1 file changed, 6 insertions(+), 39 deletions(-)
> > >
> > > diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> > > index 9511474..9294b3d 100644
> > > --- a/target-i386/cpu.c
> > > +++ b/target-i386/cpu.c
> > > @@ -1824,37 +1824,6 @@ static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, const char *name,
> > > cpu->env.tsc_khz = cpu->env.user_tsc_khz = value / 1000;
> > > }
> > >
> > > -static void x86_cpuid_get_apic_id(Object *obj, Visitor *v, const char *name,
> > > - void *opaque, Error **errp)
> > > -{
> > > - X86CPU *cpu = X86_CPU(obj);
> > > - int64_t value = cpu->apic_id;
> > > -
> > > - visit_type_int(v, name, &value, errp);
> > > -}
> > > -
> > > -static void x86_cpuid_set_apic_id(Object *obj, Visitor *v, const char *name,
> > > - void *opaque, Error **errp)
> > > -{
> > > - X86CPU *cpu = X86_CPU(obj);
> > > - DeviceState *dev = DEVICE(obj);
> > > - Error *error = NULL;
> > > - int64_t value;
> > > -
> > > - if (dev->realized) {
> > > - error_setg(errp, "Attempt to set property '%s' on '%s' after "
> > > - "it was realized", name, object_get_typename(obj));
> > > - return;
> > > - }
> > > -
> > > - visit_type_int(v, name, &value, &error);
> > > - if (error) {
> > > - error_propagate(errp, error);
> > > - return;
> > > - }
> > > - cpu->apic_id = value;
> > > -}
> > > -
> > > /* Generic getter for "feature-words" and "filtered-features" properties */
> > > static void x86_cpu_get_feature_words(Object *obj, Visitor *v,
> > > const char *name, void *opaque,
> > > @@ -3127,9 +3096,6 @@ static void x86_cpu_initfn(Object *obj)
> > > object_property_add(obj, "tsc-frequency", "int",
> > > x86_cpuid_get_tsc_freq,
> > > x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
> > > - object_property_add(obj, "apic-id", "int",
> > > - x86_cpuid_get_apic_id,
> > > - x86_cpuid_set_apic_id, NULL, NULL, NULL);
> > > object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
> > > x86_cpu_get_feature_words,
> > > NULL, NULL, (void *)env->features, NULL);
> > > @@ -3139,11 +3105,6 @@ static void x86_cpu_initfn(Object *obj)
> > >
> > > cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
> > >
> > > -#ifndef CONFIG_USER_ONLY
> > > - /* Any code creating new X86CPU objects have to set apic-id explicitly */
> > > - cpu->apic_id = UNASSIGNED_APIC_ID;
> > > -#endif
> > > -
> > > for (w = 0; w < FEATURE_WORDS; w++) {
> > > int bitnr;
> > >
> > > @@ -3200,6 +3161,12 @@ static bool x86_cpu_has_work(CPUState *cs)
> > > }
> > >
> > > static Property x86_cpu_properties[] = {
> > > +#ifdef CONFIG_USER_ONLY
> > > + /* apic_id = 0 by default for *-user, see commit 9886e834 */
> > > + DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, 0),
> > > +#else
> > > + DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, UNASSIGNED_APIC_ID),
> > > +#endif
> >
> > Suggestion for a follow-up patch: setting the default to
> > UNASSIGNED_APIC_ID unconditionally, and just adding this to
> > x86_cpu_realizefn().
> >
> > #ifdef CONFIG_USER_ONLY
> > if (cpu->apic_id == UNASSIGNED_APIC_ID) {
> > cpu->apic_id = 0;
> > }
> > #endif
> Putting default along with property definition seemed cleaner to me,
> considering that we want do similar thing for socket/core/thread-ids
> it still seems a better way.
Agreed that consistency is more important.
It bothers me that we don't have a better mechanism to declare
different defaults depending on CONFIG_USER_ONLY, but that's
something to be discussed later.
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
--
Eduardo
^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2016-06-28 17:14 UTC | newest]
Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-06-23 14:54 [Qemu-devel] [PATCH 00/11] pc: allow to use -device/device_add for CPUs Igor Mammedov
2016-06-23 14:54 ` [Qemu-devel] [PATCH 01/11] target-i386: cpu: use uint32_t for X86CPU.apic_id Igor Mammedov
2016-06-23 14:54 ` [Qemu-devel] [PATCH 02/11] pc: add x86_topo_ids_from_apicid() Igor Mammedov
2016-06-23 14:54 ` [Qemu-devel] [PATCH 03/11] pc: extract CPU lookup into a separate function Igor Mammedov
2016-06-23 17:32 ` Eduardo Habkost
2016-06-23 17:41 ` Igor Mammedov
2016-06-23 14:54 ` [Qemu-devel] [PATCH 04/11] pc: cpu: consolidate apic-id validity checks in pc_cpu_pre_plug() Igor Mammedov
2016-06-23 14:54 ` [Qemu-devel] [PATCH 05/11] target-i386: cpu: replace custom apic-id setter/getter with static property Igor Mammedov
2016-06-27 17:55 ` Eduardo Habkost
2016-06-28 6:43 ` Igor Mammedov
2016-06-28 13:35 ` Eduardo Habkost
2016-06-23 14:54 ` [Qemu-devel] [PATCH 06/11] target-i386: add socket/core/thread properties to X86CPU Igor Mammedov
2016-06-23 17:44 ` Eduardo Habkost
2016-06-23 19:18 ` Igor Mammedov
2016-06-23 20:18 ` Eduardo Habkost
2016-06-23 20:46 ` Igor Mammedov
2016-06-23 21:43 ` Eduardo Habkost
2016-06-24 5:23 ` Igor Mammedov
2016-06-23 14:54 ` [Qemu-devel] [PATCH 07/11] pc: set APIC ID based on socket/core/thread ids if it's not been set yet Igor Mammedov
2016-06-23 17:19 ` Eduardo Habkost
2016-06-23 17:48 ` Igor Mammedov
2016-06-23 19:27 ` Eduardo Habkost
2016-06-23 20:50 ` Igor Mammedov
2016-06-23 14:54 ` [Qemu-devel] [PATCH 08/11] pc: implement query-hotpluggable-cpus callback Igor Mammedov
2016-06-23 14:54 ` [Qemu-devel] [PATCH 09/11] pc: register created initial and hotpluged CPUs in one place pc_cpu_plug() Igor Mammedov
2016-06-23 14:54 ` [Qemu-devel] [PATCH 10/11] pc: delay setting number of boot CPUs to machine_done time Igor Mammedov
2016-06-23 14:54 ` [Qemu-devel] [PATCH 11/11] pc: cpu: allow device_add to be used with x86 cpu Igor Mammedov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).