diff options
author | Dave Airlie <[email protected]> | 2011-03-21 19:56:26 +1000 |
---|---|---|
committer | Dave Airlie <[email protected]> | 2011-03-22 11:48:36 +1000 |
commit | e4b040c2b922ff1887651cbf658b06b48b5992c5 (patch) | |
tree | 1de33b10801198abbfbfe1f06e03178c480734b7 /src | |
parent | b881ea87f1d59482420047e6d7454c78dd4f0e89 (diff) |
r600g: fix bo names causing -35 EDEADLCK
this is a port of the r300 winsys code to do the same thing.
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/winsys/r600/drm/r600_drm.c | 18 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/r600_priv.h | 6 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/radeon_bo.c | 24 |
3 files changed, 48 insertions, 0 deletions
diff --git a/src/gallium/winsys/r600/drm/r600_drm.c b/src/gallium/winsys/r600/drm/r600_drm.c index c081abb4dcd..ddd8ee3d6dd 100644 --- a/src/gallium/winsys/r600/drm/r600_drm.c +++ b/src/gallium/winsys/r600/drm/r600_drm.c @@ -30,6 +30,7 @@ #include <sys/ioctl.h> #include "util/u_inlines.h" #include "util/u_debug.h" +#include "util/u_hash_table.h" #include <pipebuffer/pb_bufmgr.h> #include "r600.h" #include "r600_priv.h" @@ -242,6 +243,18 @@ static int radeon_init_fence(struct radeon *radeon) return 0; } +#define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x))) + +static unsigned handle_hash(void *key) +{ + return PTR_TO_UINT(key); +} + +static int handle_compare(void *key1, void *key2) +{ + return PTR_TO_UINT(key1) != PTR_TO_UINT(key2); +} + static struct radeon *radeon_new(int fd, unsigned device) { struct radeon *radeon; @@ -340,6 +353,9 @@ static struct radeon *radeon_new(int fd, unsigned device) radeon_decref(radeon); return NULL; } + + radeon->bo_handles = util_hash_table_create(handle_hash, handle_compare); + pipe_mutex_init(radeon->bo_handles_mutex); return radeon; } @@ -356,6 +372,8 @@ struct radeon *radeon_decref(struct radeon *radeon) return NULL; } + util_hash_table_destroy(radeon->bo_handles); + pipe_mutex_destroy(radeon->bo_handles_mutex); if (radeon->fence_bo) { r600_bo_reference(radeon, &radeon->fence_bo, NULL); } diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h index 41c5ee02c38..a958c95ab62 100644 --- a/src/gallium/winsys/r600/drm/r600_priv.h +++ b/src/gallium/winsys/r600/drm/r600_priv.h @@ -32,6 +32,7 @@ #include <assert.h> #include <util/u_double_list.h> #include <util/u_inlines.h> +#include "util/u_hash_table.h" #include <os/os_thread.h> #include "r600.h" @@ -52,6 +53,10 @@ struct radeon { unsigned clock_crystal_freq; unsigned num_backends; unsigned minor_version; + + /* List of buffer handles and its mutex. */ + struct util_hash_table *bo_handles; + pipe_mutex bo_handles_mutex; }; struct r600_reg { @@ -77,6 +82,7 @@ struct radeon_bo { struct r600_reloc *reloc; unsigned reloc_id; unsigned last_flush; + unsigned name; }; struct r600_bo { diff --git a/src/gallium/winsys/r600/drm/radeon_bo.c b/src/gallium/winsys/r600/drm/radeon_bo.c index 3643ddbcb93..13b1d50b6e5 100644 --- a/src/gallium/winsys/r600/drm/radeon_bo.c +++ b/src/gallium/winsys/r600/drm/radeon_bo.c @@ -74,6 +74,16 @@ struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle, struct radeon_bo *bo; int r; + if (handle) { + pipe_mutex_lock(radeon->bo_handles_mutex); + bo = util_hash_table_get(radeon->bo_handles, + (void *)(uintptr_t)handle); + if (bo) { + struct radeon_bo *b = NULL; + radeon_bo_reference(radeon, &b, bo); + goto done; + } + } bo = calloc(1, sizeof(*bo)); if (bo == NULL) { return NULL; @@ -94,6 +104,7 @@ struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle, free(bo); return NULL; } + bo->name = handle; bo->handle = open_arg.handle; bo->size = open_arg.size; bo->shared = TRUE; @@ -121,6 +132,13 @@ struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle, radeon_bo_reference(radeon, &bo, NULL); return bo; } + + if (handle) + util_hash_table_set(radeon->bo_handles, (void *)(uintptr_t)handle, bo); +done: + if (handle) + pipe_mutex_unlock(radeon->bo_handles_mutex); + return bo; } @@ -128,6 +146,12 @@ static void radeon_bo_destroy(struct radeon *radeon, struct radeon_bo *bo) { struct drm_gem_close args; + if (bo->name) { + pipe_mutex_lock(radeon->bo_handles_mutex); + util_hash_table_remove(radeon->bo_handles, + (void *)(uintptr_t)bo->name); + pipe_mutex_unlock(radeon->bo_handles_mutex); + } LIST_DEL(&bo->fencedlist); radeon_bo_fixed_unmap(radeon, bo); memset(&args, 0, sizeof(args)); |