summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <michel.daenzer@amd.com>2015-05-21 10:49:05 +0900
committerEmil Velikov <emil.l.velikov@gmail.com>2015-07-01 15:22:40 +0100
commit3c4570e3fc283f81b5cf4b3b05a9bb66cf47ae2f (patch)
treea5736611066e65626b56f65fa14ba7be2381cf61
parent2843e2a5c846c40cf2932be3963af381e595cbfa (diff)
winsys/radeon: Unmap GPU VM address range when destroying BO
But only when doing so is safe according to the RADEON_INFO_VA_UNMAP_WORKING kernel query. This avoids kernel GPU VM address range conflicts when the BO has other references than the GEM handle being closed, e.g. when the BO is shared. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90537 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90873 Cc: "10.5 10.6" <mesa-stable@lists.freedesktop.org> Reviewed-by: Christian König <christian.koenig@amd.com> (cherry picked from commit 7796e8889a9a2cc1b454dc32d8da3d756404339a) Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com> Conflicts: src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_bo.c28
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_winsys.c4
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_winsys.h1
3 files changed, 29 insertions, 4 deletions
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
index 1ebec10daf..7b78550ca2 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
@@ -305,14 +305,34 @@ static void radeon_bo_destroy(struct pb_buffer *_buf)
if (bo->ptr)
os_munmap(bo->ptr, bo->base.size);
+ if (mgr->va) {
+ if (bo->rws->va_unmap_working) {
+ struct drm_radeon_gem_va va;
+
+ va.handle = bo->handle;
+ va.vm_id = 0;
+ va.operation = RADEON_VA_UNMAP;
+ va.flags = RADEON_VM_PAGE_READABLE |
+ RADEON_VM_PAGE_WRITEABLE |
+ RADEON_VM_PAGE_SNOOPED;
+ va.offset = bo->va;
+
+ if (drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_VA, &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 : %d bytes\n", bo->base.size);
+ fprintf(stderr, "radeon: va : 0x%016llx\n", (unsigned long long)bo->va);
+ }
+ }
+
+ radeon_bomgr_free_va(mgr, bo->va, bo->base.size);
+ }
+
/* Close object. */
args.handle = bo->handle;
drmIoctl(bo->rws->fd, DRM_IOCTL_GEM_CLOSE, &args);
- if (mgr->va) {
- radeon_bomgr_free_va(mgr, bo->va, bo->base.size);
- }
-
pipe_mutex_destroy(bo->map_mutex);
if (bo->initial_domain & RADEON_DOMAIN_VRAM)
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
index 72b7931936..12c351d79c 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
@@ -49,6 +49,8 @@
#define RADEON_INFO_ACTIVE_CU_COUNT 0x20
#endif
+#define RADEON_INFO_VA_UNMAP_WORKING 0x25
+
static struct util_hash_table *fd_tab = NULL;
pipe_static_mutex(fd_tab_mutex);
@@ -376,6 +378,8 @@ static boolean do_winsys_init(struct radeon_drm_winsys *ws)
if (!radeon_get_drm_value(ws->fd, RADEON_INFO_IB_VM_MAX_SIZE, NULL,
&ib_vm_max_size))
ws->info.r600_virtual_address = FALSE;
+ radeon_get_drm_value(ws->fd, RADEON_INFO_VA_UNMAP_WORKING, NULL,
+ &ws->va_unmap_working);
}
if (ws->gen == DRV_R600 && !debug_get_bool_option("RADEON_VA", FALSE))
ws->info.r600_virtual_address = FALSE;
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
index 1e0c632be9..ca192be9b8 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
@@ -55,6 +55,7 @@ struct radeon_drm_winsys {
enum radeon_generation gen;
struct radeon_info info;
uint32_t va_start;
+ uint32_t va_unmap_working;
uint32_t accel_working2;
struct pb_manager *kman;