Introduce machine_set_cpu_numa_node() helper that stores
node mapping for CPU in MachineState::possible_cpus.
CPU and node it belongs to is specified by 'props' argument.
Patch doesn't remove old way of storing mapping in
numa_info[X].node_cpu as removing it at the same time
makes patch rather big. Instead it just mirrors mapping
in possible_cpus and follow up per target patches will
switch to possible_cpus and numa_info[X].node_cpu will
be removed once there isn't any users left.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
include/hw/boards.h | 2 ++
hw/core/machine.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++
numa.c | 8 +++++++
3 files changed, 78 insertions(+)
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 1dd0fde..40f30f1 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -42,6 +42,8 @@ bool machine_dump_guest_core(MachineState *machine);
bool machine_mem_merge(MachineState *machine);
void machine_register_compat_props(MachineState *machine);
HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine);
+void machine_set_cpu_numa_node(MachineState *machine,
+ CpuInstanceProperties *props, Error **errp);
/**
* CPUArchId:
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 0d92672..6ff0b45 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -388,6 +388,74 @@ HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine)
return head;
}
+void machine_set_cpu_numa_node(MachineState *machine,
+ CpuInstanceProperties *props, Error **errp)
+{
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
+ bool match = false;
+ int i;
+
+ if (!mc->possible_cpu_arch_ids) {
+ error_setg(errp, "mapping of CPUs to NUMA node is not supported");
+ return;
+ }
+
+ /* force board to initialize possible_cpus if it hasn't been done yet */
+ mc->possible_cpu_arch_ids(machine);
+
+ for (i = 0; i < machine->possible_cpus->len; i++) {
+ CPUArchId *slot = &machine->possible_cpus->cpus[i];
+
+ /* reject unsupported by board properties */
+ if (props->has_thread_id && !slot->props.has_thread_id) {
+ error_setg(errp, "thread-id is not supported");
+ return;
+ }
+
+ if (props->has_core_id && !slot->props.has_core_id) {
+ error_setg(errp, "core-id is not supported");
+ return;
+ }
+
+ if (props->has_socket_id && !slot->props.has_socket_id) {
+ error_setg(errp, "socket-id is not supported");
+ return;
+ }
+
+ /* skip slots with explicit mismatch */
+ if (props->has_thread_id && props->thread_id != slot->props.thread_id) {
+ continue;
+ }
+
+ if (props->has_core_id && props->core_id != slot->props.core_id) {
+ continue;
+ }
+
+ if (props->has_socket_id && props->socket_id != slot->props.socket_id) {
+ continue;
+ }
+
+ /* reject assignment if slot is already assigned, for compatibility
+ * of legacy cpu_index mapping with SPAPR core based mapping do not
+ * error out if cpu thread and matched core have the same node-id */
+ if (slot->props.has_node_id &&
+ slot->props.node_id != props->node_id) {
+ error_setg(errp, "CPU is already assigned to node-id: %" PRId64,
+ slot->props.node_id);
+ return;
+ }
+
+ /* assign slot to node as it's matched '-numa cpu' key */
+ match = true;
+ slot->props.node_id = props->node_id;
+ slot->props.has_node_id = props->has_node_id;
+ }
+
+ if (!match) {
+ error_setg(errp, "no match found");
+ }
+}
+
static void machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
diff --git a/numa.c b/numa.c
index 24c596d..44057f1 100644
--- a/numa.c
+++ b/numa.c
@@ -169,6 +169,7 @@ static void numa_node_parse(MachineState *ms, NumaNodeOptions *node,
exit(1);
}
for (cpus = node->cpus; cpus; cpus = cpus->next) {
+ CpuInstanceProperties props;
if (cpus->value >= max_cpus) {
error_setg(errp,
"CPU index (%" PRIu16 ")"
@@ -177,6 +178,10 @@ static void numa_node_parse(MachineState *ms, NumaNodeOptions *node,
return;
}
bitmap_set(numa_info[nodenr].node_cpu, cpus->value, 1);
+ props = mc->cpu_index_to_instance_props(ms, cpus->value);
+ props.node_id = nodenr;
+ props.has_node_id = true;
+ machine_set_cpu_numa_node(ms, &props, &error_fatal);
}
if (node->has_mem && node->has_memdev) {
@@ -393,9 +398,12 @@ void parse_numa_opts(MachineState *ms)
if (i == nb_numa_nodes) {
for (i = 0; i < max_cpus; i++) {
CpuInstanceProperties props;
+ /* fetch default mapping from board and enable it */
props = mc->cpu_index_to_instance_props(ms, i);
+ props.has_node_id = true;
set_bit(i, numa_info[props.node_id].node_cpu);
+ machine_set_cpu_numa_node(ms, &props, &error_fatal);
}
}
--
2.7.4
On Wed, Mar 22, 2017 at 02:32:35PM +0100, Igor Mammedov wrote:
> Introduce machine_set_cpu_numa_node() helper that stores
> node mapping for CPU in MachineState::possible_cpus.
> CPU and node it belongs to is specified by 'props' argument.
>
> Patch doesn't remove old way of storing mapping in
> numa_info[X].node_cpu as removing it at the same time
> makes patch rather big. Instead it just mirrors mapping
> in possible_cpus and follow up per target patches will
> switch to possible_cpus and numa_info[X].node_cpu will
> be removed once there isn't any users left.
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> ---
> include/hw/boards.h | 2 ++
> hw/core/machine.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> numa.c | 8 +++++++
> 3 files changed, 78 insertions(+)
>
> diff --git a/include/hw/boards.h b/include/hw/boards.h
> index 1dd0fde..40f30f1 100644
> --- a/include/hw/boards.h
> +++ b/include/hw/boards.h
> @@ -42,6 +42,8 @@ bool machine_dump_guest_core(MachineState *machine);
> bool machine_mem_merge(MachineState *machine);
> void machine_register_compat_props(MachineState *machine);
> HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine);
> +void machine_set_cpu_numa_node(MachineState *machine,
> + CpuInstanceProperties *props, Error **errp);
>
> /**
> * CPUArchId:
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 0d92672..6ff0b45 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -388,6 +388,74 @@ HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine)
> return head;
> }
>
> +void machine_set_cpu_numa_node(MachineState *machine,
> + CpuInstanceProperties *props, Error **errp)
> +{
> + MachineClass *mc = MACHINE_GET_CLASS(machine);
> + bool match = false;
> + int i;
> +
> + if (!mc->possible_cpu_arch_ids) {
> + error_setg(errp, "mapping of CPUs to NUMA node is not supported");
> + return;
> + }
> +
> + /* force board to initialize possible_cpus if it hasn't been done yet */
> + mc->possible_cpu_arch_ids(machine);
> +
> + for (i = 0; i < machine->possible_cpus->len; i++) {
> + CPUArchId *slot = &machine->possible_cpus->cpus[i];
> +
> + /* reject unsupported by board properties */
> + if (props->has_thread_id && !slot->props.has_thread_id) {
> + error_setg(errp, "thread-id is not supported");
> + return;
> + }
> +
> + if (props->has_core_id && !slot->props.has_core_id) {
> + error_setg(errp, "core-id is not supported");
> + return;
> + }
> +
> + if (props->has_socket_id && !slot->props.has_socket_id) {
> + error_setg(errp, "socket-id is not supported");
> + return;
> + }
> +
> + /* skip slots with explicit mismatch */
> + if (props->has_thread_id && props->thread_id != slot->props.thread_id) {
> + continue;
> + }
> +
> + if (props->has_core_id && props->core_id != slot->props.core_id) {
> + continue;
> + }
> +
> + if (props->has_socket_id && props->socket_id != slot->props.socket_id) {
> + continue;
> + }
> +
> + /* reject assignment if slot is already assigned, for compatibility
> + * of legacy cpu_index mapping with SPAPR core based mapping do not
> + * error out if cpu thread and matched core have the same node-id */
> + if (slot->props.has_node_id &&
> + slot->props.node_id != props->node_id) {
> + error_setg(errp, "CPU is already assigned to node-id: %" PRId64,
> + slot->props.node_id);
> + return;
> + }
> +
> + /* assign slot to node as it's matched '-numa cpu' key */
> + match = true;
> + slot->props.node_id = props->node_id;
> + slot->props.has_node_id = props->has_node_id;
> + }
> +
> + if (!match) {
> + error_setg(errp, "no match found");
> + }
> +}
> +
> static void machine_class_init(ObjectClass *oc, void *data)
> {
> MachineClass *mc = MACHINE_CLASS(oc);
> diff --git a/numa.c b/numa.c
> index 24c596d..44057f1 100644
> --- a/numa.c
> +++ b/numa.c
> @@ -169,6 +169,7 @@ static void numa_node_parse(MachineState *ms, NumaNodeOptions *node,
> exit(1);
> }
> for (cpus = node->cpus; cpus; cpus = cpus->next) {
> + CpuInstanceProperties props;
> if (cpus->value >= max_cpus) {
> error_setg(errp,
> "CPU index (%" PRIu16 ")"
> @@ -177,6 +178,10 @@ static void numa_node_parse(MachineState *ms, NumaNodeOptions *node,
> return;
> }
> bitmap_set(numa_info[nodenr].node_cpu, cpus->value, 1);
> + props = mc->cpu_index_to_instance_props(ms, cpus->value);
> + props.node_id = nodenr;
> + props.has_node_id = true;
> + machine_set_cpu_numa_node(ms, &props, &error_fatal);
> }
>
> if (node->has_mem && node->has_memdev) {
> @@ -393,9 +398,12 @@ void parse_numa_opts(MachineState *ms)
> if (i == nb_numa_nodes) {
> for (i = 0; i < max_cpus; i++) {
> CpuInstanceProperties props;
> + /* fetch default mapping from board and enable it */
> props = mc->cpu_index_to_instance_props(ms, i);
> + props.has_node_id = true;
>
> set_bit(i, numa_info[props.node_id].node_cpu);
> + machine_set_cpu_numa_node(ms, &props, &error_fatal);
> }
> }
>
--
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
On Wed, Mar 22, 2017 at 02:32:35PM +0100, Igor Mammedov wrote:
> Introduce machine_set_cpu_numa_node() helper that stores
> node mapping for CPU in MachineState::possible_cpus.
> CPU and node it belongs to is specified by 'props' argument.
>
> Patch doesn't remove old way of storing mapping in
> numa_info[X].node_cpu as removing it at the same time
> makes patch rather big. Instead it just mirrors mapping
> in possible_cpus and follow up per target patches will
> switch to possible_cpus and numa_info[X].node_cpu will
> be removed once there isn't any users left.
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
So, this patch is the one that makes "-numa" and "-numa cpu"
affect query-hotpluggable-cpus output.
Before this patch:
$ qemu-system-x86_64 -smp 2 -m 2G -numa node -numa node -numa node -numa node
[run qmp-shell]
(QEMU) query-hotpluggable-cpus
{
"return": [
{
"qom-path": "/machine/unattached/device[2]",
"type": "qemu64-x86_64-cpu",
"vcpus-count": 1,
"props": {
"socket-id": 1,
"core-id": 0,
"thread-id": 0
}
},
{
"qom-path": "/machine/unattached/device[0]",
"type": "qemu64-x86_64-cpu",
"vcpus-count": 1,
"props": {
"socket-id": 0,
"core-id": 0,
"thread-id": 0
}
}
]
}
After this patch:
$ qemu-system-x86_64 -smp 2 -m 2G -numa node -numa node -numa node -numa node
[run qmp-shell]
(QEMU) query-hotpluggable-cpus
{
"return": [
{
"qom-path": "/machine/unattached/device[2]",
"type": "qemu64-x86_64-cpu",
"vcpus-count": 1,
"props": {
"socket-id": 1,
"node-id": 1,
"core-id": 0,
"thread-id": 0
}
},
{
"qom-path": "/machine/unattached/device[0]",
"type": "qemu64-x86_64-cpu",
"vcpus-count": 1,
"props": {
"socket-id": 0,
"node-id": 0,
"core-id": 0,
"thread-id": 0
}
}
]
}
As noted in another message, I am not sure we really should make
"-numa" affect query-hotpluggable-cpus output unconditionally (I
believe we shouldn't). But we do, we need to document this very
clearly.
> ---
> include/hw/boards.h | 2 ++
> hw/core/machine.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> numa.c | 8 +++++++
> 3 files changed, 78 insertions(+)
>
> diff --git a/include/hw/boards.h b/include/hw/boards.h
> index 1dd0fde..40f30f1 100644
> --- a/include/hw/boards.h
> +++ b/include/hw/boards.h
> @@ -42,6 +42,8 @@ bool machine_dump_guest_core(MachineState *machine);
> bool machine_mem_merge(MachineState *machine);
> void machine_register_compat_props(MachineState *machine);
> HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine);
> +void machine_set_cpu_numa_node(MachineState *machine,
> + CpuInstanceProperties *props, Error **errp);
>
> /**
> * CPUArchId:
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 0d92672..6ff0b45 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -388,6 +388,74 @@ HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine)
> return head;
> }
>
> +void machine_set_cpu_numa_node(MachineState *machine,
> + CpuInstanceProperties *props, Error **errp)
> +{
> + MachineClass *mc = MACHINE_GET_CLASS(machine);
> + bool match = false;
> + int i;
> +
> + if (!mc->possible_cpu_arch_ids) {
> + error_setg(errp, "mapping of CPUs to NUMA node is not supported");
> + return;
> + }
> +
> + /* force board to initialize possible_cpus if it hasn't been done yet */
> + mc->possible_cpu_arch_ids(machine);
> +
> + for (i = 0; i < machine->possible_cpus->len; i++) {
> + CPUArchId *slot = &machine->possible_cpus->cpus[i];
> +
> + /* reject unsupported by board properties */
> + if (props->has_thread_id && !slot->props.has_thread_id) {
> + error_setg(errp, "thread-id is not supported");
> + return;
> + }
> +
> + if (props->has_core_id && !slot->props.has_core_id) {
> + error_setg(errp, "core-id is not supported");
> + return;
> + }
> +
> + if (props->has_socket_id && !slot->props.has_socket_id) {
> + error_setg(errp, "socket-id is not supported");
> + return;
> + }
> +
> + /* skip slots with explicit mismatch */
> + if (props->has_thread_id && props->thread_id != slot->props.thread_id) {
> + continue;
> + }
> +
> + if (props->has_core_id && props->core_id != slot->props.core_id) {
> + continue;
> + }
> +
> + if (props->has_socket_id && props->socket_id != slot->props.socket_id) {
> + continue;
> + }
> +
> + /* reject assignment if slot is already assigned, for compatibility
> + * of legacy cpu_index mapping with SPAPR core based mapping do not
> + * error out if cpu thread and matched core have the same node-id */
> + if (slot->props.has_node_id &&
> + slot->props.node_id != props->node_id) {
> + error_setg(errp, "CPU is already assigned to node-id: %" PRId64,
> + slot->props.node_id);
> + return;
> + }
> +
> + /* assign slot to node as it's matched '-numa cpu' key */
> + match = true;
> + slot->props.node_id = props->node_id;
> + slot->props.has_node_id = props->has_node_id;
> + }
> +
> + if (!match) {
> + error_setg(errp, "no match found");
> + }
> +}
> +
> static void machine_class_init(ObjectClass *oc, void *data)
> {
> MachineClass *mc = MACHINE_CLASS(oc);
> diff --git a/numa.c b/numa.c
> index 24c596d..44057f1 100644
> --- a/numa.c
> +++ b/numa.c
> @@ -169,6 +169,7 @@ static void numa_node_parse(MachineState *ms, NumaNodeOptions *node,
> exit(1);
> }
> for (cpus = node->cpus; cpus; cpus = cpus->next) {
> + CpuInstanceProperties props;
> if (cpus->value >= max_cpus) {
> error_setg(errp,
> "CPU index (%" PRIu16 ")"
> @@ -177,6 +178,10 @@ static void numa_node_parse(MachineState *ms, NumaNodeOptions *node,
> return;
> }
> bitmap_set(numa_info[nodenr].node_cpu, cpus->value, 1);
> + props = mc->cpu_index_to_instance_props(ms, cpus->value);
> + props.node_id = nodenr;
> + props.has_node_id = true;
> + machine_set_cpu_numa_node(ms, &props, &error_fatal);
> }
>
> if (node->has_mem && node->has_memdev) {
> @@ -393,9 +398,12 @@ void parse_numa_opts(MachineState *ms)
> if (i == nb_numa_nodes) {
> for (i = 0; i < max_cpus; i++) {
> CpuInstanceProperties props;
> + /* fetch default mapping from board and enable it */
> props = mc->cpu_index_to_instance_props(ms, i);
> + props.has_node_id = true;
>
> set_bit(i, numa_info[props.node_id].node_cpu);
> + machine_set_cpu_numa_node(ms, &props, &error_fatal);
> }
> }
>
> --
> 2.7.4
>
>
--
Eduardo
On Wed, 12 Apr 2017 18:15:29 -0300 Eduardo Habkost <ehabkost@redhat.com> wrote: > On Wed, Mar 22, 2017 at 02:32:35PM +0100, Igor Mammedov wrote: > > Introduce machine_set_cpu_numa_node() helper that stores > > node mapping for CPU in MachineState::possible_cpus. > > CPU and node it belongs to is specified by 'props' argument. > > > > Patch doesn't remove old way of storing mapping in > > numa_info[X].node_cpu as removing it at the same time > > makes patch rather big. Instead it just mirrors mapping > > in possible_cpus and follow up per target patches will > > switch to possible_cpus and numa_info[X].node_cpu will > > be removed once there isn't any users left. > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com> > > So, this patch is the one that makes "-numa" and "-numa cpu" > affect query-hotpluggable-cpus output. that was intent behind series. [...] > As noted in another message, I am not sure we really should make > "-numa" affect query-hotpluggable-cpus output unconditionally (I > believe we shouldn't). But we do, we need to document this very > clearly. What place would you suggest to document this at? [...]
On Wed, Apr 19, 2017 at 11:52:45AM +0200, Igor Mammedov wrote: > On Wed, 12 Apr 2017 18:15:29 -0300 > Eduardo Habkost <ehabkost@redhat.com> wrote: > > > On Wed, Mar 22, 2017 at 02:32:35PM +0100, Igor Mammedov wrote: > > > Introduce machine_set_cpu_numa_node() helper that stores > > > node mapping for CPU in MachineState::possible_cpus. > > > CPU and node it belongs to is specified by 'props' argument. > > > > > > Patch doesn't remove old way of storing mapping in > > > numa_info[X].node_cpu as removing it at the same time > > > makes patch rather big. Instead it just mirrors mapping > > > in possible_cpus and follow up per target patches will > > > switch to possible_cpus and numa_info[X].node_cpu will > > > be removed once there isn't any users left. > > > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com> > > > > So, this patch is the one that makes "-numa" and "-numa cpu" > > affect query-hotpluggable-cpus output. > that was intent behind series. > > [...] > > As noted in another message, I am not sure we really should make > > "-numa" affect query-hotpluggable-cpus output unconditionally (I > > believe we shouldn't). But we do, we need to document this very > > clearly. > What place would you suggest to document this at? qemu-options.hx documentation for -numa cpu, NumaCpuOptions docs on qapi-schema, and/or query-hotpluggable-cpus docs on qapi-schema. -- Eduardo
On Wed, Mar 22, 2017 at 02:32:35PM +0100, Igor Mammedov wrote:
> Introduce machine_set_cpu_numa_node() helper that stores
> node mapping for CPU in MachineState::possible_cpus.
> CPU and node it belongs to is specified by 'props' argument.
>
> Patch doesn't remove old way of storing mapping in
> numa_info[X].node_cpu as removing it at the same time
> makes patch rather big. Instead it just mirrors mapping
> in possible_cpus and follow up per target patches will
> switch to possible_cpus and numa_info[X].node_cpu will
> be removed once there isn't any users left.
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
> include/hw/boards.h | 2 ++
> hw/core/machine.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> numa.c | 8 +++++++
> 3 files changed, 78 insertions(+)
>
> diff --git a/include/hw/boards.h b/include/hw/boards.h
> index 1dd0fde..40f30f1 100644
> --- a/include/hw/boards.h
> +++ b/include/hw/boards.h
> @@ -42,6 +42,8 @@ bool machine_dump_guest_core(MachineState *machine);
> bool machine_mem_merge(MachineState *machine);
> void machine_register_compat_props(MachineState *machine);
> HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine);
> +void machine_set_cpu_numa_node(MachineState *machine,
> + CpuInstanceProperties *props, Error **errp);
>
> /**
> * CPUArchId:
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 0d92672..6ff0b45 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -388,6 +388,74 @@ HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine)
> return head;
> }
>
> +void machine_set_cpu_numa_node(MachineState *machine,
> + CpuInstanceProperties *props, Error **errp)
If you change this to:
void cpu_slot_set_numa_node(CPUArchId *slot, uint64_t node_id,
Error **errp);
and move the CPU slot lookup code from machine_set_cpu_numa_node()
to a helper:
CPUArchId *machine_get_cpu_slot(MachineState *machine,
CpuInstanceProperties *props, Error **errp);
and change cpu_index_to_cpu_instance_props to return CPUArchId:
CPUArchId *cpu_index_to_cpu_slot(MachineState *machine, int cpu_index);
We could simply have this on "-numa cpu" code:
slot = machine_get_cpu_slot(machine, props);
cpu_slot_set_numa_node(slot, node_id);
and this on the legacy "-numa node,cpu=..." code:
slot = mc->cpu_index_to_cpu_slot(machine, i);
cpu_slot_set_numa_node(slot, node_id);
I believe we will be able to reuse machine_get_cpu_slot() to
replace pc_find_cpu_slot() and spapr_find_cpu_slot() later.
(I also suggest renaming "CPUArchId" and "possible CPUs" to
"CPUSlot" and "CPU slots" in the code and comments. This would
help people reviewing the code, but it can be done later if you
prefer.)
[...]
> @@ -177,6 +178,10 @@ static void numa_node_parse(MachineState *ms, NumaNodeOptions *node,
> return;
> }
> bitmap_set(numa_info[nodenr].node_cpu, cpus->value, 1);
> + props = mc->cpu_index_to_instance_props(ms, cpus->value);
> + props.node_id = nodenr;
> + props.has_node_id = true;
> + machine_set_cpu_numa_node(ms, &props, &error_fatal);
> }
>
> if (node->has_mem && node->has_memdev) {
> @@ -393,9 +398,12 @@ void parse_numa_opts(MachineState *ms)
> if (i == nb_numa_nodes) {
> for (i = 0; i < max_cpus; i++) {
> CpuInstanceProperties props;
> + /* fetch default mapping from board and enable it */
> props = mc->cpu_index_to_instance_props(ms, i);
> + props.has_node_id = true;
>
> set_bit(i, numa_info[props.node_id].node_cpu);
> + machine_set_cpu_numa_node(ms, &props, &error_fatal);
> }
> }
>
> --
> 2.7.4
>
>
--
Eduardo
On Thu, 13 Apr 2017 10:58:05 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:
> On Wed, Mar 22, 2017 at 02:32:35PM +0100, Igor Mammedov wrote:
> > Introduce machine_set_cpu_numa_node() helper that stores
> > node mapping for CPU in MachineState::possible_cpus.
> > CPU and node it belongs to is specified by 'props' argument.
> >
> > Patch doesn't remove old way of storing mapping in
> > numa_info[X].node_cpu as removing it at the same time
> > makes patch rather big. Instead it just mirrors mapping
> > in possible_cpus and follow up per target patches will
> > switch to possible_cpus and numa_info[X].node_cpu will
> > be removed once there isn't any users left.
> >
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> > include/hw/boards.h | 2 ++
> > hw/core/machine.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> > numa.c | 8 +++++++
> > 3 files changed, 78 insertions(+)
> >
> > diff --git a/include/hw/boards.h b/include/hw/boards.h
> > index 1dd0fde..40f30f1 100644
> > --- a/include/hw/boards.h
> > +++ b/include/hw/boards.h
> > @@ -42,6 +42,8 @@ bool machine_dump_guest_core(MachineState *machine);
> > bool machine_mem_merge(MachineState *machine);
> > void machine_register_compat_props(MachineState *machine);
> > HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine);
> > +void machine_set_cpu_numa_node(MachineState *machine,
> > + CpuInstanceProperties *props, Error **errp);
> >
> > /**
> > * CPUArchId:
> > diff --git a/hw/core/machine.c b/hw/core/machine.c
> > index 0d92672..6ff0b45 100644
> > --- a/hw/core/machine.c
> > +++ b/hw/core/machine.c
> > @@ -388,6 +388,74 @@ HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine)
> > return head;
> > }
> >
> > +void machine_set_cpu_numa_node(MachineState *machine,
> > + CpuInstanceProperties *props, Error **errp)
>
> If you change this to:
>
> void cpu_slot_set_numa_node(CPUArchId *slot, uint64_t node_id,
> Error **errp);
>
> and move the CPU slot lookup code from machine_set_cpu_numa_node()
> to a helper:
>
> CPUArchId *machine_get_cpu_slot(MachineState *machine,
> CpuInstanceProperties *props, Error **errp);
it would work in case of exact 1:1 lookup, but Paolo asked for
wildcard support (i.e. -numa cpu,node-id=x,socket-id=y should set
mapping for all cpus in socket y).
So I'd prefer to keep machine_set_cpu_numa_node() as is,
with it series splits nicely in clean and bisectable patches
without breaking anything in the middle.
> and change cpu_index_to_cpu_instance_props to return CPUArchId:
>
> CPUArchId *cpu_index_to_cpu_slot(MachineState *machine, int cpu_index);
>
> We could simply have this on "-numa cpu" code:
>
> slot = machine_get_cpu_slot(machine, props);
> cpu_slot_set_numa_node(slot, node_id);
>
> and this on the legacy "-numa node,cpu=..." code:
>
> slot = mc->cpu_index_to_cpu_slot(machine, i);
> cpu_slot_set_numa_node(slot, node_id);
>
> I believe we will be able to reuse machine_get_cpu_slot() to
> replace pc_find_cpu_slot() and spapr_find_cpu_slot() later.
As I already replied to David, xxx_find_cpu_slot() possibly might
be generalized but I'd like to postpone it until ARM topology
is materialized and merged.
Another reason I'd like to postpone generalization is that
xxx_find_cpu_slot() could be optimized in target specific way
replacing CPU lookup in array with computational expression.
It will make lookup O(1) function and it could be used as
a better replacement for qemu_get_cpu()/cpu_exists() but
I haven't looked into this yet.
> (I also suggest renaming "CPUArchId" and "possible CPUs" to
> "CPUSlot" and "CPU slots" in the code and comments. This would
> help people reviewing the code, but it can be done later if you
> prefer.)
I'm fine with changing CPUArchId to CPUSlot but I'd leave
"possible CPUs" as is, since it precisely describes what it is,
"CPU slots" is too ambiguous.
>
> [...]
> > @@ -177,6 +178,10 @@ static void numa_node_parse(MachineState *ms, NumaNodeOptions *node,
> > return;
> > }
> > bitmap_set(numa_info[nodenr].node_cpu, cpus->value, 1);
> > + props = mc->cpu_index_to_instance_props(ms, cpus->value);
> > + props.node_id = nodenr;
> > + props.has_node_id = true;
> > + machine_set_cpu_numa_node(ms, &props, &error_fatal);
> > }
> >
> > if (node->has_mem && node->has_memdev) {
> > @@ -393,9 +398,12 @@ void parse_numa_opts(MachineState *ms)
> > if (i == nb_numa_nodes) {
> > for (i = 0; i < max_cpus; i++) {
> > CpuInstanceProperties props;
> > + /* fetch default mapping from board and enable it */
> > props = mc->cpu_index_to_instance_props(ms, i);
> > + props.has_node_id = true;
> >
> > set_bit(i, numa_info[props.node_id].node_cpu);
> > + machine_set_cpu_numa_node(ms, &props, &error_fatal);
> > }
> > }
> >
> > --
> > 2.7.4
> >
> >
>
Just noticed I didn't reply to this yet: On Wed, Apr 19, 2017 at 11:31:05AM +0200, Igor Mammedov wrote: > On Thu, 13 Apr 2017 10:58:05 -0300 > Eduardo Habkost <ehabkost@redhat.com> wrote: > > > On Wed, Mar 22, 2017 at 02:32:35PM +0100, Igor Mammedov wrote: > > > Introduce machine_set_cpu_numa_node() helper that stores > > > node mapping for CPU in MachineState::possible_cpus. > > > CPU and node it belongs to is specified by 'props' argument. > > > > > > Patch doesn't remove old way of storing mapping in > > > numa_info[X].node_cpu as removing it at the same time > > > makes patch rather big. Instead it just mirrors mapping > > > in possible_cpus and follow up per target patches will > > > switch to possible_cpus and numa_info[X].node_cpu will > > > be removed once there isn't any users left. > > > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com> > > > --- > > > include/hw/boards.h | 2 ++ > > > hw/core/machine.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++ > > > numa.c | 8 +++++++ > > > 3 files changed, 78 insertions(+) > > > > > > diff --git a/include/hw/boards.h b/include/hw/boards.h > > > index 1dd0fde..40f30f1 100644 > > > --- a/include/hw/boards.h > > > +++ b/include/hw/boards.h > > > @@ -42,6 +42,8 @@ bool machine_dump_guest_core(MachineState *machine); > > > bool machine_mem_merge(MachineState *machine); > > > void machine_register_compat_props(MachineState *machine); > > > HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine); > > > +void machine_set_cpu_numa_node(MachineState *machine, > > > + CpuInstanceProperties *props, Error **errp); > > > > > > /** > > > * CPUArchId: > > > diff --git a/hw/core/machine.c b/hw/core/machine.c > > > index 0d92672..6ff0b45 100644 > > > --- a/hw/core/machine.c > > > +++ b/hw/core/machine.c > > > @@ -388,6 +388,74 @@ HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine) > > > return head; > > > } > > > > > > +void machine_set_cpu_numa_node(MachineState *machine, > > > + CpuInstanceProperties *props, Error **errp) > > > > If you change this to: > > > > void cpu_slot_set_numa_node(CPUArchId *slot, uint64_t node_id, > > Error **errp); > > > > and move the CPU slot lookup code from machine_set_cpu_numa_node() > > to a helper: > > > > CPUArchId *machine_get_cpu_slot(MachineState *machine, > > CpuInstanceProperties *props, Error **errp); > it would work in case of exact 1:1 lookup, but Paolo asked for > wildcard support (i.e. -numa cpu,node-id=x,socket-id=y should set > mapping for all cpus in socket y). > So I'd prefer to keep machine_set_cpu_numa_node() as is, > with it series splits nicely in clean and bisectable patches > without breaking anything in the middle. Makes sense to me. And this is also a good reason we won't have a 1:1 mapping from query-hotpluggable-cpus output to -numa cpu input. (So this answers my question about the intent to change query-hotpluggable-cpus output) > > > > and change cpu_index_to_cpu_instance_props to return CPUArchId: > > > > CPUArchId *cpu_index_to_cpu_slot(MachineState *machine, int cpu_index); > > > > We could simply have this on "-numa cpu" code: > > > > slot = machine_get_cpu_slot(machine, props); > > cpu_slot_set_numa_node(slot, node_id); > > > > and this on the legacy "-numa node,cpu=..." code: > > > > slot = mc->cpu_index_to_cpu_slot(machine, i); > > cpu_slot_set_numa_node(slot, node_id); > > > > I believe we will be able to reuse machine_get_cpu_slot() to > > replace pc_find_cpu_slot() and spapr_find_cpu_slot() later. > As I already replied to David, xxx_find_cpu_slot() possibly might > be generalized but I'd like to postpone it until ARM topology > is materialized and merged. OK. > > Another reason I'd like to postpone generalization is that > xxx_find_cpu_slot() could be optimized in target specific way > replacing CPU lookup in array with computational expression. > It will make lookup O(1) function and it could be used as > a better replacement for qemu_get_cpu()/cpu_exists() but > I haven't looked into this yet. I would prefer optimization in generic code to machine-specific code just for optimization. But both approaches are valid, let's see how this evolves. > > > > (I also suggest renaming "CPUArchId" and "possible CPUs" to > > "CPUSlot" and "CPU slots" in the code and comments. This would > > help people reviewing the code, but it can be done later if you > > prefer.) > I'm fine with changing CPUArchId to CPUSlot but I'd leave > "possible CPUs" as is, since it precisely describes what it is, > "CPU slots" is too ambiguous. No problem to me. We can discuss that later, anyway. Thanks! -- Eduardo
© 2016 - 2025 Red Hat, Inc.