qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v3 12/18] numa: Split the numa initialization


From: Babu Moger
Subject: [PATCH v3 12/18] numa: Split the numa initialization
Date: Tue, 03 Dec 2019 18:38:18 -0600
User-agent: StGit/unknown-version

To generate the apic id for EPYC cpu models correctly, we need to know the
number of numa nodes in advance. At present numa node initialization and cpu
initialization happens at the same time. Apic id generation happens during the
cpu initialization. At this point it is not known how many numa nodes are
configured. So, save the cpu indexes and move the cpu initialization inside the
numa_complete_configuration. Cpu initialization is done in new function
numa_node_complete_configuration.

Signed-off-by: Babu Moger <address@hidden>
---
 hw/core/numa.c        |   62 ++++++++++++++++++++++++++++++++-----------------
 include/sysemu/numa.h |    5 ++++
 2 files changed, 46 insertions(+), 21 deletions(-)

diff --git a/hw/core/numa.c b/hw/core/numa.c
index 038c96d4ab..ba02a41421 100644
--- a/hw/core/numa.c
+++ b/hw/core/numa.c
@@ -33,6 +33,7 @@
 #include "qapi/error.h"
 #include "qapi/opts-visitor.h"
 #include "qapi/qapi-visit-machine.h"
+#include "qapi/clone-visitor.h"
 #include "sysemu/qtest.h"
 #include "hw/core/cpu.h"
 #include "hw/mem/pc-dimm.h"
@@ -59,11 +60,8 @@ static int max_numa_nodeid; /* Highest specified NUMA node 
ID, plus one.
 static void parse_numa_node(MachineState *ms, NumaNodeOptions *node,
                             Error **errp)
 {
-    Error *err = NULL;
     uint16_t nodenr;
-    uint16List *cpus = NULL;
     MachineClass *mc = MACHINE_GET_CLASS(ms);
-    unsigned int max_cpus = ms->smp.max_cpus;
     NodeInfo *numa_info = ms->numa_state->nodes;
 
     if (node->has_nodeid) {
@@ -87,24 +85,8 @@ static void parse_numa_node(MachineState *ms, 
NumaNodeOptions *node,
         error_setg(errp, "NUMA is not supported by this machine-type");
         return;
     }
-    for (cpus = node->cpus; cpus; cpus = cpus->next) {
-        CpuInstanceProperties props;
-        if (cpus->value >= max_cpus) {
-            error_setg(errp,
-                       "CPU index (%" PRIu16 ")"
-                       " should be smaller than maxcpus (%d)",
-                       cpus->value, max_cpus);
-            return;
-        }
-        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, &err);
-        if (err) {
-            error_propagate(errp, err);
-            return;
-        }
-    }
+
+    numa_info[nodenr].cpu_indexes = QAPI_CLONE(uint16List, node->cpus);
 
     have_memdevs = have_memdevs ? : node->has_memdev;
     have_mem = have_mem ? : node->has_mem;
@@ -360,12 +342,50 @@ void numa_default_auto_assign_ram(MachineClass *mc, 
NodeInfo *nodes,
     nodes[i].node_mem = size - usedmem;
 }
 
+
+void numa_node_complete_configuration(MachineState *ms, NodeInfo *node,
+                                      uint16_t nodenr)
+{
+    Error *err = NULL;
+    uint16List *cpus = NULL;
+    MachineClass *mc = MACHINE_GET_CLASS(ms);
+    unsigned int max_cpus = ms->smp.max_cpus;
+
+    for (cpus = node->cpu_indexes; cpus; cpus = cpus->next) {
+        CpuInstanceProperties props;
+        if (cpus->value >= max_cpus) {
+            error_report("CPU index (%" PRIu16 ")"
+                         " should be smaller than maxcpus (%d)",
+                         cpus->value, max_cpus);
+            return;
+        }
+        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, &err);
+        if (err) {
+            error_report("Numa node initialization failed");
+            return;
+        }
+    }
+}
+
 void numa_complete_configuration(MachineState *ms)
 {
     int i;
     MachineClass *mc = MACHINE_GET_CLASS(ms);
     NodeInfo *numa_info = ms->numa_state->nodes;
 
+    for (i = 0; i < ms->numa_state->num_nodes; i++) {
+        /*
+         * numa_node_complete_configuration() needs to be called after all
+         * nodes were already parsed, because to support new epyc mode, we
+         * need to know the number of numa nodes in advance to generate
+         * apic id correctly.
+         */
+        numa_node_complete_configuration(ms, &numa_info[i], i);
+    }
+
     /*
      * If memory hotplug is enabled (slots > 0) but without '-numa'
      * options explicitly on CLI, guestes will break.
diff --git a/include/sysemu/numa.h b/include/sysemu/numa.h
index ae9c41d02b..91794d685f 100644
--- a/include/sysemu/numa.h
+++ b/include/sysemu/numa.h
@@ -19,6 +19,9 @@ struct NodeInfo {
     struct HostMemoryBackend *node_memdev;
     bool present;
     uint8_t distance[MAX_NODES];
+
+    /* These indexes are saved for numa node initialization later */
+    uint16List *cpu_indexes;
 };
 
 struct NumaNodeMem {
@@ -41,6 +44,8 @@ typedef struct NumaState NumaState;
 void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp);
 void parse_numa_opts(MachineState *ms);
 void numa_complete_configuration(MachineState *ms);
+void numa_node_complete_configuration(MachineState *ms, NodeInfo *node,
+                                      uint16_t nodenr);
 void query_numa_node_mem(NumaNodeMem node_mem[], MachineState *ms);
 extern QemuOptsList qemu_numa_opts;
 void numa_legacy_auto_assign_ram(MachineClass *mc, NodeInfo *nodes,




reply via email to

[Prev in Thread] Current Thread [Next in Thread]