diff --git a/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau.h b/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau.h index 60b1237c65d..0a0af67d9d6 100644 --- a/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau.h +++ b/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau.h @@ -7,6 +7,8 @@ #include "nvkmd/nvkmd.h" #include "vk_drm_syncobj.h" +#include "util/simple_mtx.h" +#include "util/vma.h" #include "drm-uapi/nouveau_drm.h" @@ -35,10 +37,20 @@ VkResult nvkmd_nouveau_try_create_pdev(struct _drmDevice *drm_device, enum nvk_debug debug_flags, struct nvkmd_pdev **pdev_out); +#define NVKMD_NOUVEAU_HEAP_START ((uint64_t)4096) +#define NVKMD_NOUVEAU_HEAP_END ((uint64_t)(1ull << 38)) +#define NVKMD_NOUVEAU_REPLAY_HEAP_START NVKMD_NOUVEAU_HEAP_END +#define NVKMD_NOUVEAU_REPLAY_HEAP_END \ + ((uint64_t)NOUVEAU_WS_DEVICE_KERNEL_RESERVATION_START) + struct nvkmd_nouveau_dev { struct nvkmd_dev base; struct nouveau_ws_device *ws_dev; + + simple_mtx_t heap_mutex; + struct util_vma_heap heap; + struct util_vma_heap replay_heap; }; NVKMD_DECL_SUBCLASS(dev, nouveau); @@ -75,18 +87,11 @@ VkResult nvkmd_nouveau_import_dma_buf(struct nvkmd_dev *dev, struct nvkmd_nouveau_va { struct nvkmd_va base; - struct nouveau_ws_device *dev; + struct nvkmd_nouveau_dev *dev; }; NVKMD_DECL_SUBCLASS(va, nouveau); -/* Internal helper to create a VA object for already allocated VA */ -VkResult nvkmd_nouveau_va_create(struct nvkmd_nouveau_dev *dev, - struct vk_object_base *log_obj, - enum nvkmd_va_flags flags, uint8_t pte_kind, - uint64_t addr, uint64_t size_B, - struct nvkmd_va **va_out); - VkResult nvkmd_nouveau_alloc_va(struct nvkmd_dev *dev, struct vk_object_base *log_obj, enum nvkmd_va_flags flags, uint8_t pte_kind, diff --git a/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_dev.c b/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_dev.c index bdf971192fd..51fdc70ba7f 100644 --- a/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_dev.c +++ b/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_dev.c @@ -39,6 +39,18 @@ nvkmd_nouveau_create_dev(struct nvkmd_pdev *_pdev, "Failed to get DRM device: %m"); } + simple_mtx_init(&dev->heap_mutex, mtx_plain); + + STATIC_ASSERT(NVKMD_NOUVEAU_HEAP_START < NVKMD_NOUVEAU_HEAP_END); + util_vma_heap_init(&dev->heap, NVKMD_NOUVEAU_HEAP_START, + NVKMD_NOUVEAU_HEAP_END - NVKMD_NOUVEAU_HEAP_START); + + STATIC_ASSERT(NVKMD_NOUVEAU_REPLAY_HEAP_START < + NVKMD_NOUVEAU_REPLAY_HEAP_END); + util_vma_heap_init(&dev->replay_heap, + NVKMD_NOUVEAU_REPLAY_HEAP_START, + NVKMD_NOUVEAU_REPLAY_HEAP_END - NVKMD_NOUVEAU_REPLAY_HEAP_START); + *dev_out = &dev->base; return VK_SUCCESS; diff --git a/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_mem.c b/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_mem.c index 25f8cbe369b..7618481928d 100644 --- a/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_mem.c +++ b/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_mem.c @@ -23,11 +23,12 @@ nvkmd_nouveau_alloc_mem(struct nvkmd_dev *dev, static VkResult create_mem_or_close_bo(struct nvkmd_nouveau_dev *dev, struct vk_object_base *log_obj, + uint64_t va_align_B, uint8_t pte_kind, enum nvkmd_mem_flags flags, - uint8_t pte_kind, struct nouveau_ws_bo *bo, struct nvkmd_mem **mem_out) { + const uint64_t size_B = bo->size; VkResult result; struct nvkmd_nouveau_mem *mem = CALLOC_STRUCT(nvkmd_nouveau_mem); @@ -36,23 +37,31 @@ create_mem_or_close_bo(struct nvkmd_nouveau_dev *dev, goto fail_bo; } - struct nvkmd_va *va; - result = nvkmd_nouveau_va_create(dev, log_obj, 0 /* flags */, pte_kind, - bo->offset, bo->size, &va); - if (result != VK_SUCCESS) - goto fail_mem; - mem->base.ops = &nvkmd_nouveau_mem_ops; mem->base.refcnt = 1; mem->base.flags = flags; - mem->base.size_B = bo->size; - mem->base.va = va; + mem->base.size_B = size_B; mem->bo = bo; + result = nvkmd_dev_alloc_va(&dev->base, log_obj, + 0 /* flags */, pte_kind, + size_B, va_align_B, + 0 /* fixed_addr */, + &mem->base.va); + if (result != VK_SUCCESS) + goto fail_mem; + + result = nvkmd_va_bind_mem(mem->base.va, log_obj, 0 /* va_offset_B */, + &mem->base, 0 /* mem_offset_B */, size_B); + if (result != VK_SUCCESS) + goto fail_va; + *mem_out = &mem->base; return VK_SUCCESS; +fail_va: + nvkmd_va_free(mem->base.va); fail_mem: FREE(mem); fail_bo: @@ -83,8 +92,8 @@ nvkmd_nouveau_alloc_tiled_mem(struct nvkmd_dev *_dev, if (bo == NULL) return vk_errorf(log_obj, VK_ERROR_OUT_OF_DEVICE_MEMORY, "%m"); - return create_mem_or_close_bo(dev, log_obj, flags, - pte_kind, bo, mem_out); + return create_mem_or_close_bo(dev, log_obj, align_B, pte_kind, + flags, bo, mem_out); } VkResult @@ -98,8 +107,11 @@ nvkmd_nouveau_import_dma_buf(struct nvkmd_dev *_dev, if (bo == NULL) return vk_errorf(log_obj, VK_ERROR_INVALID_EXTERNAL_HANDLE, "%m"); - return create_mem_or_close_bo(dev, log_obj, (int)bo->flags, - 0 /* pte_kind */, bo, mem_out); + return create_mem_or_close_bo(dev, log_obj, + 0 /* align_B */, + 0 /* pte_kind */, + (int)bo->flags, + bo, mem_out); } static void @@ -107,7 +119,7 @@ nvkmd_nouveau_mem_free(struct nvkmd_mem *_mem) { struct nvkmd_nouveau_mem *mem = nvkmd_nouveau_mem(_mem); - FREE((void *)mem->base.va); + nvkmd_va_free(mem->base.va); nouveau_ws_bo_destroy(mem->bo); FREE(mem); } diff --git a/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_va.c b/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_va.c index bd3c9c6c52b..f5c58c4e999 100644 --- a/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_va.c +++ b/src/nouveau/vulkan/nvkmd/nouveau/nvkmd_nouveau_va.c @@ -6,27 +6,107 @@ #include "nvkmd_nouveau.h" #include "nouveau_bo.h" +#include "util/bitscan.h" #include "vk_log.h" -VkResult -nvkmd_nouveau_va_create(struct nvkmd_nouveau_dev *dev, - struct vk_object_base *log_obj, - enum nvkmd_va_flags flags, uint8_t pte_kind, - uint64_t addr, uint64_t size_B, - struct nvkmd_va **va_out) +#include +#include +#include + +static VkResult MUST_CHECK +alloc_heap_addr_locked(struct nvkmd_nouveau_dev *dev, + struct vk_object_base *log_obj, + enum nvkmd_va_flags flags, + uint64_t size_B, uint64_t align_B, + uint64_t fixed_addr, uint64_t *addr_out) { - struct nvkmd_nouveau_va *va = CALLOC_STRUCT(nvkmd_nouveau_va); - if (va == NULL) - return vk_error(log_obj, VK_ERROR_OUT_OF_HOST_MEMORY); + if (flags & NVKMD_VA_ALLOC_FIXED) { + assert(flags & NVKMD_VA_REPLAY); + if (fixed_addr < NVKMD_NOUVEAU_REPLAY_HEAP_START || + fixed_addr >= NVKMD_NOUVEAU_REPLAY_HEAP_END) { + return vk_errorf(log_obj, VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, + "Capture address 0x%" PRIx64 " not in the reaplay " + "heap address range [0x%" PRIx64 ", 0x%" PRIx64 ")", + fixed_addr, NVKMD_NOUVEAU_REPLAY_HEAP_START, + NVKMD_NOUVEAU_REPLAY_HEAP_END); + } - va->base.ops = &nvkmd_nouveau_va_ops; - va->base.flags = flags; - va->base.pte_kind = pte_kind; - va->base.addr = addr; - va->base.size_B = size_B; - va->dev = dev->ws_dev; + if (fixed_addr & (align_B - 1)) { + return vk_errorf(log_obj, VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, + "Unaligned capture address: 0x%" PRIx64, fixed_addr); + } - *va_out = &va->base; + if (!util_vma_heap_alloc_addr(&dev->replay_heap, fixed_addr, size_B)) { + return vk_errorf(log_obj, VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, + "Replay address collision: 0x%" PRIx64, fixed_addr); + } + + *addr_out = fixed_addr; + } else if (flags & NVKMD_VA_REPLAY) { + *addr_out = util_vma_heap_alloc(&dev->replay_heap, size_B, align_B); + if (*addr_out == 0) + return vk_errorf(log_obj, VK_ERROR_OUT_OF_DEVICE_MEMORY, + "Failed to allocate virtual address range"); + } else { + *addr_out = util_vma_heap_alloc(&dev->heap, size_B, align_B); + if (*addr_out == 0) + return vk_errorf(log_obj, VK_ERROR_OUT_OF_DEVICE_MEMORY, + "Failed to allocate virtual address range"); + } + + return VK_SUCCESS; +} + +static VkResult MUST_CHECK +alloc_heap_addr(struct nvkmd_nouveau_dev *dev, + struct vk_object_base *log_obj, + enum nvkmd_va_flags flags, + uint64_t size_B, uint64_t align_B, + uint64_t fixed_addr, uint64_t *addr_out) +{ + simple_mtx_lock(&dev->heap_mutex); + VkResult result = alloc_heap_addr_locked(dev, log_obj, flags, + size_B, align_B, + fixed_addr, addr_out); + simple_mtx_unlock(&dev->heap_mutex); + return result; +} + +static void +free_heap_addr(struct nvkmd_nouveau_dev *dev, + enum nvkmd_va_flags flags, + uint64_t addr, uint64_t size_B) +{ + simple_mtx_lock(&dev->heap_mutex); + if (flags & NVKMD_VA_REPLAY) { + assert(addr >= NVKMD_NOUVEAU_REPLAY_HEAP_START); + assert(addr <= NVKMD_NOUVEAU_REPLAY_HEAP_END); + assert(addr + size_B <= NVKMD_NOUVEAU_REPLAY_HEAP_END); + + util_vma_heap_free(&dev->replay_heap, addr, size_B); + } else { + assert(addr >= NVKMD_NOUVEAU_HEAP_START); + assert(addr <= NVKMD_NOUVEAU_HEAP_END); + assert(addr + size_B <= NVKMD_NOUVEAU_HEAP_END); + + util_vma_heap_free(&dev->heap, addr, size_B); + } + simple_mtx_unlock(&dev->heap_mutex); +} + +static VkResult MUST_CHECK +vm_bind(struct nvkmd_nouveau_dev *dev, + struct vk_object_base *log_obj, + struct drm_nouveau_vm_bind_op *op) +{ + struct drm_nouveau_vm_bind vmbind = { + .op_count = 1, + .op_ptr = (uint64_t)(uintptr_t)(void *)op, + }; + int err = drmCommandWriteRead(dev->ws_dev->fd, DRM_NOUVEAU_VM_BIND, + &vmbind, sizeof(vmbind)); + if (err) + return vk_errorf(log_obj, VK_ERROR_UNKNOWN, "vm_bind failed: %m"); return VK_SUCCESS; } @@ -39,43 +119,84 @@ nvkmd_nouveau_alloc_va(struct nvkmd_dev *_dev, uint64_t fixed_addr, struct nvkmd_va **va_out) { struct nvkmd_nouveau_dev *dev = nvkmd_nouveau_dev(_dev); - - assert((fixed_addr == 0) == !(flags & NVKMD_VA_ALLOC_FIXED)); + VkResult result; struct nvkmd_nouveau_va *va = CALLOC_STRUCT(nvkmd_nouveau_va); if (va == NULL) return vk_error(log_obj, VK_ERROR_OUT_OF_HOST_MEMORY); - va->base.addr = nouveau_ws_alloc_vma(dev->ws_dev, fixed_addr, - size_B, align_B, - flags & NVKMD_VA_REPLAY, - flags & NVKMD_VA_SPARSE); - if (va->base.addr == 0) { - FREE(va); - return vk_errorf(log_obj, VK_ERROR_OUT_OF_DEVICE_MEMORY, - "Failed to allocate virtual address range: %m"); + /* if the caller doesn't care, use the GPU page size */ + if (align_B == 0) + align_B = 0x1000; + + assert((fixed_addr == 0) == !(flags & NVKMD_VA_ALLOC_FIXED)); + + result = alloc_heap_addr(dev, log_obj, flags, size_B, align_B, + fixed_addr, &va->base.addr); + if (result != VK_SUCCESS) + goto fail_alloc; + + if (flags & NVKMD_VA_SPARSE) { + struct drm_nouveau_vm_bind_op bind = { + .op = DRM_NOUVEAU_VM_BIND_OP_MAP, + .addr = va->base.addr, + .range = size_B, + .flags = DRM_NOUVEAU_VM_BIND_SPARSE, + }; + result = vm_bind(dev, log_obj, &bind); + if (result != VK_SUCCESS) + goto fail_addr; } va->base.ops = &nvkmd_nouveau_va_ops; va->base.flags = flags; va->base.pte_kind = pte_kind; va->base.size_B = size_B; - va->dev = dev->ws_dev; + va->dev = dev; *va_out = &va->base; return VK_SUCCESS; + +fail_addr: + free_heap_addr(dev, flags, va->base.addr, size_B); +fail_alloc: + FREE(va); + + return result; } static void nvkmd_nouveau_va_free(struct nvkmd_va *_va) { struct nvkmd_nouveau_va *va = nvkmd_nouveau_va(_va); + VkResult result = VK_SUCCESS; + + STATIC_ASSERT(VK_SUCCESS == 0); + + { + struct drm_nouveau_vm_bind_op bind = { + .op = DRM_NOUVEAU_VM_BIND_OP_UNMAP, + .addr = va->base.addr, + .range = va->base.size_B, + }; + result |= vm_bind(va->dev, NULL, &bind); + } + + if (va->base.flags & NVKMD_VA_SPARSE) { + struct drm_nouveau_vm_bind_op bind = { + .op = DRM_NOUVEAU_VM_BIND_OP_UNMAP, + .addr = va->base.addr, + .range = va->base.size_B, + .flags = DRM_NOUVEAU_VM_BIND_SPARSE, + }; + result |= vm_bind(va->dev, NULL, &bind); + } + + /* If unbinding fails, we leak the VA range */ + if (result == VK_SUCCESS) + free_heap_addr(va->dev, va->base.flags, va->base.addr, va->base.size_B); - nouveau_ws_bo_unbind_vma(va->dev, va->base.addr, va->base.size_B); - nouveau_ws_free_vma(va->dev, va->base.addr, va->base.size_B, - va->base.flags & NVKMD_VA_REPLAY, - va->base.flags & NVKMD_VA_SPARSE); FREE(va); } @@ -90,12 +211,17 @@ nvkmd_nouveau_va_bind_mem(struct nvkmd_va *_va, struct nvkmd_nouveau_va *va = nvkmd_nouveau_va(_va); struct nvkmd_nouveau_mem *mem = nvkmd_nouveau_mem(_mem); - assert(va->dev == mem->bo->dev); - nouveau_ws_bo_bind_vma(va->dev, mem->bo, - va->base.addr + va_offset_B, range_B, - mem_offset_B, va->base.pte_kind); + assert(mem->bo->dev == va->dev->ws_dev); - return VK_SUCCESS; + struct drm_nouveau_vm_bind_op bind = { + .op = DRM_NOUVEAU_VM_BIND_OP_MAP, + .handle = mem->bo->handle, + .addr = va->base.addr + va_offset_B, + .range = range_B, + .bo_offset = mem_offset_B, + .flags = va->base.pte_kind, + }; + return vm_bind(va->dev, log_obj, &bind); } static VkResult @@ -106,9 +232,12 @@ nvkmd_nouveau_va_unbind(struct nvkmd_va *_va, { struct nvkmd_nouveau_va *va = nvkmd_nouveau_va(_va); - nouveau_ws_bo_unbind_vma(va->dev, va->base.addr + va_offset_B, range_B); - - return VK_SUCCESS; + struct drm_nouveau_vm_bind_op bind = { + .op = DRM_NOUVEAU_VM_BIND_OP_MAP, + .addr = va->base.addr + va_offset_B, + .range = range_B, + }; + return vm_bind(va->dev, log_obj, &bind); } const struct nvkmd_va_ops nvkmd_nouveau_va_ops = { diff --git a/src/nouveau/vulkan/nvkmd/nvkmd.h b/src/nouveau/vulkan/nvkmd/nvkmd.h index d3cac57446f..185795fb57c 100644 --- a/src/nouveau/vulkan/nvkmd/nvkmd.h +++ b/src/nouveau/vulkan/nvkmd/nvkmd.h @@ -175,7 +175,7 @@ struct nvkmd_mem { enum nvkmd_mem_flags flags; uint64_t size_B; - const struct nvkmd_va *va; + struct nvkmd_va *va; void *map; }; diff --git a/src/nouveau/winsys/nouveau_bo.c b/src/nouveau/winsys/nouveau_bo.c index 2c7f83cb18e..86c2bbde7ca 100644 --- a/src/nouveau/winsys/nouveau_bo.c +++ b/src/nouveau/winsys/nouveau_bo.c @@ -13,129 +13,24 @@ #include "nvidia/classes/cl9097.h" #include "nvidia/classes/clc597.h" -static void -bo_bind(struct nouveau_ws_device *dev, - uint32_t handle, uint64_t addr, - uint64_t range, uint64_t bo_offset, - uint32_t flags) -{ - int ret; - - struct drm_nouveau_vm_bind_op newbindop = { - .op = DRM_NOUVEAU_VM_BIND_OP_MAP, - .handle = handle, - .addr = addr, - .range = range, - .bo_offset = bo_offset, - .flags = flags, - }; - struct drm_nouveau_vm_bind vmbind = { - .op_count = 1, - .op_ptr = (uint64_t)(uintptr_t)(void *)&newbindop, - }; - ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_VM_BIND, &vmbind, sizeof(vmbind)); - if (ret) - fprintf(stderr, "vm bind failed %d\n", errno); - assert(ret == 0); -} - -static void -bo_unbind(struct nouveau_ws_device *dev, - uint64_t offset, uint64_t range, - uint32_t flags) -{ - struct drm_nouveau_vm_bind_op newbindop = { - .op = DRM_NOUVEAU_VM_BIND_OP_UNMAP, - .addr = offset, - .range = range, - .flags = flags, - }; - struct drm_nouveau_vm_bind vmbind = { - .op_count = 1, - .op_ptr = (uint64_t)(uintptr_t)(void *)&newbindop, - }; - ASSERTED int ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_VM_BIND, &vmbind, sizeof(vmbind)); - assert(ret == 0); -} - -uint64_t -nouveau_ws_alloc_vma(struct nouveau_ws_device *dev, - uint64_t req_addr, uint64_t size, uint64_t align, - bool bda_capture_replay, - bool sparse_resident) -{ - assert(dev->has_vm_bind); - - /* if the caller doesn't care, use the GPU page size */ - if (align == 0) - align = 0x1000; - - uint64_t offset; - simple_mtx_lock(&dev->vma_mutex); - if (bda_capture_replay) { - if (req_addr != 0) { - bool found = util_vma_heap_alloc_addr(&dev->bda_heap, req_addr, size); - offset = found ? req_addr : 0; - } else { - offset = util_vma_heap_alloc(&dev->bda_heap, size, align); - } - } else { - 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); - - if (sparse_resident) - bo_bind(dev, 0, offset, size, 0, DRM_NOUVEAU_VM_BIND_SPARSE); - - return offset; -} - -void -nouveau_ws_free_vma(struct nouveau_ws_device *dev, - uint64_t offset, uint64_t size, - bool bda_capture_replay, - bool sparse_resident) -{ - assert(dev->has_vm_bind); - - if (dev->debug_flags & NVK_DEBUG_VM) - fprintf(stderr, "free vma %" PRIx64 " %" PRIx64 "\n", - offset, size); - - if (sparse_resident) - bo_unbind(dev, offset, size, DRM_NOUVEAU_VM_BIND_SPARSE); - - simple_mtx_lock(&dev->vma_mutex); - if (bda_capture_replay) { - util_vma_heap_free(&dev->bda_heap, offset, size); - } else { - util_vma_heap_free(&dev->vma_heap, offset, size); - } - simple_mtx_unlock(&dev->vma_mutex); -} - void nouveau_ws_bo_unbind_vma(struct nouveau_ws_device *dev, uint64_t offset, uint64_t range) { assert(dev->has_vm_bind); - if (dev->debug_flags & NVK_DEBUG_VM) - fprintf(stderr, "unbind vma %" PRIx64 " %" PRIx64 "\n", - offset, range); - bo_unbind(dev, offset, range, 0); + struct drm_nouveau_vm_bind_op newbindop = { + .op = DRM_NOUVEAU_VM_BIND_OP_UNMAP, + .addr = offset, + .range = range, + }; + struct drm_nouveau_vm_bind vmbind = { + .op_count = 1, + .op_ptr = (uint64_t)(uintptr_t)(void *)&newbindop, + }; + ASSERTED int ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_VM_BIND, + &vmbind, sizeof(vmbind)); + assert(ret == 0); } void @@ -148,10 +43,21 @@ nouveau_ws_bo_bind_vma(struct nouveau_ws_device *dev, { assert(dev->has_vm_bind); - if (dev->debug_flags & NVK_DEBUG_VM) - fprintf(stderr, "bind vma %x %" PRIx64 " %" PRIx64 " %" PRIx64 " %d\n", - bo->handle, addr, range, bo_offset, pte_kind); - bo_bind(dev, bo->handle, addr, range, bo_offset, pte_kind); + struct drm_nouveau_vm_bind_op newbindop = { + .op = DRM_NOUVEAU_VM_BIND_OP_MAP, + .handle = bo->handle, + .addr = addr, + .range = range, + .bo_offset = bo_offset, + .flags = pte_kind, + }; + struct drm_nouveau_vm_bind vmbind = { + .op_count = 1, + .op_ptr = (uint64_t)(uintptr_t)(void *)&newbindop, + }; + ASSERTED int ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_VM_BIND, + &vmbind, sizeof(vmbind)); + assert(ret == 0); } struct nouveau_ws_bo * @@ -230,31 +136,15 @@ nouveau_ws_bo_new_tiled_locked(struct nouveau_ws_device *dev, struct nouveau_ws_bo *bo = CALLOC_STRUCT(nouveau_ws_bo); bo->size = size; - bo->align = align; - bo->offset = -1ULL; bo->handle = req.info.handle; bo->map_handle = req.info.map_handle; bo->dev = dev; bo->flags = flags; bo->refcnt = 1; - if (dev->has_vm_bind) { - bo->offset = nouveau_ws_alloc_vma(dev, 0, bo->size, align, false, 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 * @@ -320,7 +210,6 @@ nouveau_ws_bo_from_dma_buf_locked(struct nouveau_ws_device *dev, int fd) struct nouveau_ws_bo *bo = CALLOC_STRUCT(nouveau_ws_bo); bo->size = info.size; - bo->offset = info.offset; bo->handle = info.handle; bo->map_handle = info.map_handle; bo->dev = dev; @@ -333,17 +222,10 @@ nouveau_ws_bo_from_dma_buf_locked(struct nouveau_ws_device *dev, int fd) assert(bo->size == align64(bo->size, align)); - bo->offset = nouveau_ws_alloc_vma(dev, 0, bo->size, align, false, 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); @@ -390,11 +272,6 @@ nouveau_ws_bo_destroy(struct nouveau_ws_bo *bo) if (--bo->refcnt == 0) { _mesa_hash_table_remove_key(dev->bos, (void *)(uintptr_t)bo->handle); - if (dev->has_vm_bind) { - nouveau_ws_bo_unbind_vma(bo->dev, bo->offset, bo->size); - nouveau_ws_free_vma(bo->dev, bo->offset, bo->size, false, false); - } - drmCloseBufferHandle(bo->dev->fd, bo->handle); FREE(bo); } diff --git a/src/nouveau/winsys/nouveau_bo.h b/src/nouveau/winsys/nouveau_bo.h index e4ffd0c8017..f5900032408 100644 --- a/src/nouveau/winsys/nouveau_bo.h +++ b/src/nouveau/winsys/nouveau_bo.h @@ -33,24 +33,14 @@ enum nouveau_ws_bo_map_flags { }; struct nouveau_ws_bo { - uint64_t size; - uint64_t offset; - uint64_t align; - uint64_t map_handle; struct nouveau_ws_device *dev; + uint64_t size; + uint64_t map_handle; uint32_t handle; enum nouveau_ws_bo_flags flags; atomic_uint_fast32_t refcnt; }; -uint64_t nouveau_ws_alloc_vma(struct nouveau_ws_device *dev, - uint64_t addr, uint64_t size, uint64_t align, - bool bda, bool sparse); - -void nouveau_ws_free_vma(struct nouveau_ws_device *dev, - uint64_t offset, uint64_t size, - bool bda, bool sparse); - void nouveau_ws_bo_bind_vma(struct nouveau_ws_device *dev, struct nouveau_ws_bo *bo, uint64_t addr, diff --git a/src/nouveau/winsys/nouveau_device.c b/src/nouveau/winsys/nouveau_device.c index 95ae951395a..07273d20a86 100644 --- a/src/nouveau/winsys/nouveau_device.c +++ b/src/nouveau/winsys/nouveau_device.c @@ -289,17 +289,12 @@ nouveau_ws_device_new(drmDevicePtr drm_device, if (version < 0x01000301) goto out_err; - const uint64_t BDA = 1ull << 38; - const uint64_t KERN = 1ull << 39; + const uint64_t KERN = NOUVEAU_WS_DEVICE_KERNEL_RESERVATION_START; const uint64_t TOP = 1ull << 40; struct drm_nouveau_vm_init vminit = { KERN, TOP-KERN }; int ret = drmCommandWrite(fd, DRM_NOUVEAU_VM_INIT, &vminit, sizeof(vminit)); - if (ret == 0) { + if (ret == 0) device->has_vm_bind = true; - util_vma_heap_init(&device->vma_heap, 4096, BDA - 4096); - util_vma_heap_init(&device->bda_heap, BDA, KERN - BDA); - simple_mtx_init(&device->vma_mutex, mtx_plain); - } if (nouveau_ws_device_alloc(fd, device)) goto out_err; @@ -384,11 +379,6 @@ nouveau_ws_device_new(drmDevicePtr drm_device, return device; out_err: - if (device->has_vm_bind) { - util_vma_heap_finish(&device->vma_heap); - util_vma_heap_finish(&device->bda_heap); - simple_mtx_destroy(&device->vma_mutex); - } if (ver) drmFreeVersion(ver); out_open: @@ -406,12 +396,6 @@ nouveau_ws_device_destroy(struct nouveau_ws_device *device) _mesa_hash_table_destroy(device->bos, NULL); simple_mtx_destroy(&device->bos_lock); - if (device->has_vm_bind) { - util_vma_heap_finish(&device->vma_heap); - util_vma_heap_finish(&device->bda_heap); - simple_mtx_destroy(&device->vma_mutex); - } - close(device->fd); FREE(device); } diff --git a/src/nouveau/winsys/nouveau_device.h b/src/nouveau/winsys/nouveau_device.h index e248369783d..d3777e0b46d 100644 --- a/src/nouveau/winsys/nouveau_device.h +++ b/src/nouveau/winsys/nouveau_device.h @@ -4,7 +4,6 @@ #include "nouveau_private.h" #include "nv_device_info.h" #include "util/simple_mtx.h" -#include "util/vma.h" #include @@ -42,6 +41,8 @@ enum nvk_debug { NVK_DEBUG_NO_CBUF = 1ull << 5, }; +#define NOUVEAU_WS_DEVICE_KERNEL_RESERVATION_START (1ull << 39) + struct nouveau_ws_device { int fd; @@ -56,9 +57,6 @@ struct nouveau_ws_device { struct hash_table *bos; bool has_vm_bind; - struct util_vma_heap vma_heap; - struct util_vma_heap bda_heap; - simple_mtx_t vma_mutex; }; struct nouveau_ws_device *nouveau_ws_device_new(struct _drmDevice *drm_device,