qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH] util/mmap-alloc: support MAP_SYNC in qemu_ram_m


From: Michael S. Tsirkin
Subject: Re: [Qemu-devel] [PATCH] util/mmap-alloc: support MAP_SYNC in qemu_ram_mmap()
Date: Tue, 2 Jan 2018 18:02:17 +0200

On Wed, Dec 27, 2017 at 02:56:20PM +0800, Haozhong Zhang wrote:
> When a file supporting DAX is used as vNVDIMM backend, mmap it with
> MAP_SYNC flag in addition can guarantee the persistence of guest write
> to the backend file without other QEMU actions (e.g., periodic fsync()
> by QEMU).
> 
> By using MAP_SHARED_VALIDATE flag with MAP_SYNC, we can ensure mmap
> with MAP_SYNC fails if MAP_SYNC is not supported by the kernel or the
> backend file. On such failures, QEMU retries mmap without MAP_SYNC and
> MAP_SHARED_VALIDATE.
> 
> Signed-off-by: Haozhong Zhang <address@hidden>

If users rely on MAP_SYNC then don't you need to fail allocation
if you can't use it?

> ---
>  util/mmap-alloc.c | 36 +++++++++++++++++++++++++++++++++++-
>  1 file changed, 35 insertions(+), 1 deletion(-)
> 
> diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
> index 2fd8cbcc6f..37b302f057 100644
> --- a/util/mmap-alloc.c
> +++ b/util/mmap-alloc.c
> @@ -18,7 +18,18 @@
>  
>  #ifdef CONFIG_LINUX
>  #include <sys/vfs.h>
> +
> +/*
> + * MAP_SHARED_VALIDATE and MAP_SYNC were introduced in 4.15 kernel, so
> + * they may not be defined when compiling on older kernels.
> + */
> +#ifndef MAP_SHARED_VALIDATE
> +#define MAP_SHARED_VALIDATE   0x3
>  #endif
> +#ifndef MAP_SYNC
> +#define MAP_SYNC              0x80000
> +#endif
> +#endif /* CONFIG_LINUX */
>  
>  size_t qemu_fd_getpagesize(int fd)
>  {

This stuff is arch-specific. I think you want to import this into
standard-headers rather than duplicate things from Linux.


> @@ -97,6 +108,7 @@ void *qemu_ram_mmap(int fd, size_t size, size_t align, 
> bool shared)
>  #endif
>      size_t offset;
>      void *ptr1;
> +    int xflags = 0;
>  
>      if (ptr == MAP_FAILED) {
>          return MAP_FAILED;
> @@ -107,12 +119,34 @@ void *qemu_ram_mmap(int fd, size_t size, size_t align, 
> bool shared)
>      assert(align >= getpagesize());
>  
>      offset = QEMU_ALIGN_UP((uintptr_t)ptr, align) - (uintptr_t)ptr;
> +
> +#if defined(__linux__)
> +    /*
> +     * If 'fd' refers to a file supporting DAX, mmap it with MAP_SYNC
> +     * will guarantee the guest write persistence without other
> +     * actions in QEMU (e.g., fsync() in QEMU).
> +     *
> +     * MAP_SHARED_VALIDATE ensures mmap with MAP_SYNC fails if
> +     * MAP_SYNC is not supported by the kernel or the file.
> +     *
> +     * On failures of mmap with xflags, QEMU will retry mmap without
> +     * xflags.

If all you are doing is retrying without, then I don't think you
even need VALIDATE.

> +     */
> +    xflags = shared ? (MAP_SHARED_VALIDATE | MAP_SYNC) : 0;
> +#endif
> +
> + retry_mmap_fd:
>      ptr1 = mmap(ptr + offset, size, PROT_READ | PROT_WRITE,
>                  MAP_FIXED |
>                  (fd == -1 ? MAP_ANONYMOUS : 0) |
> -                (shared ? MAP_SHARED : MAP_PRIVATE),
> +                (shared ? MAP_SHARED : MAP_PRIVATE) | xflags,
>                  fd, 0);
>      if (ptr1 == MAP_FAILED) {
> +        if (xflags) {
> +            xflags = 0;
> +            goto retry_mmap_fd;
> +        }
> +
>          munmap(ptr, total);
>          return MAP_FAILED;
>      }
> -- 
> 2.14.1



reply via email to

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