[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v19 09/11] hostmem backend: implement memory policy
From: |
Hu Tao |
Subject: |
[Qemu-devel] [PATCH v19 09/11] hostmem backend: implement memory policy |
Date: |
Tue, 4 Mar 2014 15:28:23 +0800 |
Signed-off-by: Hu Tao <address@hidden>
---
backends/hostmem.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++--
include/sysemu/hostmem.h | 4 ++
qapi-schema.json | 20 ++++++++++
3 files changed, 118 insertions(+), 3 deletions(-)
diff --git a/backends/hostmem.c b/backends/hostmem.c
index 0bd3900..077e8cc 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -10,11 +10,14 @@
* See the COPYING file in the top-level directory.
*/
#include "sysemu/hostmem.h"
-#include "sysemu/sysemu.h"
#include "qapi/visitor.h"
+#include "qapi-visit.h"
#include "qapi/qmp/qerror.h"
#include "qemu/config-file.h"
#include "qom/object_interfaces.h"
+#ifdef CONFIG_NUMA
+#include <numaif.h>
+#endif
static void
hostmemory_backend_get_size(Object *obj, Visitor *v, void *opaque,
@@ -50,11 +53,85 @@ hostmemory_backend_set_size(Object *obj, Visitor *v, void
*opaque,
backend->size = value;
}
+static void
+get_host_nodes(Object *obj, Visitor *v, void *opaque, const char *name,
+ Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+ uint16List *host_nodes = NULL;
+ uint16List **node = &host_nodes;
+ unsigned long value;
+
+ value = find_first_bit(backend->host_nodes, MAX_NODES);
+ if (value == MAX_NODES) {
+ return;
+ }
+
+ *node = g_malloc0(sizeof(**node));
+ (*node)->value = value;
+ node = &(*node)->next;
+
+ do {
+ value = find_next_bit(backend->host_nodes, MAX_NODES, value + 1);
+ if (value == MAX_NODES) {
+ break;
+ }
+
+ *node = g_malloc0(sizeof(**node));
+ (*node)->value = value;
+ node = &(*node)->next;
+ } while (true);
+
+ visit_type_uint16List(v, &host_nodes, name, errp);
+}
+
+static void
+set_host_nodes(Object *obj, Visitor *v, void *opaque, const char *name,
+ Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+ uint16List *l = NULL;
+
+ visit_type_uint16List(v, &l, name, errp);
+
+ while (l) {
+ bitmap_set(backend->host_nodes, l->value, 1);
+ l = l->next;
+ }
+}
+
+static void
+get_policy(Object *obj, Visitor *v, void *opaque, const char *name,
+ Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+ int policy = backend->policy;
+
+ visit_type_enum(v, &policy, HostMemPolicy_lookup, NULL, name, errp);
+}
+
+static void
+set_policy(Object *obj, Visitor *v, void *opaque, const char *name,
+ Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+ int policy;
+
+ visit_type_enum(v, &policy, HostMemPolicy_lookup, NULL, name, errp);
+ backend->policy = policy;
+}
+
static void hostmemory_backend_initfn(Object *obj)
{
object_property_add(obj, "size", "int",
hostmemory_backend_get_size,
hostmemory_backend_set_size, NULL, NULL, NULL);
+ object_property_add(obj, "host-nodes", "int",
+ get_host_nodes,
+ set_host_nodes, NULL, NULL, NULL);
+ object_property_add(obj, "policy", "str",
+ get_policy,
+ set_policy, NULL, NULL, NULL);
}
static void hostmemory_backend_finalize(Object *obj)
@@ -69,8 +146,22 @@ static void hostmemory_backend_finalize(Object *obj)
static void
hostmemory_backend_memory_init(UserCreatable *uc, Error **errp)
{
- error_setg(errp, "memory_init is not implemented for type [%s]",
- object_get_typename(OBJECT(uc)));
+#ifdef CONFIG_NUMA
+ HostMemoryBackend *backend = MEMORY_BACKEND(uc);
+ void *p = memory_region_get_ram_ptr(&backend->mr);
+ unsigned long maxnode = find_last_bit(backend->host_nodes, MAX_NODES);
+
+ /* This is a workaround for a long standing bug in Linux'
+ * mbind implementation, which cuts off the last specified
+ * node.
+ */
+ if (mbind(p, backend->size, backend->policy, backend->host_nodes,
+ maxnode + 2, 0)) {
+ error_setg_errno(errp, errno,
+ "cannot bind memory to host NUMA nodes\n");
+ return;
+ }
+#endif
}
MemoryRegion *
diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
index bc3ffb3..a2b0702 100644
--- a/include/sysemu/hostmem.h
+++ b/include/sysemu/hostmem.h
@@ -12,10 +12,12 @@
#ifndef QEMU_RAM_H
#define QEMU_RAM_H
+#include "sysemu/sysemu.h" /* for MAX_NODES */
#include "qom/object.h"
#include "qapi/error.h"
#include "exec/memory.h"
#include "qemu/option.h"
+#include "qemu/bitmap.h"
#define TYPE_MEMORY_BACKEND "memory"
#define MEMORY_BACKEND(obj) \
@@ -50,6 +52,8 @@ struct HostMemoryBackend {
/* protected */
uint64_t size;
+ DECLARE_BITMAP(host_nodes, MAX_NODES);
+ HostMemPolicy policy;
MemoryRegion mr;
};
diff --git a/qapi-schema.json b/qapi-schema.json
index 62e0b83..86b78a5 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4554,3 +4554,23 @@
'*cpus': ['uint16'],
'*mem': 'size',
'*memdev': 'str' }}
+
+##
+# @HostMemPolicy
+#
+# Host memory policy types
+#
+# @default: restore default policy, remove any nondefault policy
+#
+# @preferred: set the preferred host nodes for allocation
+#
+# @membind: a strict policy that restricts memory allocation to the
+# host nodes specified
+#
+# @interleave: memory allocations are interleaved across the set
+# of host nodes specified
+#
+# Since 2.1
+##
+{ 'enum': 'HostMemPolicy',
+ 'data': [ 'default', 'preferred', 'membind', 'interleave' ] }
--
1.8.5.2.229.g4448466
- [Qemu-devel] [PATCH v19 00/11] Add support for binding guest numa nodes to host numa nodes, Hu Tao, 2014/03/04
- [Qemu-devel] [PATCH v19 05/11] numa: add -numa node, memdev= option, Hu Tao, 2014/03/04
- [Qemu-devel] [PATCH v19 11/11] hmp: add info memdev, Hu Tao, 2014/03/04
- [Qemu-devel] [PATCH v19 02/11] add memdev backend infrastructure, Hu Tao, 2014/03/04
- [Qemu-devel] [PATCH v19 01/11] object_add: allow completion handler to get canonical path, Hu Tao, 2014/03/04
- [Qemu-devel] [PATCH v19 08/11] Add Linux libnuma detection, Hu Tao, 2014/03/04
- [Qemu-devel] [PATCH v19 03/11] pc: pass QEMUMachineInitArgs to pc_memory_init, Hu Tao, 2014/03/04
- [Qemu-devel] [PATCH v19 06/11] qapi: make string input visitor parse int list, Hu Tao, 2014/03/04
- [Qemu-devel] [PATCH v19 09/11] hostmem backend: implement memory policy,
Hu Tao <=
- [Qemu-devel] [PATCH v19 10/11] qmp: add query-memdev, Hu Tao, 2014/03/04
- [Qemu-devel] [PATCH v19 04/11] numa: introduce memory_region_allocate_system_memory, Hu Tao, 2014/03/04
- [Qemu-devel] [PATCH v19 07/11] qapi: make string output visitor parse int list, Hu Tao, 2014/03/04