qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH v5 5/6] Add memfd based hostmem


From: Marc-André Lureau
Subject: [Qemu-devel] [PATCH v5 5/6] Add memfd based hostmem
Date: Mon, 23 Oct 2017 10:59:09 +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 | 124 +++++++++++++++++++++++++++++++++++++++++++++++
 tests/vhost-user-test.c  |   2 +-
 backends/Makefile.objs   |   2 +
 qemu-options.hx          |  15 ++++++
 4 files changed, 142 insertions(+), 1 deletion(-)
 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..448591556a
--- /dev/null
+++ b/backends/hostmem-memfd.c
@@ -0,0 +1,124 @@
+/*
+ * 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;
+    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->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 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_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/tests/vhost-user-test.c b/tests/vhost-user-test.c
index 4b98018478..830f1e4026 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -31,7 +31,7 @@
 #include <linux/virtio_net.h>
 #include <sys/vfs.h>
 
-#define VHOST_USER_NET_TESTS_WORKING 0 /* broken as of 2.10.0 */
+#define VHOST_USER_NET_TESTS_WORKING 1 /* broken as of 2.10.0 */
 
 /* GLIB version compatibility flags */
 #if !GLIB_CHECK_VERSION(2, 26, 0)
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..5828caefeb 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4208,6 +4208,21 @@ 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}
+
+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.
+
 @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




reply via email to

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