Module: Mesa
Branch: main
Commit: 9bfd3997b4ea829f8033f93a0b8fa0da12873286
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=9bfd3997b4ea829f8033f93a0b8fa0da12873286

Author: Matt Coster <[email protected]>
Date:   Thu May 18 09:10:34 2023 +0100

pvr: Fix memory leaks on realloc failure in pvr_pipeline.c

Signed-off-by: Matt Coster <[email protected]>
Reviewed-by: Karmjit Mahil <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23130>

---

 src/imagination/vulkan/pvr_pipeline.c | 125 ++++++++++++++++++----------------
 1 file changed, 66 insertions(+), 59 deletions(-)

diff --git a/src/imagination/vulkan/pvr_pipeline.c 
b/src/imagination/vulkan/pvr_pipeline.c
index 26a2c83c668..05bf2b5df5c 100644
--- a/src/imagination/vulkan/pvr_pipeline.c
+++ b/src/imagination/vulkan/pvr_pipeline.c
@@ -356,7 +356,7 @@ static VkResult 
pvr_pds_vertex_attrib_program_create_and_upload(
          device->vk.enabled_features.robustBufferAccess);
    struct pvr_pds_upload *const program = &program_out->program;
    struct pvr_pds_info *const info = &program_out->info;
-   struct pvr_const_map_entry *entries_buffer;
+   struct pvr_const_map_entry *new_entries;
    ASSERTED uint32_t code_size_in_dwords;
    size_t staging_buffer_size;
    uint32_t *staging_buffer;
@@ -364,15 +364,16 @@ static VkResult 
pvr_pds_vertex_attrib_program_create_and_upload(
 
    memset(info, 0, sizeof(*info));
 
-   entries_buffer = vk_alloc2(&device->vk.alloc,
-                              allocator,
-                              const_entries_size_in_bytes,
-                              8,
-                              VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
-   if (!entries_buffer)
-      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
+   info->entries = vk_alloc2(&device->vk.alloc,
+                             allocator,
+                             const_entries_size_in_bytes,
+                             8,
+                             VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+   if (!info->entries) {
+      result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
+      goto err_out;
+   }
 
-   info->entries = entries_buffer;
    info->entries_size_in_bytes = const_entries_size_in_bytes;
 
    pvr_pds_generate_vertex_primary_program(
@@ -391,8 +392,8 @@ static VkResult 
pvr_pds_vertex_attrib_program_create_and_upload(
                               8,
                               VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
    if (!staging_buffer) {
-      vk_free2(&device->vk.alloc, allocator, entries_buffer);
-      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
+      result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
+      goto err_free_entries;
    }
 
    /* This also fills in info->entries. */
@@ -406,17 +407,17 @@ static VkResult 
pvr_pds_vertex_attrib_program_create_and_upload(
    assert(info->code_size_in_dwords <= code_size_in_dwords);
 
    /* FIXME: Add a vk_realloc2() ? */
-   entries_buffer = vk_realloc((!allocator) ? &device->vk.alloc : allocator,
-                               entries_buffer,
-                               info->entries_written_size_in_bytes,
-                               8,
-                               VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
-   if (!entries_buffer) {
-      vk_free2(&device->vk.alloc, allocator, staging_buffer);
-      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
+   new_entries = vk_realloc((!allocator) ? &device->vk.alloc : allocator,
+                            info->entries,
+                            info->entries_written_size_in_bytes,
+                            8,
+                            VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+   if (!new_entries) {
+      result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
+      goto err_free_staging_buffer;
    }
 
-   info->entries = entries_buffer;
+   info->entries = new_entries;
    info->entries_size_in_bytes = info->entries_written_size_in_bytes;
 
    /* FIXME: Figure out the define for alignment of 16. */
@@ -429,15 +430,21 @@ static VkResult 
pvr_pds_vertex_attrib_program_create_and_upload(
                                16,
                                16,
                                program);
-   if (result != VK_SUCCESS) {
-      vk_free2(&device->vk.alloc, allocator, entries_buffer);
-      vk_free2(&device->vk.alloc, allocator, staging_buffer);
-      return result;
-   }
+   if (result != VK_SUCCESS)
+      goto err_free_staging_buffer;
 
    vk_free2(&device->vk.alloc, allocator, staging_buffer);
 
    return VK_SUCCESS;
+
+err_free_staging_buffer:
+   vk_free2(&device->vk.alloc, allocator, staging_buffer);
+
+err_free_entries:
+   vk_free2(&device->vk.alloc, allocator, info->entries);
+
+err_out:
+   return result;
 }
 
 static inline void pvr_pds_vertex_attrib_program_destroy(
@@ -721,7 +728,7 @@ static VkResult 
pvr_pds_descriptor_program_create_and_upload(
       pvr_pds_get_max_descriptor_upload_const_map_size_in_bytes();
    struct pvr_pds_info *const pds_info = &descriptor_state->pds_info;
    struct pvr_pds_descriptor_program_input program = { 0 };
-   struct pvr_const_map_entry *entries_buffer;
+   struct pvr_const_map_entry *new_entries;
    ASSERTED uint32_t code_size_in_dwords;
    uint32_t staging_buffer_size;
    uint32_t *staging_buffer;
@@ -807,18 +814,16 @@ static VkResult 
pvr_pds_descriptor_program_create_and_upload(
       program.addr_literal_count = addr_literals;
    }
 
-   entries_buffer = vk_alloc2(&device->vk.alloc,
-                              allocator,
-                              const_entries_size_in_bytes,
-                              8,
-                              VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
-   if (!entries_buffer) {
-      pvr_bo_suballoc_free(descriptor_state->static_consts);
-
-      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
+   pds_info->entries = vk_alloc2(&device->vk.alloc,
+                                 allocator,
+                                 const_entries_size_in_bytes,
+                                 8,
+                                 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+   if (!pds_info->entries) {
+      result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
+      goto err_free_static_consts;
    }
 
-   pds_info->entries = entries_buffer;
    pds_info->entries_size_in_bytes = const_entries_size_in_bytes;
 
    pvr_pds_generate_descriptor_upload_program(&program, NULL, pds_info);
@@ -827,7 +832,7 @@ static VkResult 
pvr_pds_descriptor_program_create_and_upload(
    staging_buffer_size = PVR_DW_TO_BYTES(pds_info->code_size_in_dwords);
 
    if (!staging_buffer_size) {
-      vk_free2(&device->vk.alloc, allocator, entries_buffer);
+      vk_free2(&device->vk.alloc, allocator, pds_info->entries);
 
       *descriptor_state = (struct pvr_stage_allocation_descriptor_state){ 0 };
 
@@ -840,10 +845,8 @@ static VkResult 
pvr_pds_descriptor_program_create_and_upload(
                               8,
                               VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
    if (!staging_buffer) {
-      pvr_bo_suballoc_free(descriptor_state->static_consts);
-      vk_free2(&device->vk.alloc, allocator, entries_buffer);
-
-      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
+      result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
+      goto err_free_entries;
    }
 
    pvr_pds_generate_descriptor_upload_program(&program,
@@ -853,19 +856,17 @@ static VkResult 
pvr_pds_descriptor_program_create_and_upload(
    assert(pds_info->code_size_in_dwords <= code_size_in_dwords);
 
    /* FIXME: use vk_realloc2() ? */
-   entries_buffer = vk_realloc((!allocator) ? &device->vk.alloc : allocator,
-                               entries_buffer,
-                               pds_info->entries_written_size_in_bytes,
-                               8,
-                               VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
-   if (!entries_buffer) {
-      pvr_bo_suballoc_free(descriptor_state->static_consts);
-      vk_free2(&device->vk.alloc, allocator, staging_buffer);
-
-      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
+   new_entries = vk_realloc((!allocator) ? &device->vk.alloc : allocator,
+                            pds_info->entries,
+                            pds_info->entries_written_size_in_bytes,
+                            8,
+                            VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+   if (!new_entries) {
+      result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
+      goto err_free_staging_buffer;
    }
 
-   pds_info->entries = entries_buffer;
+   pds_info->entries = new_entries;
    pds_info->entries_size_in_bytes = pds_info->entries_written_size_in_bytes;
 
    /* FIXME: Figure out the define for alignment of 16. */
@@ -878,17 +879,23 @@ static VkResult 
pvr_pds_descriptor_program_create_and_upload(
                                16,
                                16,
                                &descriptor_state->pds_code);
-   if (result != VK_SUCCESS) {
-      pvr_bo_suballoc_free(descriptor_state->static_consts);
-      vk_free2(&device->vk.alloc, allocator, entries_buffer);
-      vk_free2(&device->vk.alloc, allocator, staging_buffer);
-
-      return result;
-   }
+   if (result != VK_SUCCESS)
+      goto err_free_staging_buffer;
 
    vk_free2(&device->vk.alloc, allocator, staging_buffer);
 
    return VK_SUCCESS;
+
+err_free_staging_buffer:
+   vk_free2(&device->vk.alloc, allocator, staging_buffer);
+
+err_free_entries:
+   vk_free2(&device->vk.alloc, allocator, pds_info->entries);
+
+err_free_static_consts:
+   pvr_bo_suballoc_free(descriptor_state->static_consts);
+
+   return result;
 }
 
 static void pvr_pds_descriptor_program_destroy(

Reply via email to