[PATCH v8 8/8] memory: Factor out common ram region initialization

BALATON Zoltan posted 8 patches 1 month ago
Maintainers: Pierrick Bouvier <pierrick.bouvier@linaro.org>, Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>, Gerd Hoffmann <kraxel@redhat.com>, Artyom Tarasenko <atar4qemu@gmail.com>, Max Filippov <jcmvbkbc@gmail.com>, Paolo Bonzini <pbonzini@redhat.com>, Peter Xu <peterx@redhat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>
There is a newer version of this series
[PATCH v8 8/8] memory: Factor out common ram region initialization
Posted by BALATON Zoltan 1 month ago
Introduce internal helper function to remove duplicated code from
different memory_region_init_*ram functions. Remove locall err and
error_propagate and pass errp and check return values instead.
Also shorten some function prototypes while at it.

Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
 system/memory.c | 167 +++++++++++++++++-------------------------------
 1 file changed, 58 insertions(+), 109 deletions(-)

diff --git a/system/memory.c b/system/memory.c
index 9a12224555..7781d20d41 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -1568,39 +1568,38 @@ static void memory_region_set_ops(MemoryRegion *mr,
     mr->terminates = true;
 }
 
-void memory_region_init_io(MemoryRegion *mr,
-                           Object *owner,
-                           const MemoryRegionOps *ops,
-                           void *opaque,
-                           const char *name,
-                           uint64_t size)
+void memory_region_init_io(MemoryRegion *mr, Object *owner,
+                           const MemoryRegionOps *ops, void *opaque,
+                           const char *name, uint64_t size)
 {
     memory_region_init(mr, owner, name, size);
     memory_region_set_ops(mr, ops, opaque);
 }
 
-bool memory_region_init_ram_flags_nomigrate(MemoryRegion *mr,
-                                            Object *owner,
-                                            const char *name,
-                                            uint64_t size,
-                                            uint32_t ram_flags,
-                                            Error **errp)
+static bool memory_region_set_ram_block(MemoryRegion *mr, RAMBlock *rb)
 {
-    Error *err = NULL;
-    memory_region_init(mr, owner, name, size);
     mr->ram = true;
     mr->terminates = true;
     mr->destructor = memory_region_destructor_ram;
-    mr->ram_block = qemu_ram_alloc(size, ram_flags, mr, &err);
-    if (err) {
+    mr->ram_block = rb;
+    if (!rb) {
         mr->size = int128_zero();
         object_unparent(OBJECT(mr));
-        error_propagate(errp, err);
         return false;
     }
     return true;
 }
 
+bool memory_region_init_ram_flags_nomigrate(MemoryRegion *mr, Object *owner,
+                                            const char *name, uint64_t size,
+                                            uint32_t ram_flags, Error **errp)
+{
+    RAMBlock *rb = qemu_ram_alloc(size, ram_flags, mr, errp);
+
+    memory_region_init(mr, owner, name, size);
+    return memory_region_set_ram_block(mr, rb);
+}
+
 bool memory_region_init_resizeable_ram(MemoryRegion *mr,
                                        Object *owner,
                                        const char *name,
@@ -1611,116 +1610,70 @@ bool memory_region_init_resizeable_ram(MemoryRegion *mr,
                                                        void *host),
                                        Error **errp)
 {
-    Error *err = NULL;
+    RAMBlock *rb = qemu_ram_alloc_resizeable(size, max_size, resized, mr, errp);
+
     memory_region_init(mr, owner, name, size);
-    mr->ram = true;
-    mr->terminates = true;
-    mr->destructor = memory_region_destructor_ram;
-    mr->ram_block = qemu_ram_alloc_resizeable(size, max_size, resized,
-                                              mr, &err);
-    if (err) {
-        mr->size = int128_zero();
-        object_unparent(OBJECT(mr));
-        error_propagate(errp, err);
-        return false;
-    }
-    return true;
+    return memory_region_set_ram_block(mr, rb);
 }
 
 #if defined(CONFIG_POSIX) && !defined(EMSCRIPTEN)
-bool memory_region_init_ram_from_file(MemoryRegion *mr,
-                                      Object *owner,
-                                      const char *name,
-                                      uint64_t size,
-                                      uint64_t align,
-                                      uint32_t ram_flags,
-                                      const char *path,
-                                      ram_addr_t offset,
+bool memory_region_init_ram_from_file(MemoryRegion *mr, Object *owner,
+                                      const char *name, uint64_t size,
+                                      uint64_t align, uint32_t ram_flags,
+                                      const char *path, ram_addr_t offset,
                                       Error **errp)
 {
-    Error *err = NULL;
+    RAMBlock *rb = qemu_ram_alloc_from_file(size, mr, ram_flags, path, offset,
+                                            errp);
+
     memory_region_init(mr, owner, name, size);
-    mr->ram = true;
     mr->readonly = !!(ram_flags & RAM_READONLY);
-    mr->terminates = true;
-    mr->destructor = memory_region_destructor_ram;
     mr->align = align;
-    mr->ram_block = qemu_ram_alloc_from_file(size, mr, ram_flags, path,
-                                             offset, &err);
-    if (err) {
-        mr->size = int128_zero();
-        object_unparent(OBJECT(mr));
-        error_propagate(errp, err);
-        return false;
-    }
-    return true;
+    return memory_region_set_ram_block(mr, rb);
 }
 
-bool memory_region_init_ram_from_fd(MemoryRegion *mr,
-                                    Object *owner,
-                                    const char *name,
-                                    uint64_t size,
-                                    uint32_t ram_flags,
-                                    int fd,
-                                    ram_addr_t offset,
-                                    Error **errp)
+bool memory_region_init_ram_from_fd(MemoryRegion *mr, Object *owner,
+                                    const char *name, uint64_t size,
+                                    uint32_t ram_flags, int fd,
+                                    ram_addr_t offset, Error **errp)
 {
-    Error *err = NULL;
+    RAMBlock *rb = qemu_ram_alloc_from_fd(size, size, NULL, mr, ram_flags, fd,
+                                          offset, false, errp);
+
     memory_region_init(mr, owner, name, size);
-    mr->ram = true;
     mr->readonly = !!(ram_flags & RAM_READONLY);
-    mr->terminates = true;
-    mr->destructor = memory_region_destructor_ram;
-    mr->ram_block = qemu_ram_alloc_from_fd(size, size, NULL, mr, ram_flags, fd,
-                                           offset, false, &err);
-    if (err) {
-        mr->size = int128_zero();
-        object_unparent(OBJECT(mr));
-        error_propagate(errp, err);
-        return false;
-    }
-    return true;
+    return memory_region_set_ram_block(mr, rb);
 }
 #endif
 
-void memory_region_init_ram_ptr(MemoryRegion *mr,
-                                Object *owner,
-                                const char *name,
-                                uint64_t size,
+void memory_region_init_ram_ptr(MemoryRegion *mr, Object *owner,
+                                const char *name, uint64_t size,
                                 void *ptr)
 {
-    memory_region_init(mr, owner, name, size);
-    mr->ram = true;
-    mr->terminates = true;
-    mr->destructor = memory_region_destructor_ram;
-
     /* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL.  */
     assert(ptr != NULL);
-    mr->ram_block = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_abort);
+    RAMBlock *rb = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_abort);
+
+    memory_region_init(mr, owner, name, size);
+    memory_region_set_ram_block(mr, rb);
 }
 
-void memory_region_init_ram_device_ptr(MemoryRegion *mr,
-                                       Object *owner,
-                                       const char *name,
-                                       uint64_t size,
+void memory_region_init_ram_device_ptr(MemoryRegion *mr, Object *owner,
+                                       const char *name, uint64_t size,
                                        void *ptr)
 {
-    memory_region_init_io(mr, owner, &ram_device_mem_ops, mr, name, size);
-    mr->ram = true;
-    mr->ram_device = true;
-    mr->destructor = memory_region_destructor_ram;
-
     /* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL.  */
     assert(ptr != NULL);
-    mr->ram_block = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_abort);
+    RAMBlock *rb = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_abort);
+
+    memory_region_init_io(mr, owner, &ram_device_mem_ops, mr, name, size);
+    mr->ram_device = true;
+    memory_region_set_ram_block(mr, rb);
 }
 
-void memory_region_init_alias(MemoryRegion *mr,
-                              Object *owner,
-                              const char *name,
-                              MemoryRegion *orig,
-                              hwaddr offset,
-                              uint64_t size)
+void memory_region_init_alias(MemoryRegion *mr, Object *owner,
+                              const char *name, MemoryRegion *orig,
+                              hwaddr offset, uint64_t size)
 {
     memory_region_init(mr, owner, name, size);
     mr->alias = orig;
@@ -3732,21 +3685,17 @@ bool memory_region_init_rom_device(MemoryRegion *mr, Object *owner,
                                    const char *name, uint64_t size,
                                    Error **errp)
 {
-    Error *err = NULL;
+    RAMBlock *rb = qemu_ram_alloc(size, 0, mr, errp);
 
     assert(ops);
     memory_region_init_io(mr, owner, ops, opaque, name, size);
-    mr->rom_device = true;
-    mr->destructor = memory_region_destructor_ram;
-    mr->ram_block = qemu_ram_alloc(size, 0, mr, &err);
-    if (err) {
-        mr->size = int128_zero();
-        object_unparent(OBJECT(mr));
-        error_propagate(errp, err);
-        return false;
+    if (memory_region_set_ram_block(mr, rb)) {
+        mr->ram = false;
+        mr->rom_device = true;
+        memory_region_register_ram(mr, owner);
+        return true;
     }
-    memory_region_register_ram(mr, owner);
-    return true;
+    return false;
 }
 
 /*
-- 
2.41.3
Re: [PATCH v8 8/8] memory: Factor out common ram region initialization
Posted by Akihiko Odaki 1 month ago
On 2026/03/06 10:41, BALATON Zoltan wrote:
> Introduce internal helper function to remove duplicated code from
> different memory_region_init_*ram functions. Remove locall err and
> error_propagate and pass errp and check return values instead.
> Also shorten some function prototypes while at it.
> 
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
>   system/memory.c | 167 +++++++++++++++++-------------------------------
>   1 file changed, 58 insertions(+), 109 deletions(-)
> 
> diff --git a/system/memory.c b/system/memory.c
> index 9a12224555..7781d20d41 100644
> --- a/system/memory.c
> +++ b/system/memory.c
> @@ -1568,39 +1568,38 @@ static void memory_region_set_ops(MemoryRegion *mr,
>       mr->terminates = true;
>   }
>   
> -void memory_region_init_io(MemoryRegion *mr,
> -                           Object *owner,
> -                           const MemoryRegionOps *ops,
> -                           void *opaque,
> -                           const char *name,
> -                           uint64_t size)
> +void memory_region_init_io(MemoryRegion *mr, Object *owner,
> +                           const MemoryRegionOps *ops, void *opaque,
> +                           const char *name, uint64_t size)
>   {
>       memory_region_init(mr, owner, name, size);
>       memory_region_set_ops(mr, ops, opaque);
>   }
>   
> -bool memory_region_init_ram_flags_nomigrate(MemoryRegion *mr,
> -                                            Object *owner,
> -                                            const char *name,
> -                                            uint64_t size,
> -                                            uint32_t ram_flags,
> -                                            Error **errp)
> +static bool memory_region_set_ram_block(MemoryRegion *mr, RAMBlock *rb)
>   {
> -    Error *err = NULL;
> -    memory_region_init(mr, owner, name, size);
>       mr->ram = true;
>       mr->terminates = true;
>       mr->destructor = memory_region_destructor_ram;
> -    mr->ram_block = qemu_ram_alloc(size, ram_flags, mr, &err);
> -    if (err) {
> +    mr->ram_block = rb;
> +    if (!rb) {
>           mr->size = int128_zero();
>           object_unparent(OBJECT(mr));
> -        error_propagate(errp, err);
>           return false;
>       }
>       return true;
>   }
>   
> +bool memory_region_init_ram_flags_nomigrate(MemoryRegion *mr, Object *owner,
> +                                            const char *name, uint64_t size,
> +                                            uint32_t ram_flags, Error **errp)
> +{
> +    RAMBlock *rb = qemu_ram_alloc(size, ram_flags, mr, errp);

qemu_ram_alloc() should be called after memory_region_init() since it 
may dereference mr.

Regards,
Akihiko Odaki

> +
> +    memory_region_init(mr, owner, name, size);
> +    return memory_region_set_ram_block(mr, rb);
> +}
> +
>   bool memory_region_init_resizeable_ram(MemoryRegion *mr,
>                                          Object *owner,
>                                          const char *name,
> @@ -1611,116 +1610,70 @@ bool memory_region_init_resizeable_ram(MemoryRegion *mr,
>                                                          void *host),
>                                          Error **errp)
>   {
> -    Error *err = NULL;
> +    RAMBlock *rb = qemu_ram_alloc_resizeable(size, max_size, resized, mr, errp);
> +
>       memory_region_init(mr, owner, name, size);
> -    mr->ram = true;
> -    mr->terminates = true;
> -    mr->destructor = memory_region_destructor_ram;
> -    mr->ram_block = qemu_ram_alloc_resizeable(size, max_size, resized,
> -                                              mr, &err);
> -    if (err) {
> -        mr->size = int128_zero();
> -        object_unparent(OBJECT(mr));
> -        error_propagate(errp, err);
> -        return false;
> -    }
> -    return true;
> +    return memory_region_set_ram_block(mr, rb);
>   }
>   
>   #if defined(CONFIG_POSIX) && !defined(EMSCRIPTEN)
> -bool memory_region_init_ram_from_file(MemoryRegion *mr,
> -                                      Object *owner,
> -                                      const char *name,
> -                                      uint64_t size,
> -                                      uint64_t align,
> -                                      uint32_t ram_flags,
> -                                      const char *path,
> -                                      ram_addr_t offset,
> +bool memory_region_init_ram_from_file(MemoryRegion *mr, Object *owner,
> +                                      const char *name, uint64_t size,
> +                                      uint64_t align, uint32_t ram_flags,
> +                                      const char *path, ram_addr_t offset,
>                                         Error **errp)
>   {
> -    Error *err = NULL;
> +    RAMBlock *rb = qemu_ram_alloc_from_file(size, mr, ram_flags, path, offset,
> +                                            errp);
> +
>       memory_region_init(mr, owner, name, size);
> -    mr->ram = true;
>       mr->readonly = !!(ram_flags & RAM_READONLY);
> -    mr->terminates = true;
> -    mr->destructor = memory_region_destructor_ram;
>       mr->align = align;
> -    mr->ram_block = qemu_ram_alloc_from_file(size, mr, ram_flags, path,
> -                                             offset, &err);
> -    if (err) {
> -        mr->size = int128_zero();
> -        object_unparent(OBJECT(mr));
> -        error_propagate(errp, err);
> -        return false;
> -    }
> -    return true;
> +    return memory_region_set_ram_block(mr, rb);
>   }
>   
> -bool memory_region_init_ram_from_fd(MemoryRegion *mr,
> -                                    Object *owner,
> -                                    const char *name,
> -                                    uint64_t size,
> -                                    uint32_t ram_flags,
> -                                    int fd,
> -                                    ram_addr_t offset,
> -                                    Error **errp)
> +bool memory_region_init_ram_from_fd(MemoryRegion *mr, Object *owner,
> +                                    const char *name, uint64_t size,
> +                                    uint32_t ram_flags, int fd,
> +                                    ram_addr_t offset, Error **errp)
>   {
> -    Error *err = NULL;
> +    RAMBlock *rb = qemu_ram_alloc_from_fd(size, size, NULL, mr, ram_flags, fd,
> +                                          offset, false, errp);
> +
>       memory_region_init(mr, owner, name, size);
> -    mr->ram = true;
>       mr->readonly = !!(ram_flags & RAM_READONLY);
> -    mr->terminates = true;
> -    mr->destructor = memory_region_destructor_ram;
> -    mr->ram_block = qemu_ram_alloc_from_fd(size, size, NULL, mr, ram_flags, fd,
> -                                           offset, false, &err);
> -    if (err) {
> -        mr->size = int128_zero();
> -        object_unparent(OBJECT(mr));
> -        error_propagate(errp, err);
> -        return false;
> -    }
> -    return true;
> +    return memory_region_set_ram_block(mr, rb);
>   }
>   #endif
>   
> -void memory_region_init_ram_ptr(MemoryRegion *mr,
> -                                Object *owner,
> -                                const char *name,
> -                                uint64_t size,
> +void memory_region_init_ram_ptr(MemoryRegion *mr, Object *owner,
> +                                const char *name, uint64_t size,
>                                   void *ptr)
>   {
> -    memory_region_init(mr, owner, name, size);
> -    mr->ram = true;
> -    mr->terminates = true;
> -    mr->destructor = memory_region_destructor_ram;
> -
>       /* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL.  */
>       assert(ptr != NULL);
> -    mr->ram_block = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_abort);
> +    RAMBlock *rb = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_abort);
> +
> +    memory_region_init(mr, owner, name, size);
> +    memory_region_set_ram_block(mr, rb);
>   }
>   
> -void memory_region_init_ram_device_ptr(MemoryRegion *mr,
> -                                       Object *owner,
> -                                       const char *name,
> -                                       uint64_t size,
> +void memory_region_init_ram_device_ptr(MemoryRegion *mr, Object *owner,
> +                                       const char *name, uint64_t size,
>                                          void *ptr)
>   {
> -    memory_region_init_io(mr, owner, &ram_device_mem_ops, mr, name, size);
> -    mr->ram = true;
> -    mr->ram_device = true;
> -    mr->destructor = memory_region_destructor_ram;
> -
>       /* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL.  */
>       assert(ptr != NULL);
> -    mr->ram_block = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_abort);
> +    RAMBlock *rb = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_abort);
> +
> +    memory_region_init_io(mr, owner, &ram_device_mem_ops, mr, name, size);
> +    mr->ram_device = true;
> +    memory_region_set_ram_block(mr, rb);
>   }
>   
> -void memory_region_init_alias(MemoryRegion *mr,
> -                              Object *owner,
> -                              const char *name,
> -                              MemoryRegion *orig,
> -                              hwaddr offset,
> -                              uint64_t size)
> +void memory_region_init_alias(MemoryRegion *mr, Object *owner,
> +                              const char *name, MemoryRegion *orig,
> +                              hwaddr offset, uint64_t size)
>   {
>       memory_region_init(mr, owner, name, size);
>       mr->alias = orig;
> @@ -3732,21 +3685,17 @@ bool memory_region_init_rom_device(MemoryRegion *mr, Object *owner,
>                                      const char *name, uint64_t size,
>                                      Error **errp)
>   {
> -    Error *err = NULL;
> +    RAMBlock *rb = qemu_ram_alloc(size, 0, mr, errp);
>   
>       assert(ops);
>       memory_region_init_io(mr, owner, ops, opaque, name, size);
> -    mr->rom_device = true;
> -    mr->destructor = memory_region_destructor_ram;
> -    mr->ram_block = qemu_ram_alloc(size, 0, mr, &err);
> -    if (err) {
> -        mr->size = int128_zero();
> -        object_unparent(OBJECT(mr));
> -        error_propagate(errp, err);
> -        return false;
> +    if (memory_region_set_ram_block(mr, rb)) {
> +        mr->ram = false;
> +        mr->rom_device = true;
> +        memory_region_register_ram(mr, owner);
> +        return true;
>       }
> -    memory_region_register_ram(mr, owner);
> -    return true;
> +    return false;
>   }
>   
>   /*