From 2336349f5e00f6597f155582ff4021fa83ab2de9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 3 Aug 2012 16:43:49 +0200 Subject: [PATCH 1/2] winsys/radeon: fix VA allocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wait for VA use to end before reusing it. Should fix: https://bugs.freedesktop.org/show_bug.cgi?id=45018 Signed-off-by: Christian König --- src/gallium/winsys/radeon/drm/radeon_drm_bo.c | 64 +++++++++++++++++-------- 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c index 2626586..0c94461 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c @@ -102,6 +102,7 @@ static INLINE struct radeon_bo *radeon_bo(struct pb_buffer *bo) struct radeon_bo_va_hole { struct list_head list; + uint32_t handle; uint64_t offset; uint64_t size; }; @@ -204,7 +205,30 @@ static uint64_t radeon_bomgr_find_va(struct radeon_bomgr *mgr, uint64_t size, ui pipe_mutex_lock(mgr->bo_va_mutex); /* first look for a hole */ LIST_FOR_EACH_ENTRY_SAFE(hole, n, &mgr->va_holes, list) { + if (hole->handle) { + struct drm_radeon_gem_busy busy_args; + struct drm_gem_close close_args; + + memset(&busy_args, 0, sizeof(busy_args)); + busy_args.handle = hole->handle; + if (drmCommandWriteRead(mgr->rws->fd, DRM_RADEON_GEM_BUSY, + &busy_args, sizeof(busy_args)) != 0) { + continue; + } + + memset(&close_args, 0, sizeof(close_args)); + close_args.handle = hole->handle; + drmIoctl(mgr->rws->fd, DRM_IOCTL_GEM_CLOSE, &close_args); + + hole->handle = 0; + } offset = hole->offset; + if ((offset + hole->size) == mgr->va_offset) { + mgr->va_offset = offset; + list_del(&hole->list); + FREE(hole); + continue; + } waste = 0; if (alignment) { waste = offset % alignment; @@ -280,23 +304,21 @@ static void radeon_bomgr_force_va(struct radeon_bomgr *mgr, uint64_t va, uint64_ pipe_mutex_unlock(mgr->bo_va_mutex); } -static void radeon_bomgr_free_va(struct radeon_bomgr *mgr, uint64_t va, uint64_t size) +static void radeon_bomgr_free_va(struct radeon_bomgr *mgr, uint64_t va, + uint64_t size, uint32_t handle) { + struct radeon_bo_va_hole *hole; pipe_mutex_lock(mgr->bo_va_mutex); - if ((va + size) == mgr->va_offset) { - mgr->va_offset = va; - } else { - struct radeon_bo_va_hole *hole; - /* FIXME on allocation failure we just lose virtual address space - * maybe print a warning - */ - hole = CALLOC_STRUCT(radeon_bo_va_hole); - if (hole) { - hole->size = size; - hole->offset = va; - list_add(&hole->list, &mgr->va_holes); - } + /* FIXME on allocation failure we just lose virtual address space + * maybe print a warning + */ + hole = CALLOC_STRUCT(radeon_bo_va_hole); + if (hole) { + hole->handle = handle; + hole->size = size; + hole->offset = va; + list_add(&hole->list, &mgr->va_holes); } pipe_mutex_unlock(mgr->bo_va_mutex); } @@ -320,12 +342,12 @@ static void radeon_bo_destroy(struct pb_buffer *_buf) os_munmap(bo->ptr, bo->base.size); if (mgr->va) { - radeon_bomgr_free_va(mgr, bo->va, bo->va_size); + radeon_bomgr_free_va(mgr, bo->va, bo->va_size, bo->handle); + } else { + /* Close object. */ + args.handle = bo->handle; + drmIoctl(bo->rws->fd, DRM_IOCTL_GEM_CLOSE, &args); } - - /* Close object. */ - args.handle = bo->handle; - drmIoctl(bo->rws->fd, DRM_IOCTL_GEM_CLOSE, &args); pipe_mutex_destroy(bo->map_mutex); FREE(bo); } @@ -540,7 +562,7 @@ static struct pb_buffer *radeon_bomgr_create_bo(struct pb_manager *_mgr, return NULL; } if (va.operation == RADEON_VA_RESULT_VA_EXIST) { - radeon_bomgr_free_va(mgr, bo->va, bo->va_size); + radeon_bomgr_free_va(mgr, bo->va, bo->va_size, 0); bo->va = va.offset; radeon_bomgr_force_va(mgr, bo->va, bo->va_size); } @@ -865,7 +887,7 @@ done: return NULL; } if (va.operation == RADEON_VA_RESULT_VA_EXIST) { - radeon_bomgr_free_va(mgr, bo->va, bo->va_size); + radeon_bomgr_free_va(mgr, bo->va, bo->va_size, 0); bo->va = va.offset; radeon_bomgr_force_va(mgr, bo->va, bo->va_size); } -- 1.7.9.5