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);
