r600g: fix bo names causing -35 EDEADLCK
authorDave Airlie <airlied@redhat.com>
Mon, 21 Mar 2011 09:56:26 +0000 (19:56 +1000)
committerDave Airlie <airlied@redhat.com>
Tue, 22 Mar 2011 01:48:36 +0000 (11:48 +1000)
this is a port of the r300 winsys code to do the same thing.

src/gallium/winsys/r600/drm/r600_drm.c
src/gallium/winsys/r600/drm/r600_priv.h
src/gallium/winsys/r600/drm/radeon_bo.c

index c081abb..ddd8ee3 100644 (file)
@@ -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);
        }
index 41c5ee0..a958c95 100644 (file)
@@ -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 {
index 3643ddb..13b1d50 100644 (file)
@@ -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));