numa: move source of default CPUs to NUMA node mapping into boards
Originally CPU threads were by default assigned in
round-robin fashion. However it was causing issues in
guest since CPU threads from the same socket/core could
be placed on different NUMA nodes.
Commit fb43b73b (pc: fix default VCPU to NUMA node mapping)
fixed it by grouping threads within a socket on the same node
introducing cpu_index_to_socket_id() callback and commit
20bb648d (spapr: Fix default NUMA node allocation for threads)
reused callback to fix similar issues for SPAPR machine
even though socket doesn't make much sense there.
As result QEMU ended up having 3 default distribution rules
used by 3 targets /virt-arm, spapr, pc/.
In effort of moving NUMA mapping for CPUs into possible_cpus,
generalize default mapping in numa.c by making boards decide
on default mapping and let them explicitly tell generic
numa code to which node a CPU thread belongs to by replacing
cpu_index_to_socket_id() with @cpu_index_to_instance_props()
which provides default node_id assigned by board to specified
cpu_index.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <1494415802-227633-2-git-send-email-imammedo@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
diff --git a/numa.c b/numa.c
index d753687..bcdfca2 100644
--- a/numa.c
+++ b/numa.c
@@ -443,9 +443,10 @@
nodes[i].node_mem = size - usedmem;
}
-void parse_numa_opts(MachineClass *mc)
+void parse_numa_opts(MachineState *ms)
{
int i;
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
for (i = 0; i < MAX_NODES; i++) {
numa_info[i].node_cpu = bitmap_new(max_cpus);
@@ -511,21 +512,18 @@
break;
}
}
- /* Historically VCPUs were assigned in round-robin order to NUMA
- * nodes. However it causes issues with guest not handling it nice
- * in case where cores/threads from a multicore CPU appear on
- * different nodes. So allow boards to override default distribution
- * rule grouping VCPUs by socket so that VCPUs from the same socket
- * would be on the same node.
- */
+
+ /* assign CPUs to nodes using board provided default mapping */
+ if (!mc->cpu_index_to_instance_props) {
+ error_report("default CPUs to NUMA node mapping isn't supported");
+ exit(1);
+ }
if (i == nb_numa_nodes) {
for (i = 0; i < max_cpus; i++) {
- unsigned node_id = i % nb_numa_nodes;
- if (mc->cpu_index_to_socket_id) {
- node_id = mc->cpu_index_to_socket_id(i) % nb_numa_nodes;
- }
+ CpuInstanceProperties props;
+ props = mc->cpu_index_to_instance_props(ms, i);
- set_bit(i, numa_info[node_id].node_cpu);
+ set_bit(i, numa_info[props.node_id].node_cpu);
}
}