diff options
author | Igor Mammedov <imammedo@redhat.com> | 2017-06-01 12:53:28 +0200 |
---|---|---|
committer | Eduardo Habkost <ehabkost@redhat.com> | 2017-09-19 16:51:33 -0300 |
commit | 79e0793614fcd6b5674fa96180b66971c37d1dfd (patch) | |
tree | 6e5ea5fbd24dc2d96fb60c6a200e7ce729d7f1a3 /hw/i386/pc.c | |
parent | ba1ba5cca3962a9cc400c713c736b4fb8db1f38e (diff) |
numa: cpu: calculate/set default node-ids after all -numa CLI options are parsed
Calculating default node-ids for CPUs in possible_cpu_arch_ids()
is rather fragile since defaults calculation uses nb_numa_nodes but
callback might be potentially called early before all -numa CLI
options are parsed, which would lead to cpus assigned only upto
nb_numa_nodes at the time possible_cpu_arch_ids() is called.
Issue was introduced by
(7c88e65 numa: mirror cpu to node mapping in MachineState::possible_cpus)
and for example CLI:
-smp 4 -numa node,cpus=0 -numa node
would set props.node-id in possible_cpus array for every non
explicitly mapped CPU to the first node.
Issue is not visible to guest nor to mgmt interface due to
1) implictly mapped cpus are forced to the first node in
case of partial mapping
2) in case of default mapping possible_cpu_arch_ids() is
called after all -numa options are parsed (resulting
in correct mapping).
However it's fragile to rely on late execution of
possible_cpu_arch_ids(), therefore add machine specific
callback that returns node-id for CPU and use it to calculate/
set defaults at machine_numa_finish_init() time when all -numa
options are parsed.
Reported-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Message-Id: <1496314408-163972-1-git-send-email-imammedo@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Diffstat (limited to 'hw/i386/pc.c')
-rw-r--r-- | hw/i386/pc.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 2247ac0a01..610c65aeab 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -2234,6 +2234,16 @@ pc_cpu_index_to_props(MachineState *ms, unsigned cpu_index) return possible_cpus->cpus[cpu_index].props; } +static int64_t pc_get_default_cpu_node_id(const MachineState *ms, int idx) +{ + X86CPUTopoInfo topo; + + assert(idx < ms->possible_cpus->len); + x86_topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id, + smp_cores, smp_threads, &topo); + return topo.pkg_id % nb_numa_nodes; +} + static const CPUArchIdList *pc_possible_cpu_arch_ids(MachineState *ms) { int i; @@ -2263,15 +2273,6 @@ static const CPUArchIdList *pc_possible_cpu_arch_ids(MachineState *ms) ms->possible_cpus->cpus[i].props.core_id = topo.core_id; ms->possible_cpus->cpus[i].props.has_thread_id = true; ms->possible_cpus->cpus[i].props.thread_id = topo.smt_id; - - /* default distribution of CPUs over NUMA nodes */ - if (nb_numa_nodes) { - /* preset values but do not enable them i.e. 'has_node_id = false', - * numa init code will enable them later if manual mapping wasn't - * present on CLI */ - ms->possible_cpus->cpus[i].props.node_id = - topo.pkg_id % nb_numa_nodes; - } } return ms->possible_cpus; } @@ -2316,6 +2317,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) pcmc->linuxboot_dma_enabled = true; mc->get_hotplug_handler = pc_get_hotpug_handler; mc->cpu_index_to_instance_props = pc_cpu_index_to_props; + mc->get_default_cpu_node_id = pc_get_default_cpu_node_id; mc->possible_cpu_arch_ids = pc_possible_cpu_arch_ids; mc->has_hotpluggable_cpus = true; mc->default_boot_order = "cad"; |