diff mbox

[v4,2/3] Add memfd based hostmem

Message ID 20170621140219.4568-3-marcandre.lureau@redhat.com
State New
Headers show

Commit Message

Marc-André Lureau June 21, 2017, 2:02 p.m. UTC
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.

Usage:
-object memory-backend-memfd,id=mem1,size=1G

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 backends/hostmem-memfd.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++
 backends/Makefile.objs   |  2 ++
 qemu-options.hx          | 11 ++++++++
 3 files changed, 80 insertions(+)
 create mode 100644 backends/hostmem-memfd.c

Comments

Eduardo Habkost June 23, 2017, 9:08 p.m. UTC | #1
On Wed, Jun 21, 2017 at 04:02:18PM +0200, Marc-André Lureau wrote:
> 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.

How exactly can the memfd be used to share memory?  Is there an existing
mechanism for sharing the memfd file descriptor with another process?


> 
> 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.
> 
> Usage:
> -object memory-backend-memfd,id=mem1,size=1G
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  backends/hostmem-memfd.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++
>  backends/Makefile.objs   |  2 ++
>  qemu-options.hx          | 11 ++++++++
>  3 files changed, 80 insertions(+)
>  create mode 100644 backends/hostmem-memfd.c
> 
[...]
Marc-André Lureau June 27, 2017, 8:23 a.m. UTC | #2
Hi Eduardo

On Fri, Jun 23, 2017 at 11:09 PM Eduardo Habkost <ehabkost@redhat.com>
wrote:

> On Wed, Jun 21, 2017 at 04:02:18PM +0200, Marc-André Lureau wrote:
> > 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.
>
> How exactly can the memfd be used to share memory?  Is there an existing
> mechanism for sharing the memfd file descriptor with another process



Since there is no backing file, the traditional mechanism is by passing fd,
via socket ancillary data or forking etc.. Both ivshmem and vhost-user have
such messages, with eventually details for the memory map usage.


> >
> > 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.
> >
> > Usage:
> > -object memory-backend-memfd,id=mem1,size=1G
> >
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > ---
> >  backends/hostmem-memfd.c | 67
> ++++++++++++++++++++++++++++++++++++++++++++++++
> >  backends/Makefile.objs   |  2 ++
> >  qemu-options.hx          | 11 ++++++++
> >  3 files changed, 80 insertions(+)
> >  create mode 100644 backends/hostmem-memfd.c
> >
> [...]
>
> --
> Eduardo
>
> --
Marc-André Lureau
Eduardo Habkost June 28, 2017, 6:29 p.m. UTC | #3
On Tue, Jun 27, 2017 at 08:23:03AM +0000, Marc-André Lureau wrote:
> Hi Eduardo
> 
> On Fri, Jun 23, 2017 at 11:09 PM Eduardo Habkost <ehabkost@redhat.com>
> wrote:
> 
> > On Wed, Jun 21, 2017 at 04:02:18PM +0200, Marc-André Lureau wrote:
> > > 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.
> >
> > How exactly can the memfd be used to share memory?  Is there an existing
> > mechanism for sharing the memfd file descriptor with another process
> 
> 
> 
> Since there is no backing file, the traditional mechanism is by passing fd,
> via socket ancillary data or forking etc.. Both ivshmem and vhost-user have
> such messages, with eventually details for the memory map usage.

The documentation is very similar to memory-backend-file, so it sounded
like there was a generic mechanism to ask QEMU to share the backend FD.
Maybe it would be interesting to mention on which cases the FD can
actually be shared.  Are ivshmem and vhost-user the only existing cases?

> 
> 
> > >
> > > 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.
> > >
> > > Usage:
> > > -object memory-backend-memfd,id=mem1,size=1G
> > >
> > > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > > ---
> > >  backends/hostmem-memfd.c | 67
> > ++++++++++++++++++++++++++++++++++++++++++++++++
> > >  backends/Makefile.objs   |  2 ++
> > >  qemu-options.hx          | 11 ++++++++
> > >  3 files changed, 80 insertions(+)
> > >  create mode 100644 backends/hostmem-memfd.c
> > >
> > [...]
> >
> > --
> > Eduardo
> >
> > --
> Marc-André Lureau
Marc-André Lureau June 29, 2017, 1:34 p.m. UTC | #4
Hi

On Wed, Jun 28, 2017 at 8:29 PM Eduardo Habkost <ehabkost@redhat.com> wrote:

> On Tue, Jun 27, 2017 at 08:23:03AM +0000, Marc-André Lureau wrote:
> > Hi Eduardo
> >
> > On Fri, Jun 23, 2017 at 11:09 PM Eduardo Habkost <ehabkost@redhat.com>
> > wrote:
> >
> > > On Wed, Jun 21, 2017 at 04:02:18PM +0200, Marc-André Lureau wrote:
> > > > 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.
> > >
> > > How exactly can the memfd be used to share memory?  Is there an
> existing
> > > mechanism for sharing the memfd file descriptor with another process
> >
> >
> >
> > Since there is no backing file, the traditional mechanism is by passing
> fd,
> > via socket ancillary data or forking etc.. Both ivshmem and vhost-user
> have
> > such messages, with eventually details for the memory map usage.
>
> The documentation is very similar to memory-backend-file, so it sounded
> like there was a generic mechanism to ask QEMU to share the backend FD.
> Maybe it would be interesting to mention on which cases the FD can
> actually be shared.  Are ivshmem and vhost-user the only existing cases?
>
>
Actually, vhost-user may be the only way today to get the fd outside of
qemu process.

(ivshmem needs the server to provide the fd)

We could quite easily add or extend QMP messages for that in the future.

Do you want this detail to be written in the commit message or elsewhere?


> >
> >
> > > >
> > > > 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.
> > > >
> > > > Usage:
> > > > -object memory-backend-memfd,id=mem1,size=1G
> > > >
> > > > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > > > ---
> > > >  backends/hostmem-memfd.c | 67
> > > ++++++++++++++++++++++++++++++++++++++++++++++++
> > > >  backends/Makefile.objs   |  2 ++
> > > >  qemu-options.hx          | 11 ++++++++
> > > >  3 files changed, 80 insertions(+)
> > > >  create mode 100644 backends/hostmem-memfd.c
> > > >
> > > [...]
> > >
> > > --
> > > Eduardo
> > >
> > > --
> > Marc-André Lureau
>
> --
> Eduardo
>
Eduardo Habkost July 3, 2017, 2:34 p.m. UTC | #5
On Thu, Jun 29, 2017 at 01:34:22PM +0000, Marc-André Lureau wrote:
> Hi
> 
> On Wed, Jun 28, 2017 at 8:29 PM Eduardo Habkost <ehabkost@redhat.com> wrote:
> 
> > On Tue, Jun 27, 2017 at 08:23:03AM +0000, Marc-André Lureau wrote:
> > > Hi Eduardo
> > >
> > > On Fri, Jun 23, 2017 at 11:09 PM Eduardo Habkost <ehabkost@redhat.com>
> > > wrote:
> > >
> > > > On Wed, Jun 21, 2017 at 04:02:18PM +0200, Marc-André Lureau wrote:
> > > > > 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.
> > > >
> > > > How exactly can the memfd be used to share memory?  Is there an
> > existing
> > > > mechanism for sharing the memfd file descriptor with another process
> > >
> > >
> > >
> > > Since there is no backing file, the traditional mechanism is by passing
> > fd,
> > > via socket ancillary data or forking etc.. Both ivshmem and vhost-user
> > have
> > > such messages, with eventually details for the memory map usage.
> >
> > The documentation is very similar to memory-backend-file, so it sounded
> > like there was a generic mechanism to ask QEMU to share the backend FD.
> > Maybe it would be interesting to mention on which cases the FD can
> > actually be shared.  Are ivshmem and vhost-user the only existing cases?
> >
> >
> Actually, vhost-user may be the only way today to get the fd outside of
> qemu process.
> 
> (ivshmem needs the server to provide the fd)
> 
> We could quite easily add or extend QMP messages for that in the future.
> 
> Do you want this detail to be written in the commit message or elsewhere?

(Sorry for taking so long to reply.)

I think this should be in the documentation of the new option (in
qemu-options.hx).

I don't think it needs lots of extra detail, maybe just change "which
can be used to share the memory with a co-operating external process" to
"which allows QEMU to share the memory with an external process in some
cases (e.g. when using vhost-user)".
diff mbox

Patch

diff --git a/backends/hostmem-memfd.c b/backends/hostmem-memfd.c
new file mode 100644
index 0000000000..13d300d9ad
--- /dev/null
+++ b/backends/hostmem-memfd.c
@@ -0,0 +1,67 @@ 
+/*
+ * QEMU host memfd memory backend
+ *
+ * Copyright (C) 2016 Red Hat Inc
+ *
+ * Authors:
+ *   Marc-André Lureau <marcandre.lureau@redhat.com>
+ *
+ * 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"
+
+static void
+memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
+{
+    int fd;
+
+    if (!backend->size) {
+        error_setg(errp, "can't create backend with size 0");
+        return;
+    }
+
+    if (!memory_region_size(&backend->mr)) {
+        backend->force_prealloc = mem_prealloc;
+        fd = qemu_memfd_create(TYPE_MEMORY_BACKEND_MEMFD,
+                               backend->size,
+                               F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL,
+                               true);
+        if (fd == -1) {
+            error_setg(errp, "can't allocate memfd backend");
+            return;
+        }
+        memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend),
+            object_get_canonical_path(OBJECT(backend)),
+            backend->size, true, fd, errp);
+    }
+}
+
+static void
+memfd_backend_class_init(ObjectClass *oc, void *data)
+{
+    HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc);
+
+    bc->alloc = memfd_backend_memory_alloc;
+}
+
+static const TypeInfo memfd_backend_info = {
+    .name = TYPE_MEMORY_BACKEND_MEMFD,
+    .parent = TYPE_MEMORY_BACKEND,
+    .class_init = memfd_backend_class_init,
+};
+
+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 30c4f9850f..6db76cf54f 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3974,6 +3974,17 @@  The @option{share} boolean option determines whether the memory
 region is marked as private to QEMU, or shared. The latter allows
 a co-operating external process to access the QEMU memory region.
 
+@item -object memory-backend-memfd,id=@var{id},size=@var{size}
+
+Creates an anonymous memory file backend object, which can be used to
+share the memory with a co-operating external process. The memory is
+allocated with memfd and 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}.
+
 @item -object rng-random,id=@var{id},filename=@var{/dev/random}
 
 Creates a random number generator backend which obtains entropy from