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

Author: Faith Ekstrand <[email protected]>
Date:   Thu Nov 16 18:12:14 2023 -0600

nvk: Handle VMA allocation failure

The chances of these happening is slim to none right now but, the moment
we throw VK_KHR_buffer_device_address into the mix, failure becomes much
more of a real possibility.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26242>

---

 src/nouveau/vulkan/nvk_buffer.c |  5 +++++
 src/nouveau/vulkan/nvk_image.c  |  4 ++++
 src/nouveau/winsys/nouveau_bo.c | 22 ++++++++++++++++++++++
 3 files changed, 31 insertions(+)

diff --git a/src/nouveau/vulkan/nvk_buffer.c b/src/nouveau/vulkan/nvk_buffer.c
index 15c130de1ed..73ce178db0a 100644
--- a/src/nouveau/vulkan/nvk_buffer.c
+++ b/src/nouveau/vulkan/nvk_buffer.c
@@ -63,6 +63,11 @@ nvk_CreateBuffer(VkDevice device,
 
       buffer->addr = nouveau_ws_alloc_vma(dev->ws_dev, buffer->vma_size_B,
                                           alignment, sparse_residency);
+      if (buffer->addr == 0) {
+         vk_buffer_destroy(&dev->vk, pAllocator, &buffer->vk);
+         return vk_errorf(dev, VK_ERROR_OUT_OF_DEVICE_MEMORY,
+                          "Sparse VMA allocation failed");
+      }
    }
 
    *pBuffer = nvk_buffer_to_handle(buffer);
diff --git a/src/nouveau/vulkan/nvk_image.c b/src/nouveau/vulkan/nvk_image.c
index 8557bef27f3..9809de14aaa 100644
--- a/src/nouveau/vulkan/nvk_image.c
+++ b/src/nouveau/vulkan/nvk_image.c
@@ -542,6 +542,10 @@ nvk_image_plane_alloc_vma(struct nvk_device *dev,
       plane->addr = nouveau_ws_alloc_vma(dev->ws_dev, plane->vma_size_B,
                                          plane->nil.align_B,
                                          sparse_resident);
+      if (plane->addr == 0) {
+         return vk_errorf(dev, VK_ERROR_OUT_OF_DEVICE_MEMORY,
+                          "Sparse VMA allocation failed");
+      }
    }
 
    return VK_SUCCESS;
diff --git a/src/nouveau/winsys/nouveau_bo.c b/src/nouveau/winsys/nouveau_bo.c
index daaa17b43b3..5e3e43b044a 100644
--- a/src/nouveau/winsys/nouveau_bo.c
+++ b/src/nouveau/winsys/nouveau_bo.c
@@ -67,6 +67,14 @@ nouveau_ws_alloc_vma(struct nouveau_ws_device *dev,
    offset = util_vma_heap_alloc(&dev->vma_heap, size, align);
    simple_mtx_unlock(&dev->vma_mutex);
 
+   if (offset == 0) {
+      if (dev->debug_flags & NVK_DEBUG_VM) {
+         fprintf(stderr, "alloc vma FAILED: %" PRIx64 " sparse: %d\n",
+                 size, sparse_resident);
+      }
+      return 0;
+   }
+
    if (dev->debug_flags & NVK_DEBUG_VM)
       fprintf(stderr, "alloc vma %" PRIx64 " %" PRIx64 " sparse: %d\n",
               offset, size, sparse_resident);
@@ -201,12 +209,21 @@ nouveau_ws_bo_new_locked(struct nouveau_ws_device *dev,
 
    if (dev->has_vm_bind) {
       bo->offset = nouveau_ws_alloc_vma(dev, bo->size, align, false);
+      if (bo->offset == 0)
+         goto fail_gem_new;
+
       nouveau_ws_bo_bind_vma(dev, bo, bo->offset, bo->size, 0, 0);
    }
 
    _mesa_hash_table_insert(dev->bos, (void *)(uintptr_t)bo->handle, bo);
 
    return bo;
+
+fail_gem_new:
+   drmCloseBufferHandle(dev->fd, req.info.handle);
+   FREE(bo);
+
+   return NULL;
 }
 
 struct nouveau_ws_bo *
@@ -271,11 +288,16 @@ nouveau_ws_bo_from_dma_buf_locked(struct 
nouveau_ws_device *dev, int fd)
    assert(bo->size == ALIGN(bo->size, align));
 
    bo->offset = nouveau_ws_alloc_vma(dev, bo->size, align, false);
+   if (bo->offset == 0)
+      goto fail_calloc;
+
    nouveau_ws_bo_bind_vma(dev, bo, bo->offset, bo->size, 0, 0);
    _mesa_hash_table_insert(dev->bos, (void *)(uintptr_t)handle, bo);
 
    return bo;
 
+fail_calloc:
+   FREE(bo);
 fail_fd_to_handle:
    drmCloseBufferHandle(dev->fd, handle);
 

Reply via email to