nvk: Move Heaps and BO binding into nvkmd

We may want to move this even higher, into NVK at some point.  However
the wrappers in the winsys layer really aren't doing us much.  If
anything, now that nvkdm_mem::va is an nvkmd_va *, this actually makes
everything simpler because it's allocated through exactly the same paths
as sparse VA.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30033>
This commit is contained in:
Faith Ekstrand
2024-07-05 16:53:28 -05:00
committed by Marge Bot
parent 0856c27dd1
commit d96bf198b4
9 changed files with 253 additions and 246 deletions
@@ -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,
@@ -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;
@@ -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);
}
@@ -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 <inttypes.h>
#include <stdio.h>
#include <xf86drm.h>
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 = {
+1 -1
View File
@@ -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;
};
+27 -150
View File
@@ -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);
}
+2 -12
View File
@@ -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,
+2 -18
View File
@@ -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);
}
+2 -4
View File
@@ -4,7 +4,6 @@
#include "nouveau_private.h"
#include "nv_device_info.h"
#include "util/simple_mtx.h"
#include "util/vma.h"
#include <stddef.h>
@@ -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,