summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2011-03-21 19:56:26 +1000
committerDave Airlie <airlied@redhat.com>2011-03-22 11:48:36 +1000
commite4b040c2b922ff1887651cbf658b06b48b5992c5 (patch)
tree1de33b10801198abbfbfe1f06e03178c480734b7
parentb881ea87f1d59482420047e6d7454c78dd4f0e89 (diff)
r600g: fix bo names causing -35 EDEADLCK
this is a port of the r300 winsys code to do the same thing.
-rw-r--r--src/gallium/winsys/r600/drm/r600_drm.c18
-rw-r--r--src/gallium/winsys/r600/drm/r600_priv.h6
-rw-r--r--src/gallium/winsys/r600/drm/radeon_bo.c24
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 c081abb4dc..ddd8ee3d6d 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 41c5ee02c3..a958c95ab6 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 3643ddbcb9..13b1d50b6e 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));