[PATCH v1 07/13] util/mmap-alloc: Factor out populating of memory to mmap_populate()

David Hildenbrand posted 13 patches 5 years, 9 months ago
Maintainers: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>, Paolo Bonzini <pbonzini@redhat.com>, Stefan Weil <sw@weilnetz.de>, Richard Henderson <rth@twiddle.net>, Eduardo Habkost <ehabkost@redhat.com>
There is a newer version of this series
[PATCH v1 07/13] util/mmap-alloc: Factor out populating of memory to mmap_populate()
Posted by David Hildenbrand 5 years, 9 months ago
We want to populate memory within a reserved memory region. Let's factor
that out.

Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Greg Kurz <groug@kaod.org>
Cc: Murilo Opsfelder Araujo <muriloo@linux.ibm.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
 util/mmap-alloc.c | 89 +++++++++++++++++++++++++----------------------
 1 file changed, 47 insertions(+), 42 deletions(-)

diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
index 43a26f38a8..f043ccb0ab 100644
--- a/util/mmap-alloc.c
+++ b/util/mmap-alloc.c
@@ -114,6 +114,50 @@ static void *mmap_reserve(size_t size, int fd)
     return mmap(0, size, PROT_NONE, flags, fd, 0);
 }
 
+/*
+ * Populate memory in a reserved region from the given fd (if any).
+ */
+static void *mmap_populate(void *ptr, size_t size, int fd, bool shared,
+                           bool is_pmem)
+{
+    int map_sync_flags = 0;
+    int flags = MAP_FIXED;
+    void *new_ptr;
+
+    flags |= fd == -1 ? MAP_ANONYMOUS : 0;
+    flags |= shared ? MAP_SHARED : MAP_PRIVATE;
+    if (shared && is_pmem) {
+        map_sync_flags = MAP_SYNC | MAP_SHARED_VALIDATE;
+    }
+
+    new_ptr = mmap(ptr, size, PROT_READ | PROT_WRITE, flags | map_sync_flags,
+                   fd, 0);
+    if (new_ptr == MAP_FAILED && map_sync_flags) {
+        if (errno == ENOTSUP) {
+            char *proc_link = g_strdup_printf("/proc/self/fd/%d", fd);
+            char *file_name = g_malloc0(PATH_MAX);
+            int len = readlink(proc_link, file_name, PATH_MAX - 1);
+
+            if (len < 0) {
+                len = 0;
+            }
+            file_name[len] = '\0';
+            fprintf(stderr, "Warning: requesting persistence across crashes "
+                    "for backend file %s failed. Proceeding without "
+                    "persistence, data might become corrupted in case of host "
+                    "crash.\n", file_name);
+            g_free(proc_link);
+            g_free(file_name);
+        }
+        /*
+         * If mmap failed with MAP_SHARED_VALIDATE | MAP_SYNC, we will try
+         * again without these flags to handle backwards compatibility.
+         */
+        new_ptr = mmap(ptr, size, PROT_READ | PROT_WRITE, flags, fd, 0);
+    }
+    return new_ptr;
+}
+
 static inline size_t mmap_pagesize(int fd)
 {
 #if defined(__powerpc64__) && defined(__linux__)
@@ -131,12 +175,8 @@ void *qemu_ram_mmap(int fd,
                     bool is_pmem)
 {
     const size_t pagesize = mmap_pagesize(fd);
-    int flags;
-    int map_sync_flags = 0;
-    size_t offset;
-    size_t total;
-    void *guardptr;
-    void *ptr;
+    size_t offset, total;
+    void *ptr, *guardptr;
 
     /*
      * Note: this always allocates at least one extra page of virtual address
@@ -153,44 +193,9 @@ void *qemu_ram_mmap(int fd,
     /* Always align to host page size */
     assert(align >= pagesize);
 
-    flags = MAP_FIXED;
-    flags |= fd == -1 ? MAP_ANONYMOUS : 0;
-    flags |= shared ? MAP_SHARED : MAP_PRIVATE;
-    if (shared && is_pmem) {
-        map_sync_flags = MAP_SYNC | MAP_SHARED_VALIDATE;
-    }
-
     offset = QEMU_ALIGN_UP((uintptr_t)guardptr, align) - (uintptr_t)guardptr;
 
-    ptr = mmap(guardptr + offset, size, PROT_READ | PROT_WRITE,
-               flags | map_sync_flags, fd, 0);
-
-    if (ptr == MAP_FAILED && map_sync_flags) {
-        if (errno == ENOTSUP) {
-            char *proc_link, *file_name;
-            int len;
-            proc_link = g_strdup_printf("/proc/self/fd/%d", fd);
-            file_name = g_malloc0(PATH_MAX);
-            len = readlink(proc_link, file_name, PATH_MAX - 1);
-            if (len < 0) {
-                len = 0;
-            }
-            file_name[len] = '\0';
-            fprintf(stderr, "Warning: requesting persistence across crashes "
-                    "for backend file %s failed. Proceeding without "
-                    "persistence, data might become corrupted in case of host "
-                    "crash.\n", file_name);
-            g_free(proc_link);
-            g_free(file_name);
-        }
-        /*
-         * if map failed with MAP_SHARED_VALIDATE | MAP_SYNC,
-         * we will remove these flags to handle compatibility.
-         */
-        ptr = mmap(guardptr + offset, size, PROT_READ | PROT_WRITE,
-                   flags, fd, 0);
-    }
-
+    ptr = mmap_populate(guardptr + offset, size, fd, shared, is_pmem);
     if (ptr == MAP_FAILED) {
         munmap(guardptr, total);
         return MAP_FAILED;
-- 
2.24.1


Re: [PATCH v1 07/13] util/mmap-alloc: Factor out populating of memory to mmap_populate()
Posted by Richard Henderson 5 years, 9 months ago
On 2/3/20 6:31 PM, David Hildenbrand wrote:
> We want to populate memory within a reserved memory region. Let's factor
> that out.
> 
> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> Cc: Greg Kurz <groug@kaod.org>
> Cc: Murilo Opsfelder Araujo <muriloo@linux.ibm.com>
> Cc: Eduardo Habkost <ehabkost@redhat.com>
> Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
>  util/mmap-alloc.c | 89 +++++++++++++++++++++++++----------------------
>  1 file changed, 47 insertions(+), 42 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


Re: [PATCH v1 07/13] util/mmap-alloc: Factor out populating of memory to mmap_populate()
Posted by Murilo Opsfelder Araújo 5 years, 9 months ago
Hello, David.

On 2/3/20 3:31 PM, David Hildenbrand wrote:
> We want to populate memory within a reserved memory region. Let's factor
> that out.
>
> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> Cc: Greg Kurz <groug@kaod.org>
> Cc: Murilo Opsfelder Araujo <muriloo@linux.ibm.com>
> Cc: Eduardo Habkost <ehabkost@redhat.com>
> Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---

Acked-by: Murilo Opsfelder Araujo <muriloo@linux.ibm.com>

A minor comment below.

>   util/mmap-alloc.c | 89 +++++++++++++++++++++++++----------------------
>   1 file changed, 47 insertions(+), 42 deletions(-)
>
> diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
> index 43a26f38a8..f043ccb0ab 100644
> --- a/util/mmap-alloc.c
> +++ b/util/mmap-alloc.c
> @@ -114,6 +114,50 @@ static void *mmap_reserve(size_t size, int fd)
>       return mmap(0, size, PROT_NONE, flags, fd, 0);
>   }
>
> +/*
> + * Populate memory in a reserved region from the given fd (if any).
> + */
> +static void *mmap_populate(void *ptr, size_t size, int fd, bool shared,
> +                           bool is_pmem)
> +{
> +    int map_sync_flags = 0;
> +    int flags = MAP_FIXED;
> +    void *new_ptr;

Do you think another name would be welcome here, e.g.: "populated_ptr" or
"populated_memptr" or just "populated"?

> +
> +    flags |= fd == -1 ? MAP_ANONYMOUS : 0;
> +    flags |= shared ? MAP_SHARED : MAP_PRIVATE;
> +    if (shared && is_pmem) {
> +        map_sync_flags = MAP_SYNC | MAP_SHARED_VALIDATE;
> +    }
> +
> +    new_ptr = mmap(ptr, size, PROT_READ | PROT_WRITE, flags | map_sync_flags,
> +                   fd, 0);
> +    if (new_ptr == MAP_FAILED && map_sync_flags) {
> +        if (errno == ENOTSUP) {
> +            char *proc_link = g_strdup_printf("/proc/self/fd/%d", fd);
> +            char *file_name = g_malloc0(PATH_MAX);
> +            int len = readlink(proc_link, file_name, PATH_MAX - 1);
> +
> +            if (len < 0) {
> +                len = 0;
> +            }
> +            file_name[len] = '\0';
> +            fprintf(stderr, "Warning: requesting persistence across crashes "
> +                    "for backend file %s failed. Proceeding without "
> +                    "persistence, data might become corrupted in case of host "
> +                    "crash.\n", file_name);
> +            g_free(proc_link);
> +            g_free(file_name);
> +        }
> +        /*
> +         * If mmap failed with MAP_SHARED_VALIDATE | MAP_SYNC, we will try
> +         * again without these flags to handle backwards compatibility.
> +         */
> +        new_ptr = mmap(ptr, size, PROT_READ | PROT_WRITE, flags, fd, 0);
> +    }
> +    return new_ptr;
> +}
> +
>   static inline size_t mmap_pagesize(int fd)
>   {
>   #if defined(__powerpc64__) && defined(__linux__)
> @@ -131,12 +175,8 @@ void *qemu_ram_mmap(int fd,
>                       bool is_pmem)
>   {
>       const size_t pagesize = mmap_pagesize(fd);
> -    int flags;
> -    int map_sync_flags = 0;
> -    size_t offset;
> -    size_t total;
> -    void *guardptr;
> -    void *ptr;
> +    size_t offset, total;
> +    void *ptr, *guardptr;
>
>       /*
>        * Note: this always allocates at least one extra page of virtual address
> @@ -153,44 +193,9 @@ void *qemu_ram_mmap(int fd,
>       /* Always align to host page size */
>       assert(align >= pagesize);
>
> -    flags = MAP_FIXED;
> -    flags |= fd == -1 ? MAP_ANONYMOUS : 0;
> -    flags |= shared ? MAP_SHARED : MAP_PRIVATE;
> -    if (shared && is_pmem) {
> -        map_sync_flags = MAP_SYNC | MAP_SHARED_VALIDATE;
> -    }
> -
>       offset = QEMU_ALIGN_UP((uintptr_t)guardptr, align) - (uintptr_t)guardptr;
>
> -    ptr = mmap(guardptr + offset, size, PROT_READ | PROT_WRITE,
> -               flags | map_sync_flags, fd, 0);
> -
> -    if (ptr == MAP_FAILED && map_sync_flags) {
> -        if (errno == ENOTSUP) {
> -            char *proc_link, *file_name;
> -            int len;
> -            proc_link = g_strdup_printf("/proc/self/fd/%d", fd);
> -            file_name = g_malloc0(PATH_MAX);
> -            len = readlink(proc_link, file_name, PATH_MAX - 1);
> -            if (len < 0) {
> -                len = 0;
> -            }
> -            file_name[len] = '\0';
> -            fprintf(stderr, "Warning: requesting persistence across crashes "
> -                    "for backend file %s failed. Proceeding without "
> -                    "persistence, data might become corrupted in case of host "
> -                    "crash.\n", file_name);
> -            g_free(proc_link);
> -            g_free(file_name);
> -        }
> -        /*
> -         * if map failed with MAP_SHARED_VALIDATE | MAP_SYNC,
> -         * we will remove these flags to handle compatibility.
> -         */
> -        ptr = mmap(guardptr + offset, size, PROT_READ | PROT_WRITE,
> -                   flags, fd, 0);
> -    }
> -
> +    ptr = mmap_populate(guardptr + offset, size, fd, shared, is_pmem);
>       if (ptr == MAP_FAILED) {
>           munmap(guardptr, total);
>           return MAP_FAILED;
>
--
Murilo

Re: [PATCH v1 07/13] util/mmap-alloc: Factor out populating of memory to mmap_populate()
Posted by David Hildenbrand 5 years, 9 months ago
On 05.02.20 20:56, Murilo Opsfelder Araújo wrote:
> Hello, David.
> 
> On 2/3/20 3:31 PM, David Hildenbrand wrote:
>> We want to populate memory within a reserved memory region. Let's factor
>> that out.
>>
>> Cc: "Michael S. Tsirkin" <mst@redhat.com>
>> Cc: Greg Kurz <groug@kaod.org>
>> Cc: Murilo Opsfelder Araujo <muriloo@linux.ibm.com>
>> Cc: Eduardo Habkost <ehabkost@redhat.com>
>> Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
>> Signed-off-by: David Hildenbrand <david@redhat.com>
>> ---
> 
> Acked-by: Murilo Opsfelder Araujo <muriloo@linux.ibm.com>
> 
> A minor comment below.
> 
>>   util/mmap-alloc.c | 89 +++++++++++++++++++++++++----------------------
>>   1 file changed, 47 insertions(+), 42 deletions(-)
>>
>> diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
>> index 43a26f38a8..f043ccb0ab 100644
>> --- a/util/mmap-alloc.c
>> +++ b/util/mmap-alloc.c
>> @@ -114,6 +114,50 @@ static void *mmap_reserve(size_t size, int fd)
>>       return mmap(0, size, PROT_NONE, flags, fd, 0);
>>   }
>>
>> +/*
>> + * Populate memory in a reserved region from the given fd (if any).
>> + */
>> +static void *mmap_populate(void *ptr, size_t size, int fd, bool shared,
>> +                           bool is_pmem)
>> +{
>> +    int map_sync_flags = 0;
>> +    int flags = MAP_FIXED;
>> +    void *new_ptr;
> 
> Do you think another name would be welcome here, e.g.: "populated_ptr" or
> "populated_memptr" or just "populated"?

I'll go with populated_ptr - thanks!


-- 
Thanks,

David / dhildenb