nouveau/winsys: Allow nouveau_ws_device_new() without VM_BIND

Silently fall back to non-VM_BIND.  The client can check for the
has_vm_bind flag in the device to detect whether VM_BIND is actually
available or not.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24326>
This commit is contained in:
Faith Ekstrand 2023-08-04 11:59:21 -05:00 committed by Marge Bot
parent 1a6a198ab5
commit 0b6afbc407
3 changed files with 36 additions and 25 deletions

View file

@ -61,6 +61,8 @@ nouveau_ws_alloc_vma(struct nouveau_ws_device *dev,
uint64_t size, uint64_t align,
bool sparse_resident)
{
assert(dev->has_vm_bind);
uint64_t offset;
simple_mtx_lock(&dev->vma_mutex);
offset = util_vma_heap_alloc(&dev->vma_heap, size, align);
@ -81,6 +83,8 @@ nouveau_ws_free_vma(struct nouveau_ws_device *dev,
uint64_t offset, uint64_t size,
bool sparse_resident)
{
assert(dev->has_vm_bind);
if (dev->debug_flags & NVK_DEBUG_VM)
fprintf(stderr, "free vma %" PRIx64 " %" PRIx64 "\n",
offset, size);
@ -97,6 +101,8 @@ 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);
@ -111,6 +117,8 @@ nouveau_ws_bo_bind_vma(struct nouveau_ws_device *dev,
uint64_t bo_offset,
uint32_t pte_kind)
{
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);
@ -211,9 +219,11 @@ nouveau_ws_bo_new_tiled(struct nouveau_ws_device *dev,
bo->refcnt = 1;
#if NVK_NEW_UAPI == 1
assert(pte_kind == 0);
bo->offset = nouveau_ws_alloc_vma(dev, bo->size, align, false);
nouveau_ws_bo_bind_vma(dev, bo, bo->offset, bo->size, 0, 0);
if (dev->has_vm_bind) {
assert(pte_kind == 0);
bo->offset = nouveau_ws_alloc_vma(dev, bo->size, align, false);
nouveau_ws_bo_bind_vma(dev, bo, bo->offset, bo->size, 0, 0);
}
#endif
_mesa_hash_table_insert(dev->bos, (void *)(uintptr_t)bo->handle, bo);
@ -296,8 +306,10 @@ nouveau_ws_bo_destroy(struct nouveau_ws_bo *bo)
_mesa_hash_table_remove_key(dev->bos, (void *)(uintptr_t)bo->handle);
#if NVK_NEW_UAPI == 1
nouveau_ws_bo_unbind_vma(bo->dev, bo->offset, bo->size);
nouveau_ws_free_vma(bo->dev, bo->offset, bo->size, false);
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);
}
#endif
drmCloseBufferHandle(bo->dev->fd, bo->handle);

View file

@ -259,14 +259,6 @@ nouveau_ws_device_new(drmDevicePtr drm_device)
goto out_err;
}
#if NVK_NEW_UAPI == 1
const uint64_t TOP = 1ull << 40;
const uint64_t KERN = 1ull << 39;
util_vma_heap_init(&device->vma_heap, 4096, (TOP - KERN) - 4096);
simple_mtx_init(&device->vma_mutex, mtx_plain);
device->vma_heap.alloc_high = false;
#endif
uint32_t version =
ver->version_major << 24 |
ver->version_minor << 8 |
@ -274,20 +266,19 @@ nouveau_ws_device_new(drmDevicePtr drm_device)
drmFreeVersion(ver);
ver = NULL;
#if NVK_NEW_UAPI == 1
/* don't work on older kernels */
if (version < 0x01000400)
goto out_err;
#else
if (version < 0x01000301)
goto out_err;
#endif
#if NVK_NEW_UAPI == 1
/* start the new VM mode */
const uint64_t TOP = 1ull << 40;
const uint64_t KERN = 1ull << 39;
struct drm_nouveau_vm_init vminit = { TOP-KERN, KERN };
ASSERTED int ret = drmCommandWrite(fd, DRM_NOUVEAU_VM_INIT, &vminit, sizeof(vminit));
assert(!ret);
int ret = drmCommandWrite(fd, DRM_NOUVEAU_VM_INIT, &vminit, sizeof(vminit));
if (ret == 0) {
device->has_vm_bind = true;
util_vma_heap_init(&device->vma_heap, 4096, (TOP - KERN) - 4096);
simple_mtx_init(&device->vma_mutex, mtx_plain);
}
#endif
if (nouveau_ws_device_alloc(fd, device))
@ -351,6 +342,12 @@ nouveau_ws_device_new(drmDevicePtr drm_device)
return device;
out_err:
#if NVK_NEW_UAPI == 1
if (device->has_vm_bind) {
util_vma_heap_finish(&device->vma_heap);
simple_mtx_destroy(&device->vma_mutex);
}
#endif
if (ver)
drmFreeVersion(ver);
out_open:
@ -369,11 +366,12 @@ nouveau_ws_device_destroy(struct nouveau_ws_device *device)
simple_mtx_destroy(&device->bos_lock);
#if NVK_NEW_UAPI == 1
util_vma_heap_finish(&device->vma_heap);
simple_mtx_destroy(&device->vma_mutex);
if (device->has_vm_bind) {
util_vma_heap_finish(&device->vma_heap);
simple_mtx_destroy(&device->vma_mutex);
}
#endif
close(device->fd);
FREE(device);
}

View file

@ -50,6 +50,7 @@ struct nouveau_ws_device {
struct hash_table *bos;
#if NVK_NEW_UAPI == 1
bool has_vm_bind;
struct util_vma_heap vma_heap;
simple_mtx_t vma_mutex;
#endif