qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [RFC 2 PATCH 01/16] numa: Split the numa functionality


From: Moger, Babu
Subject: [Qemu-devel] [RFC 2 PATCH 01/16] numa: Split the numa functionality
Date: Fri, 6 Sep 2019 19:11:43 +0000

To support new epyc mode, we need to know the number of numa nodes
in advance to generate apic id correctly. So, split the numa
initialization into two. The function parse_numa initializes numa_info
and updates nb_numa_nodes. And then parse_numa_node does the numa node
initialization.

Signed-off-by: Babu Moger <address@hidden>
---
 hw/core/numa.c        |  106 +++++++++++++++++++++++++++++++++++--------------
 include/sysemu/numa.h |    2 +
 vl.c                  |    2 +
 3 files changed, 80 insertions(+), 30 deletions(-)

diff --git a/hw/core/numa.c b/hw/core/numa.c
index a11431483c..27fa6b5e1d 100644
--- a/hw/core/numa.c
+++ b/hw/core/numa.c
@@ -55,14 +55,10 @@ bool have_numa_distance;
 NodeInfo numa_info[MAX_NODES];
 
 
-static void parse_numa_node(MachineState *ms, NumaNodeOptions *node,
+static void parse_numa_info(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;
 
     if (node->has_nodeid) {
         nodenr = node->nodeid;
@@ -81,29 +77,6 @@ static void parse_numa_node(MachineState *ms, 
NumaNodeOptions *node,
         return;
     }
 
-    if (!mc->cpu_index_to_instance_props || !mc->get_default_cpu_node_id) {
-        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;
-        }
-    }
-
     have_memdevs = have_memdevs ? : node->has_memdev;
     have_mem = have_mem ? : node->has_mem;
     if ((node->has_mem && have_memdevs) || (node->has_memdev && have_mem)) {
@@ -177,7 +150,7 @@ void set_numa_options(MachineState *ms, NumaOptions 
*object, Error **errp)
 
     switch (object->type) {
     case NUMA_OPTIONS_TYPE_NODE:
-        parse_numa_node(ms, &object->u.node, &err);
+        parse_numa_info(ms, &object->u.node, &err);
         if (err) {
             goto end;
         }
@@ -242,6 +215,73 @@ end:
     return 0;
 }
 
+void set_numa_node_options(MachineState *ms, NumaOptions *object, Error **errp)
+{
+    MachineClass *mc = MACHINE_GET_CLASS(ms);
+    NumaNodeOptions *node = &object->u.node;
+    unsigned int max_cpus = ms->smp.max_cpus;
+    uint16List *cpus = NULL;
+    Error *err = NULL;
+    uint16_t nodenr;
+
+    if (node->has_nodeid) {
+        nodenr = node->nodeid;
+    } else {
+        error_setg(errp, "NUMA node information is not available");
+    }
+
+    if (!mc->cpu_index_to_instance_props || !mc->get_default_cpu_node_id) {
+        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;
+         }
+    }
+}
+
+static int parse_numa_node(void *opaque, QemuOpts *opts, Error **errp)
+{
+    NumaOptions *object = NULL;
+    MachineState *ms = MACHINE(opaque);
+    Error *err = NULL;
+    Visitor *v = opts_visitor_new(opts);
+
+    visit_type_NumaOptions(v, NULL, &object, &err);
+    visit_free(v);
+    if (err) {
+        goto end;
+    }
+
+    if (object->type == NUMA_OPTIONS_TYPE_NODE) {
+        set_numa_node_options(ms, object, &err);
+    }
+
+end:
+    qapi_free_NumaOptions(object);
+    if (err) {
+        error_propagate(errp, err);
+        return -1;
+    }
+
+    return 0;
+}
+
 /* If all node pair distances are symmetric, then only distances
  * in one direction are enough. If there is even one asymmetric
  * pair, though, then all distances must be provided. The
@@ -368,7 +408,7 @@ void numa_complete_configuration(MachineState *ms)
     if (ms->ram_slots > 0 && nb_numa_nodes == 0 &&
         mc->auto_enable_numa_with_memhp) {
             NumaNodeOptions node = { };
-            parse_numa_node(ms, &node, &error_abort);
+            parse_numa_info(ms, &node, &error_abort);
     }
 
     assert(max_numa_nodeid <= MAX_NODES);
@@ -448,6 +488,12 @@ void parse_numa_opts(MachineState *ms)
     qemu_opts_foreach(qemu_find_opts("numa"), parse_numa, ms, &error_fatal);
 }
 
+void parse_numa_node_opts(MachineState *ms)
+{
+    qemu_opts_foreach(qemu_find_opts("numa"), parse_numa_node,
+                      ms, &error_fatal);
+}
+
 void numa_cpu_pre_plug(const CPUArchId *slot, DeviceState *dev, Error **errp)
 {
     int node_id = object_property_get_int(OBJECT(dev), "node-id", 
&error_abort);
diff --git a/include/sysemu/numa.h b/include/sysemu/numa.h
index 01a263eba2..ca109adaa6 100644
--- a/include/sysemu/numa.h
+++ b/include/sysemu/numa.h
@@ -24,7 +24,9 @@ struct NumaNodeMem {
 extern NodeInfo numa_info[MAX_NODES];
 
 void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp);
+void set_numa_node_options(MachineState *ms, NumaOptions *object, Error 
**errp);
 void parse_numa_opts(MachineState *ms);
+void parse_numa_node_opts(MachineState *ms);
 void numa_complete_configuration(MachineState *ms);
 void query_numa_node_mem(NumaNodeMem node_mem[]);
 extern QemuOptsList qemu_numa_opts;
diff --git a/vl.c b/vl.c
index b426b32134..711d2ae5da 100644
--- a/vl.c
+++ b/vl.c
@@ -4339,6 +4339,8 @@ int main(int argc, char **argv, char **envp)
     }
     parse_numa_opts(current_machine);
 
+    parse_numa_node_opts(current_machine);
+
     /* do monitor/qmp handling at preconfig state if requested */
     main_loop();
 


reply via email to

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