OSDN Git Service

libdrm/amdgpu: Use private fd for amdgpu_device and winsys hash table to fix ZaphodHe...
[android-x86/external-libdrm.git] / amdgpu / amdgpu_device.c
index c610fd3..5f21b32 100644 (file)
@@ -34,6 +34,7 @@
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
 
 #include "xf86drm.h"
 #include "amdgpu_drm.h"
@@ -42,7 +43,6 @@
 
 #define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x)))
 #define UINT_TO_PTR(x) ((void *)((intptr_t)(x)))
-#define RENDERNODE_MINOR_MASK 0xff7f
 
 pthread_mutex_t fd_mutex = PTHREAD_MUTEX_INITIALIZER;
 static struct util_hash_table *fd_tab;
@@ -60,30 +60,40 @@ static int handle_compare(void *key1, void *key2)
 static unsigned fd_hash(void *key)
 {
        int fd = PTR_TO_UINT(key);
-       struct stat stat;
-       fstat(fd, &stat);
+       char *name = drmGetPrimaryDeviceNameFromFd(fd);
+       unsigned result = 0;
+       char *c;
 
-       if (!S_ISCHR(stat.st_mode))
-               return stat.st_dev ^ stat.st_ino;
-       else
-               return stat.st_dev ^ (stat.st_rdev & RENDERNODE_MINOR_MASK);
+       if (name == NULL)
+               return 0;
+
+       for (c = name; *c; ++c)
+               result += *c;
+
+       free(name);
+
+       return result;
 }
 
 static int fd_compare(void *key1, void *key2)
 {
        int fd1 = PTR_TO_UINT(key1);
        int fd2 = PTR_TO_UINT(key2);
-       struct stat stat1, stat2;
-       fstat(fd1, &stat1);
-       fstat(fd2, &stat2);
-
-       if (!S_ISCHR(stat1.st_mode) || !S_ISCHR(stat2.st_mode))
-               return stat1.st_dev != stat2.st_dev ||
-                       stat1.st_ino != stat2.st_ino;
-        else
-               return major(stat1.st_rdev) != major(stat2.st_rdev) ||
-                       (minor(stat1.st_rdev) & RENDERNODE_MINOR_MASK) !=
-                       (minor(stat2.st_rdev) & RENDERNODE_MINOR_MASK);
+       char *name1 = drmGetPrimaryDeviceNameFromFd(fd1);
+       char *name2 = drmGetPrimaryDeviceNameFromFd(fd2);
+       int result;
+
+       if (name1 == NULL || name2 == NULL) {
+               free(name1);
+               free(name2);
+               return 0;
+       }
+
+       result = strcmp(name1, name2);
+       free(name1);
+       free(name2);
+
+       return result;
 }
 
 /**
@@ -101,7 +111,7 @@ static int fd_compare(void *key1, void *key2)
 static int amdgpu_get_auth(int fd, int *auth)
 {
        int r = 0;
-       drm_client_t client;
+       drm_client_t client = {};
 
        if (drmGetNodeTypeFromFd(fd) == DRM_NODE_RENDER)
                *auth = 0;
@@ -124,7 +134,7 @@ int amdgpu_device_initialize(int fd,
        int r;
        int flag_auth = 0;
        int flag_authexist=0;
-       uint32_t accel_working;
+       uint32_t accel_working = 0;
 
        *device_handle = NULL;
 
@@ -144,7 +154,7 @@ int amdgpu_device_initialize(int fd,
                        return r;
                }
                if ((flag_auth) && (!flag_authexist)) {
-                       dev->flink_fd = fd;
+                       dev->flink_fd = dup(fd);
                }
                *major_version = dev->major_version;
                *minor_version = dev->minor_version;
@@ -159,6 +169,9 @@ int amdgpu_device_initialize(int fd,
                return -ENOMEM;
        }
 
+       dev->fd = -1;
+       dev->flink_fd = -1;
+
        atomic_set(&dev->refcount, 1);
 
        version = drmGetVersion(fd);
@@ -174,8 +187,8 @@ int amdgpu_device_initialize(int fd,
                goto cleanup;
        }
 
-       dev->fd = fd;
-       dev->flink_fd = fd;
+       dev->fd = dup(fd);
+       dev->flink_fd = dev->fd;
        dev->major_version = version->version_major;
        dev->minor_version = version->version_minor;
        drmFreeVersion(version);
@@ -183,7 +196,6 @@ int amdgpu_device_initialize(int fd,
        dev->bo_flink_names = util_hash_table_create(handle_hash,
                                                     handle_compare);
        dev->bo_handles = util_hash_table_create(handle_hash, handle_compare);
-       dev->bo_vas = util_hash_table_create(handle_hash, handle_compare);
        pthread_mutex_init(&dev->bo_table_mutex, NULL);
 
        /* Check if acceleration is working. */
@@ -199,17 +211,19 @@ int amdgpu_device_initialize(int fd,
        if (r)
                goto cleanup;
 
-       amdgpu_vamgr_init(dev);
+       dev->vamgr = amdgpu_vamgr_get_global(dev);
 
        *major_version = dev->major_version;
        *minor_version = dev->minor_version;
        *device_handle = dev;
-       util_hash_table_set(fd_tab, UINT_TO_PTR(fd), dev);
+       util_hash_table_set(fd_tab, UINT_TO_PTR(dev->fd), dev);
        pthread_mutex_unlock(&fd_mutex);
 
        return 0;
 
 cleanup:
+       if (dev->fd >= 0)
+               close(dev->fd);
        free(dev);
        pthread_mutex_unlock(&fd_mutex);
        return r;
@@ -217,12 +231,14 @@ cleanup:
 
 void amdgpu_device_free_internal(amdgpu_device_handle dev)
 {
+       amdgpu_vamgr_reference(&dev->vamgr, NULL);
        util_hash_table_destroy(dev->bo_flink_names);
        util_hash_table_destroy(dev->bo_handles);
-       util_hash_table_destroy(dev->bo_vas);
        pthread_mutex_destroy(&dev->bo_table_mutex);
-       pthread_mutex_destroy(&(dev->vamgr.bo_va_mutex));
        util_hash_table_remove(fd_tab, UINT_TO_PTR(dev->fd));
+       close(dev->fd);
+       if ((dev->flink_fd >= 0) && (dev->fd != dev->flink_fd))
+               close(dev->flink_fd);
        free(dev);
 }