summaryrefslogtreecommitdiff
path: root/numa.c
diff options
context:
space:
mode:
authorYonghee Han <onstudy@samsung.com>2016-07-27 16:40:17 +0900
committerYonghee Han <onstudy@samsung.com>2016-07-27 00:53:56 -0700
commit3158f4a51894e46ecb593bffbfd12824e1d6534a (patch)
tree2bef7f0238e687c5de65f48b5995ee124a95d157 /numa.c
parenta3b133b0ea0696e42fd876b9a803e28bc6ef5299 (diff)
downloadqemu-3158f4a51894e46ecb593bffbfd12824e1d6534a.tar.gz
qemu-3158f4a51894e46ecb593bffbfd12824e1d6534a.tar.bz2
qemu-3158f4a51894e46ecb593bffbfd12824e1d6534a.zip
Imported Upstream version 2.4.1upstream/2.4.1
Change-Id: I0b584f569cb0e0f4eac13cdb79e110c2dbc34bfc
Diffstat (limited to 'numa.c')
-rw-r--r--numa.c105
1 files changed, 99 insertions, 6 deletions
diff --git a/numa.c b/numa.c
index c975fb268..402804bdf 100644
--- a/numa.c
+++ b/numa.c
@@ -31,7 +31,6 @@
#include "qapi-visit.h"
#include "qapi/opts-visitor.h"
#include "qapi/dealloc-visitor.h"
-#include "qapi/qmp/qerror.h"
#include "hw/boards.h"
#include "sysemu/hostmem.h"
#include "qmp-commands.h"
@@ -53,6 +52,93 @@ static int max_numa_nodeid; /* Highest specified NUMA node ID, plus one.
int nb_numa_nodes;
NodeInfo numa_info[MAX_NODES];
+void numa_set_mem_node_id(ram_addr_t addr, uint64_t size, uint32_t node)
+{
+ struct numa_addr_range *range;
+
+ /*
+ * Memory-less nodes can come here with 0 size in which case,
+ * there is nothing to do.
+ */
+ if (!size) {
+ return;
+ }
+
+ range = g_malloc0(sizeof(*range));
+ range->mem_start = addr;
+ range->mem_end = addr + size - 1;
+ QLIST_INSERT_HEAD(&numa_info[node].addr, range, entry);
+}
+
+void numa_unset_mem_node_id(ram_addr_t addr, uint64_t size, uint32_t node)
+{
+ struct numa_addr_range *range, *next;
+
+ QLIST_FOREACH_SAFE(range, &numa_info[node].addr, entry, next) {
+ if (addr == range->mem_start && (addr + size - 1) == range->mem_end) {
+ QLIST_REMOVE(range, entry);
+ g_free(range);
+ return;
+ }
+ }
+}
+
+static void numa_set_mem_ranges(void)
+{
+ int i;
+ ram_addr_t mem_start = 0;
+
+ /*
+ * Deduce start address of each node and use it to store
+ * the address range info in numa_info address range list
+ */
+ for (i = 0; i < nb_numa_nodes; i++) {
+ numa_set_mem_node_id(mem_start, numa_info[i].node_mem, i);
+ mem_start += numa_info[i].node_mem;
+ }
+}
+
+/*
+ * Check if @addr falls under NUMA @node.
+ */
+static bool numa_addr_belongs_to_node(ram_addr_t addr, uint32_t node)
+{
+ struct numa_addr_range *range;
+
+ QLIST_FOREACH(range, &numa_info[node].addr, entry) {
+ if (addr >= range->mem_start && addr <= range->mem_end) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Given an address, return the index of the NUMA node to which the
+ * address belongs to.
+ */
+uint32_t numa_get_node(ram_addr_t addr, Error **errp)
+{
+ uint32_t i;
+
+ /* For non NUMA configurations, check if the addr falls under node 0 */
+ if (!nb_numa_nodes) {
+ if (numa_addr_belongs_to_node(addr, 0)) {
+ return 0;
+ }
+ }
+
+ for (i = 0; i < nb_numa_nodes; i++) {
+ if (numa_addr_belongs_to_node(addr, i)) {
+ return i;
+ }
+ }
+
+ error_setg(errp, "Address 0x" RAM_ADDR_FMT " doesn't belong to any "
+ "NUMA node", addr);
+ return -1;
+}
+
static void numa_node_parse(NumaNodeOptions *node, QemuOpts *opts, Error **errp)
{
uint16_t nodenr;
@@ -125,7 +211,7 @@ static void numa_node_parse(NumaNodeOptions *node, QemuOpts *opts, Error **errp)
max_numa_nodeid = MAX(max_numa_nodeid, nodenr + 1);
}
-static int parse_numa(QemuOpts *opts, void *opaque)
+static int parse_numa(void *opaque, QemuOpts *opts, Error **errp)
{
NumaOptions *object = NULL;
Error *err = NULL;
@@ -216,8 +302,7 @@ void parse_numa_opts(MachineClass *mc)
{
int i;
- if (qemu_opts_foreach(qemu_find_opts("numa"), parse_numa,
- NULL, 1) != 0) {
+ if (qemu_opts_foreach(qemu_find_opts("numa"), parse_numa, NULL, NULL)) {
exit(1);
}
@@ -276,6 +361,12 @@ void parse_numa_opts(MachineClass *mc)
}
for (i = 0; i < nb_numa_nodes; i++) {
+ QLIST_INIT(&numa_info[i].addr);
+ }
+
+ numa_set_mem_ranges();
+
+ for (i = 0; i < nb_numa_nodes; i++) {
if (!bitmap_empty(numa_info[i].node_cpu, MAX_CPUMASK_BITS)) {
break;
}
@@ -299,6 +390,8 @@ void parse_numa_opts(MachineClass *mc)
}
validate_numa_cpus();
+ } else {
+ numa_set_mem_node_id(0, ram_size, 0);
}
}
@@ -457,7 +550,7 @@ static int query_memdev(Object *obj, void *opaque)
m->value->policy = object_property_get_enum(obj,
"policy",
- HostMemPolicy_lookup,
+ "HostMemPolicy",
&err);
if (err) {
goto error;
@@ -486,7 +579,7 @@ MemdevList *qmp_query_memdev(Error **errp)
Object *obj;
MemdevList *list = NULL;
- obj = object_resolve_path("/objects", NULL);
+ obj = object_get_objects_root();
if (obj == NULL) {
return NULL;
}