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>
This commit is contained in:
Faith Ekstrand 2023-11-16 18:12:14 -06:00 committed by Marge Bot
parent 0052f1a6fe
commit 78eee47471
3 changed files with 31 additions and 0 deletions

View file

@ -63,6 +63,11 @@ nvk_CreateBuffer(VkDevice device,
buffer->addr = nouveau_ws_alloc_vma(dev->ws_dev, buffer->vma_size_B, buffer->addr = nouveau_ws_alloc_vma(dev->ws_dev, buffer->vma_size_B,
alignment, sparse_residency); 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); *pBuffer = nvk_buffer_to_handle(buffer);

View file

@ -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->addr = nouveau_ws_alloc_vma(dev->ws_dev, plane->vma_size_B,
plane->nil.align_B, plane->nil.align_B,
sparse_resident); sparse_resident);
if (plane->addr == 0) {
return vk_errorf(dev, VK_ERROR_OUT_OF_DEVICE_MEMORY,
"Sparse VMA allocation failed");
}
} }
return VK_SUCCESS; return VK_SUCCESS;

View file

@ -67,6 +67,14 @@ nouveau_ws_alloc_vma(struct nouveau_ws_device *dev,
offset = util_vma_heap_alloc(&dev->vma_heap, size, align); offset = util_vma_heap_alloc(&dev->vma_heap, size, align);
simple_mtx_unlock(&dev->vma_mutex); 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) if (dev->debug_flags & NVK_DEBUG_VM)
fprintf(stderr, "alloc vma %" PRIx64 " %" PRIx64 " sparse: %d\n", fprintf(stderr, "alloc vma %" PRIx64 " %" PRIx64 " sparse: %d\n",
offset, size, sparse_resident); offset, size, sparse_resident);
@ -201,12 +209,21 @@ nouveau_ws_bo_new_locked(struct nouveau_ws_device *dev,
if (dev->has_vm_bind) { if (dev->has_vm_bind) {
bo->offset = nouveau_ws_alloc_vma(dev, bo->size, align, false); 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); 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); _mesa_hash_table_insert(dev->bos, (void *)(uintptr_t)bo->handle, bo);
return bo; return bo;
fail_gem_new:
drmCloseBufferHandle(dev->fd, req.info.handle);
FREE(bo);
return NULL;
} }
struct nouveau_ws_bo * 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)); assert(bo->size == ALIGN(bo->size, align));
bo->offset = nouveau_ws_alloc_vma(dev, bo->size, align, false); 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); nouveau_ws_bo_bind_vma(dev, bo, bo->offset, bo->size, 0, 0);
_mesa_hash_table_insert(dev->bos, (void *)(uintptr_t)handle, bo); _mesa_hash_table_insert(dev->bos, (void *)(uintptr_t)handle, bo);
return bo; return bo;
fail_calloc:
FREE(bo);
fail_fd_to_handle: fail_fd_to_handle:
drmCloseBufferHandle(dev->fd, handle); drmCloseBufferHandle(dev->fd, handle);