On Wed, May 10, 2017 at 01:29:50PM +0200, Igor Mammedov wrote: [...] > diff --git a/hw/core/machine.c b/hw/core/machine.c > index 2482c63..420c8c4 100644 > --- a/hw/core/machine.c > +++ b/hw/core/machine.c > @@ -389,6 +389,102 @@ HotpluggableCPUList > *machine_query_hotpluggable_cpus(MachineState *machine) [...] > +void machine_set_cpu_numa_node(MachineState *machine, > + const CpuInstanceProperties *props, Error > **errp) > +{ [...] > + /* force board to initialize possible_cpus if it hasn't been done yet */ > + mc->possible_cpu_arch_ids(machine); [...] > diff --git a/numa.c b/numa.c > index 7182481..7db5dde 100644 > --- a/numa.c > +++ b/numa.c > @@ -170,6 +170,7 @@ static void parse_numa_node(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 ")" > @@ -178,6 +179,10 @@ static void parse_numa_node(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);
This triggers a call to possible_cpu_arch_ids() before nb_numa_nodes is set to the actual number of NUMA nodes in the machine, breaking the "node_id = ... % nb_numa_nodes" initialization logic in pc, virt, and spapr. The initialization ordering between possible_cpus and NUMA data structures looks very subtle and fragile. I still don't see an obvious way to untangle that. I suggest moving the default-NUMA-mapping code to a separate machine class method, instead of relying on possible_cpu_arch_ids() to initialize node_id. -- Eduardo