[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v6 6/9] Add memfd based hostmem
From: |
Marc-André Lureau |
Subject: |
[Qemu-devel] [PATCH v6 6/9] Add memfd based hostmem |
Date: |
Mon, 23 Oct 2017 15:18:12 +0100 |
Add a new memory backend, similar to hostmem-file, except that it
doesn't need to create files. It also enforces memory sealing.
This backend is mainly useful for sharing the memory with other
processes.
Note that Linux supports transparent huge-pages of shmem/memfd memory
since 4.8. It is relatively easier to set up THP than a dedicate
hugepage mount point by using "madvise" in
/sys/kernel/mm/transparent_hugepage/shmem_enabled.
Since 4.14, memfd allows to set hugetlb requirement explicitly.
Usage:
-object memory-backend-memfd,id=mem1,size=1G
Signed-off-by: Marc-André Lureau <address@hidden>
---
backends/hostmem-memfd.c | 168 +++++++++++++++++++++++++++++++++++++++++++++++
backends/Makefile.objs | 2 +
qemu-options.hx | 23 +++++++
3 files changed, 193 insertions(+)
create mode 100644 backends/hostmem-memfd.c
diff --git a/backends/hostmem-memfd.c b/backends/hostmem-memfd.c
new file mode 100644
index 0000000000..28f15638c8
--- /dev/null
+++ b/backends/hostmem-memfd.c
@@ -0,0 +1,168 @@
+/*
+ * QEMU host memfd memory backend
+ *
+ * Copyright (C) 2016 Red Hat Inc
+ *
+ * Authors:
+ * Marc-André Lureau <address@hidden>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "sysemu/hostmem.h"
+#include "sysemu/sysemu.h"
+#include "qom/object_interfaces.h"
+#include "qemu/memfd.h"
+#include "qapi/error.h"
+
+#define TYPE_MEMORY_BACKEND_MEMFD "memory-backend-memfd"
+
+#define MEMORY_BACKEND_MEMFD(obj) \
+ OBJECT_CHECK(HostMemoryBackendMemfd, (obj), TYPE_MEMORY_BACKEND_MEMFD)
+
+typedef struct HostMemoryBackendMemfd HostMemoryBackendMemfd;
+
+struct HostMemoryBackendMemfd {
+ HostMemoryBackend parent_obj;
+
+ bool hugetlb;
+ uint64_t hugetlbsize;
+ bool seal;
+};
+
+static void
+memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
+{
+ HostMemoryBackendMemfd *m = MEMORY_BACKEND_MEMFD(backend);
+ int fd;
+
+ if (!backend->size) {
+ error_setg(errp, "can't create backend with size 0");
+ return;
+ }
+
+ if (host_memory_backend_mr_inited(backend)) {
+ return;
+ }
+
+ backend->force_prealloc = mem_prealloc;
+ fd = qemu_memfd_create(TYPE_MEMORY_BACKEND_MEMFD, backend->size,
+ m->hugetlb, m->hugetlbsize, m->seal ?
+ F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL : 0,
+ errp);
+ if (fd == -1) {
+ return;
+ }
+
+ memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend),
+ object_get_canonical_path(OBJECT(backend)),
+ backend->size, true, fd, errp);
+}
+
+static bool
+memfd_backend_get_hugetlb(Object *o, Error **errp)
+{
+ return MEMORY_BACKEND_MEMFD(o)->hugetlb;
+}
+
+static void
+memfd_backend_set_hugetlb(Object *o, bool value, Error **errp)
+{
+ MEMORY_BACKEND_MEMFD(o)->hugetlb = value;
+}
+
+static void
+memfd_backend_set_hugetlbsize(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ HostMemoryBackendMemfd *m = MEMORY_BACKEND_MEMFD(obj);
+ Error *local_err = NULL;
+ uint64_t value;
+
+ if (host_memory_backend_mr_inited(MEMORY_BACKEND(obj))) {
+ error_setg(&local_err, "cannot change property value");
+ goto out;
+ }
+
+ visit_type_size(v, name, &value, &local_err);
+ if (local_err) {
+ goto out;
+ }
+ if (!value) {
+ error_setg(&local_err, "Property '%s.%s' doesn't take value '%"
+ PRIu64 "'", object_get_typename(obj), name, value);
+ goto out;
+ }
+ m->hugetlbsize = value;
+out:
+ error_propagate(errp, local_err);
+}
+
+static void
+memfd_backend_get_hugetlbsize(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ HostMemoryBackendMemfd *m = MEMORY_BACKEND_MEMFD(obj);
+ uint64_t value = m->hugetlbsize;
+
+ visit_type_size(v, name, &value, errp);
+}
+
+static bool
+memfd_backend_get_seal(Object *o, Error **errp)
+{
+ return MEMORY_BACKEND_MEMFD(o)->seal;
+}
+
+static void
+memfd_backend_set_seal(Object *o, bool value, Error **errp)
+{
+ MEMORY_BACKEND_MEMFD(o)->seal = value;
+}
+
+static void
+memfd_backend_instance_init(Object *obj)
+{
+ HostMemoryBackendMemfd *m = MEMORY_BACKEND_MEMFD(obj);
+
+ /* default to sealed file */
+ m->seal = true;
+}
+
+static void
+memfd_backend_class_init(ObjectClass *oc, void *data)
+{
+ HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc);
+
+ bc->alloc = memfd_backend_memory_alloc;
+
+ object_class_property_add_bool(oc, "hugetlb",
+ memfd_backend_get_hugetlb,
+ memfd_backend_set_hugetlb,
+ &error_abort);
+ object_class_property_add(oc, "hugetlbsize", "int",
+ memfd_backend_get_hugetlbsize,
+ memfd_backend_set_hugetlbsize,
+ NULL, NULL, &error_abort);
+ object_class_property_add_bool(oc, "seal",
+ memfd_backend_get_seal,
+ memfd_backend_set_seal,
+ &error_abort);
+}
+
+static const TypeInfo memfd_backend_info = {
+ .name = TYPE_MEMORY_BACKEND_MEMFD,
+ .parent = TYPE_MEMORY_BACKEND,
+ .instance_init = memfd_backend_instance_init,
+ .class_init = memfd_backend_class_init,
+ .instance_size = sizeof(HostMemoryBackendMemfd),
+};
+
+static void register_types(void)
+{
+ type_register_static(&memfd_backend_info);
+}
+
+type_init(register_types);
diff --git a/backends/Makefile.objs b/backends/Makefile.objs
index 0400799efd..67eeeba5fc 100644
--- a/backends/Makefile.objs
+++ b/backends/Makefile.objs
@@ -8,3 +8,5 @@ common-obj-$(CONFIG_LINUX) += hostmem-file.o
common-obj-y += cryptodev.o
common-obj-y += cryptodev-builtin.o
+
+common-obj-$(CONFIG_LINUX) += hostmem-memfd.o
diff --git a/qemu-options.hx b/qemu-options.hx
index 3728e9b4dd..3d4dc7880c 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4208,6 +4208,29 @@ that @option{discard-data} is only an optimization, and
QEMU
might not discard file contents if it aborts unexpectedly or is
terminated using SIGKILL.
address@hidden -object
memory-backend-memfd,address@hidden,address@hidden,address@hidden|off},address@hidden|off},address@hidden
+
+Creates an anonymous memory file backend object, which allows QEMU to
+share the memory with an external process in some cases (e.g. when
+using vhost-user). The memory is allocated with memfd and optional
+sealing. (Linux only)
+
+The @option{id} parameter is a unique ID that will be used to
+reference this memory region when configuring the @option{-numa}
+argument. The @option{size} option provides the size of the memory
+region, and accepts common suffixes, eg @option{500M}. The
address@hidden option creates a sealed-file, that will block further
+resizing the memory ('on' by default).
+
+The @option{hugetlb} option specify the file to be created resides in
+the hugetlbfs filesystem. Used in conjunction with the
address@hidden option, the @option{hugetlbsize} option specify the
+hugetlb page size on systems that support multiple hugetlb page sizes
+(it must be a power of 2 value supported by the system).
+
address@hidden option is currently incompatible with @option{seal}
+option.
+
@item -object rng-random,address@hidden,address@hidden/dev/random}
Creates a random number generator backend which obtains entropy from
--
2.15.0.rc0.40.gaefcc5f6f
- [Qemu-devel] [PATCH v6 0/9] Add memfd memory backend, Marc-André Lureau, 2017/10/23
- [Qemu-devel] [PATCH v6 1/9] memfd: split qemu_memfd_alloc(), Marc-André Lureau, 2017/10/23
- [Qemu-devel] [PATCH v6 2/9] memfd: remove needless include, Marc-André Lureau, 2017/10/23
- [Qemu-devel] [PATCH v6 4/9] memfd: add hugetlb support, Marc-André Lureau, 2017/10/23
- [Qemu-devel] [PATCH v6 3/9] memfd: add error argument, instead of perror(), Marc-André Lureau, 2017/10/23
- [Qemu-devel] [PATCH v6 5/9] memfd: add hugetlbsize argument, Marc-André Lureau, 2017/10/23
- [Qemu-devel] [PATCH v6 6/9] Add memfd based hostmem,
Marc-André Lureau <=
- [Qemu-devel] [PATCH v6 8/9] vhost-user-test: make read-guest-mem setup its own qemu, Marc-André Lureau, 2017/10/23
- [Qemu-devel] [PATCH v6 7/9] tests: keep compiling failing vhost-user tests, Marc-André Lureau, 2017/10/23
- [Qemu-devel] [PATCH v6 9/9] tests: use memfd in vhost-user-test, Marc-André Lureau, 2017/10/23