Mesa (master): radv: Fix memory leak on descriptor pool reset with layout_size=0.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Apr 19 19:30:42 UTC 2021


Module: Mesa
Branch: master
Commit: a144fa608d606807d8ae3af14000abe450d52907
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a144fa608d606807d8ae3af14000abe450d52907

Author: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Date:   Mon Apr 19 13:23:23 2021 +0200

radv: Fix memory leak on descriptor pool reset with  layout_size=0.

Gotta track those sets too to free them. Alse changed the search
on destroy to check for set instead of offset since offset is not
necessarily unique anymore.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/4652
CC: mesa-stable
Reviewed-by: Joshua Ashton <joshua at froggi.es>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10317>

---

 src/amd/vulkan/radv_descriptor_set.c | 90 +++++++++++++++++-------------------
 1 file changed, 43 insertions(+), 47 deletions(-)

diff --git a/src/amd/vulkan/radv_descriptor_set.c b/src/amd/vulkan/radv_descriptor_set.c
index 8f4c70aa5be..4536dd76220 100644
--- a/src/amd/vulkan/radv_descriptor_set.c
+++ b/src/amd/vulkan/radv_descriptor_set.c
@@ -583,55 +583,52 @@ radv_descriptor_set_create(struct radv_device *device, struct radv_descriptor_po
       layout_size = layout->binding[layout->binding_count - 1].offset + *variable_count * stride;
    }
    layout_size = align_u32(layout_size, 32);
-   if (layout_size) {
-      set->header.size = layout_size;
+   set->header.size = layout_size;
 
-      if (!pool->host_memory_base && pool->entry_count == pool->max_entry_count) {
-         vk_free2(&device->vk.alloc, NULL, set);
-         return vk_error(device->instance, VK_ERROR_OUT_OF_POOL_MEMORY);
+   if (!pool->host_memory_base && pool->entry_count == pool->max_entry_count) {
+      vk_free2(&device->vk.alloc, NULL, set);
+      return vk_error(device->instance, VK_ERROR_OUT_OF_POOL_MEMORY);
+   }
+
+   /* try to allocate linearly first, so that we don't spend
+    * time looking for gaps if the app only allocates &
+    * resets via the pool. */
+   if (pool->current_offset + layout_size <= pool->size) {
+      set->header.bo = pool->bo;
+      set->header.mapped_ptr = (uint32_t *)(pool->mapped_ptr + pool->current_offset);
+      set->header.va = pool->bo ? (radv_buffer_get_va(set->header.bo) + pool->current_offset) : 0;
+      if (!pool->host_memory_base) {
+         pool->entries[pool->entry_count].offset = pool->current_offset;
+         pool->entries[pool->entry_count].size = layout_size;
+         pool->entries[pool->entry_count].set = set;
+         pool->entry_count++;
       }
+      pool->current_offset += layout_size;
+   } else if (!pool->host_memory_base) {
+      uint64_t offset = 0;
+      int index;
 
-      /* try to allocate linearly first, so that we don't spend
-       * time looking for gaps if the app only allocates &
-       * resets via the pool. */
-      if (pool->current_offset + layout_size <= pool->size) {
-         set->header.bo = pool->bo;
-         set->header.mapped_ptr = (uint32_t *)(pool->mapped_ptr + pool->current_offset);
-         set->header.va =
-            pool->bo ? (radv_buffer_get_va(set->header.bo) + pool->current_offset) : 0;
-         if (!pool->host_memory_base) {
-            pool->entries[pool->entry_count].offset = pool->current_offset;
-            pool->entries[pool->entry_count].size = layout_size;
-            pool->entries[pool->entry_count].set = set;
-            pool->entry_count++;
-         }
-         pool->current_offset += layout_size;
-      } else if (!pool->host_memory_base) {
-         uint64_t offset = 0;
-         int index;
-
-         for (index = 0; index < pool->entry_count; ++index) {
-            if (pool->entries[index].offset - offset >= layout_size)
-               break;
-            offset = pool->entries[index].offset + pool->entries[index].size;
-         }
+      for (index = 0; index < pool->entry_count; ++index) {
+         if (pool->entries[index].offset - offset >= layout_size)
+            break;
+         offset = pool->entries[index].offset + pool->entries[index].size;
+      }
 
-         if (pool->size - offset < layout_size) {
-            vk_free2(&device->vk.alloc, NULL, set);
-            return vk_error(device->instance, VK_ERROR_OUT_OF_POOL_MEMORY);
-         }
-         set->header.bo = pool->bo;
-         set->header.mapped_ptr = (uint32_t *)(pool->mapped_ptr + offset);
-         set->header.va = pool->bo ? (radv_buffer_get_va(set->header.bo) + offset) : 0;
-         memmove(&pool->entries[index + 1], &pool->entries[index],
-                 sizeof(pool->entries[0]) * (pool->entry_count - index));
-         pool->entries[index].offset = offset;
-         pool->entries[index].size = layout_size;
-         pool->entries[index].set = set;
-         pool->entry_count++;
-      } else
+      if (pool->size - offset < layout_size) {
+         vk_free2(&device->vk.alloc, NULL, set);
          return vk_error(device->instance, VK_ERROR_OUT_OF_POOL_MEMORY);
-   }
+      }
+      set->header.bo = pool->bo;
+      set->header.mapped_ptr = (uint32_t *)(pool->mapped_ptr + offset);
+      set->header.va = pool->bo ? (radv_buffer_get_va(set->header.bo) + offset) : 0;
+      memmove(&pool->entries[index + 1], &pool->entries[index],
+              sizeof(pool->entries[0]) * (pool->entry_count - index));
+      pool->entries[index].offset = offset;
+      pool->entries[index].size = layout_size;
+      pool->entries[index].set = set;
+      pool->entry_count++;
+   } else
+      return vk_error(device->instance, VK_ERROR_OUT_OF_POOL_MEMORY);
 
    if (layout->has_immutable_samplers) {
       for (unsigned i = 0; i < layout->binding_count; ++i) {
@@ -661,10 +658,9 @@ radv_descriptor_set_destroy(struct radv_device *device, struct radv_descriptor_p
 {
    assert(!pool->host_memory_base);
 
-   if (free_bo && set->header.size && !pool->host_memory_base) {
-      uint32_t offset = (uint8_t *)set->header.mapped_ptr - pool->mapped_ptr;
+   if (free_bo && !pool->host_memory_base) {
       for (int i = 0; i < pool->entry_count; ++i) {
-         if (pool->entries[i].offset == offset) {
+         if (pool->entries[i].set == set) {
             memmove(&pool->entries[i], &pool->entries[i + 1],
                     sizeof(pool->entries[i]) * (pool->entry_count - i - 1));
             --pool->entry_count;



More information about the mesa-commit mailing list