Re: [Mesa-dev] [PATCH 08/15] winsys/radeon: implement and enable 32-bit VM allocations
Patches 5-8 are: Reviewed-by: Samuel PitoisetOn 01/06/2018 12:12 PM, Marek Olšák wrote: From: Marek Olšák --- src/gallium/winsys/radeon/drm/radeon_drm_bo.c | 42 +++ src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 28 ++- src/gallium/winsys/radeon/drm/radeon_drm_winsys.h | 2 ++ 3 files changed, 64 insertions(+), 8 deletions(-) diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c index bbfe5cc..06842a4 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c @@ -242,32 +242,54 @@ static uint64_t radeon_bomgr_find_va(const struct radeon_info *info, if ((hole->size - waste) == size) { hole->size = waste; mtx_unlock(>mutex); return offset; } } offset = heap->start; waste = offset % alignment; waste = waste ? alignment - waste : 0; + +if (offset + waste + size > heap->end) { +mtx_unlock(>mutex); +return 0; +} + if (waste) { n = CALLOC_STRUCT(radeon_bo_va_hole); n->size = waste; n->offset = offset; list_add(>list, >holes); } offset += waste; heap->start += size + waste; mtx_unlock(>mutex); return offset; } +static uint64_t radeon_bomgr_find_va64(struct radeon_drm_winsys *ws, + uint64_t size, uint64_t alignment) +{ +uint64_t va = 0; + +/* Try to allocate from the 64-bit address space first. + * If it doesn't exist (start = 0) or if it doesn't have enough space, + * fall back to the 32-bit address space. + */ +if (ws->vm64.start) +va = radeon_bomgr_find_va(>info, >vm64, size, alignment); +if (!va) +va = radeon_bomgr_find_va(>info, >vm32, size, alignment); +return va; +} + static void radeon_bomgr_free_va(const struct radeon_info *info, struct radeon_vm_heap *heap, uint64_t va, uint64_t size) { struct radeon_bo_va_hole *hole = NULL; size = align(size, info->gart_page_size); mtx_lock(>mutex); if ((va + size) == heap->start) { @@ -363,21 +385,23 @@ void radeon_bo_destroy(struct pb_buffer *_buf) if (drmCommandWriteRead(rws->fd, DRM_RADEON_GEM_VA, , sizeof(va)) != 0 && va.operation == RADEON_VA_RESULT_ERROR) { fprintf(stderr, "radeon: Failed to deallocate virtual address for buffer:\n"); fprintf(stderr, "radeon:size : %"PRIu64" bytes\n", bo->base.size); fprintf(stderr, "radeon:va: 0x%"PRIx64"\n", bo->va); } } - radeon_bomgr_free_va(>info, >vm64, bo->va, bo->base.size); + radeon_bomgr_free_va(>info, + bo->va < rws->vm32.end ? >vm32 : >vm64, + bo->va, bo->base.size); } /* Close object. */ args.handle = bo->handle; drmIoctl(rws->fd, DRM_IOCTL_GEM_CLOSE, ); mtx_destroy(>u.real.map_mutex); if (bo->initial_domain & RADEON_DOMAIN_VRAM) rws->allocated_vram -= align(bo->base.size, rws->info.gart_page_size); @@ -653,22 +677,28 @@ static struct radeon_bo *radeon_create_bo(struct radeon_drm_winsys *rws, if (heap >= 0) { pb_cache_init_entry(>bo_cache, >u.real.cache_entry, >base, heap); } if (rws->info.has_virtual_memory) { struct drm_radeon_gem_va va; unsigned va_gap_size; va_gap_size = rws->check_vm ? MAX2(4 * alignment, 64 * 1024) : 0; -bo->va = radeon_bomgr_find_va(>info, >vm64, - size + va_gap_size, alignment); + +if (flags & RADEON_FLAG_32BIT) { +bo->va = radeon_bomgr_find_va(>info, >vm32, + size + va_gap_size, alignment); +assert(bo->va + size < rws->vm32.end); +} else { +bo->va = radeon_bomgr_find_va64(rws, size + va_gap_size, alignment); +} va.handle = bo->handle; va.vm_id = 0; va.operation = RADEON_VA_MAP; va.flags = RADEON_VM_PAGE_READABLE | RADEON_VM_PAGE_WRITEABLE | RADEON_VM_PAGE_SNOOPED; va.offset = bo->va; r = drmCommandWriteRead(rws->fd, DRM_RADEON_GEM_VA, , sizeof(va)); if (r && va.operation == RADEON_VA_RESULT_ERROR) { @@ -1055,22 +1085,21 @@ static struct pb_buffer *radeon_winsys_bo_from_ptr(struct radeon_winsys *rws, bo->hash = __sync_fetch_and_add(>next_bo_hash, 1); (void) mtx_init(>u.real.map_mutex, mtx_plain); util_hash_table_set(ws->bo_handles,
[Mesa-dev] [PATCH 08/15] winsys/radeon: implement and enable 32-bit VM allocations
From: Marek Olšák--- src/gallium/winsys/radeon/drm/radeon_drm_bo.c | 42 +++ src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 28 ++- src/gallium/winsys/radeon/drm/radeon_drm_winsys.h | 2 ++ 3 files changed, 64 insertions(+), 8 deletions(-) diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c index bbfe5cc..06842a4 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c @@ -242,32 +242,54 @@ static uint64_t radeon_bomgr_find_va(const struct radeon_info *info, if ((hole->size - waste) == size) { hole->size = waste; mtx_unlock(>mutex); return offset; } } offset = heap->start; waste = offset % alignment; waste = waste ? alignment - waste : 0; + +if (offset + waste + size > heap->end) { +mtx_unlock(>mutex); +return 0; +} + if (waste) { n = CALLOC_STRUCT(radeon_bo_va_hole); n->size = waste; n->offset = offset; list_add(>list, >holes); } offset += waste; heap->start += size + waste; mtx_unlock(>mutex); return offset; } +static uint64_t radeon_bomgr_find_va64(struct radeon_drm_winsys *ws, + uint64_t size, uint64_t alignment) +{ +uint64_t va = 0; + +/* Try to allocate from the 64-bit address space first. + * If it doesn't exist (start = 0) or if it doesn't have enough space, + * fall back to the 32-bit address space. + */ +if (ws->vm64.start) +va = radeon_bomgr_find_va(>info, >vm64, size, alignment); +if (!va) +va = radeon_bomgr_find_va(>info, >vm32, size, alignment); +return va; +} + static void radeon_bomgr_free_va(const struct radeon_info *info, struct radeon_vm_heap *heap, uint64_t va, uint64_t size) { struct radeon_bo_va_hole *hole = NULL; size = align(size, info->gart_page_size); mtx_lock(>mutex); if ((va + size) == heap->start) { @@ -363,21 +385,23 @@ void radeon_bo_destroy(struct pb_buffer *_buf) if (drmCommandWriteRead(rws->fd, DRM_RADEON_GEM_VA, , sizeof(va)) != 0 && va.operation == RADEON_VA_RESULT_ERROR) { fprintf(stderr, "radeon: Failed to deallocate virtual address for buffer:\n"); fprintf(stderr, "radeon:size : %"PRIu64" bytes\n", bo->base.size); fprintf(stderr, "radeon:va: 0x%"PRIx64"\n", bo->va); } } - radeon_bomgr_free_va(>info, >vm64, bo->va, bo->base.size); + radeon_bomgr_free_va(>info, + bo->va < rws->vm32.end ? >vm32 : >vm64, + bo->va, bo->base.size); } /* Close object. */ args.handle = bo->handle; drmIoctl(rws->fd, DRM_IOCTL_GEM_CLOSE, ); mtx_destroy(>u.real.map_mutex); if (bo->initial_domain & RADEON_DOMAIN_VRAM) rws->allocated_vram -= align(bo->base.size, rws->info.gart_page_size); @@ -653,22 +677,28 @@ static struct radeon_bo *radeon_create_bo(struct radeon_drm_winsys *rws, if (heap >= 0) { pb_cache_init_entry(>bo_cache, >u.real.cache_entry, >base, heap); } if (rws->info.has_virtual_memory) { struct drm_radeon_gem_va va; unsigned va_gap_size; va_gap_size = rws->check_vm ? MAX2(4 * alignment, 64 * 1024) : 0; -bo->va = radeon_bomgr_find_va(>info, >vm64, - size + va_gap_size, alignment); + +if (flags & RADEON_FLAG_32BIT) { +bo->va = radeon_bomgr_find_va(>info, >vm32, + size + va_gap_size, alignment); +assert(bo->va + size < rws->vm32.end); +} else { +bo->va = radeon_bomgr_find_va64(rws, size + va_gap_size, alignment); +} va.handle = bo->handle; va.vm_id = 0; va.operation = RADEON_VA_MAP; va.flags = RADEON_VM_PAGE_READABLE | RADEON_VM_PAGE_WRITEABLE | RADEON_VM_PAGE_SNOOPED; va.offset = bo->va; r = drmCommandWriteRead(rws->fd, DRM_RADEON_GEM_VA, , sizeof(va)); if (r && va.operation == RADEON_VA_RESULT_ERROR) { @@ -1055,22 +1085,21 @@ static struct pb_buffer *radeon_winsys_bo_from_ptr(struct radeon_winsys *rws, bo->hash = __sync_fetch_and_add(>next_bo_hash, 1); (void) mtx_init(>u.real.map_mutex, mtx_plain); util_hash_table_set(ws->bo_handles, (void*)(uintptr_t)bo->handle, bo); mtx_unlock(>bo_handles_mutex); if (ws->info.has_virtual_memory) { struct drm_radeon_gem_va va; -bo->va = radeon_bomgr_find_va(>info, >vm64, -