aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMario Kleiner2015-07-29 14:09:04 -0500
committerAlex Deucher2015-08-05 12:47:52 -0500
commit7d418f906cbc01b3c3e61b9d05fc73f46882a55f (patch)
treedfea65818ece908d00c61f3557b9041ce4cc39c3 /amdgpu/amdgpu_device.c
parent399ac8bafaafc3dee13beb1a99c223a860aaec8f (diff)
downloadexternal-libdrm-7d418f906cbc01b3c3e61b9d05fc73f46882a55f.tar.gz
external-libdrm-7d418f906cbc01b3c3e61b9d05fc73f46882a55f.tar.xz
external-libdrm-7d418f906cbc01b3c3e61b9d05fc73f46882a55f.zip
libdrm/amdgpu: Use private fd for amdgpu_device and winsys hash table to fix ZaphodHeads. (v2)
The amdgpu_device for a device node needs its own dup'ed fd, instead of using the original fd passed in for a screen, to make multi-x-screen ZaphodHeads configurations work on amdgpu. The original fd's lifetime differs from that of the amdgpu_device, and from the one stored in the hash. The hash key is the fd, and in order to compare hash entries we fstat them, so the fd must be around for as long as the amdgpu_device is. This patch for libdrm/amdgpu is a translation of the radeon-winsys ZaphodHeads fix for mesa's radeon-winsys, from mesa commit 28dda47ae4d974e3e032d60e8e0965c8c068c6d8 "winsys/radeon: Use dup fd as key in drm-winsys hash table to fix ZaphodHeads." Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com> Acked-by: Marek Olšák <marek.olsak@amd.com> Reviewed-by: Christian König <christian.koenig@amd.com> v2: Check for valid fd's being >= 0, because fd == 0 is in theory a valid, although unlikely, fd and fd == -1 would denote an invalid fd. Thanks to William Lewis for pointing this out. Reported-by: William Lewis <minutemaidpark@hotmail.com> Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Diffstat (limited to 'amdgpu/amdgpu_device.c')
-rw-r--r--amdgpu/amdgpu_device.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/amdgpu/amdgpu_device.c b/amdgpu/amdgpu_device.c
index 44048396..5f21b320 100644
--- a/amdgpu/amdgpu_device.c
+++ b/amdgpu/amdgpu_device.c
@@ -34,6 +34,7 @@
34#include <string.h> 34#include <string.h>
35#include <stdio.h> 35#include <stdio.h>
36#include <stdlib.h> 36#include <stdlib.h>
37#include <unistd.h>
37 38
38#include "xf86drm.h" 39#include "xf86drm.h"
39#include "amdgpu_drm.h" 40#include "amdgpu_drm.h"
@@ -153,7 +154,7 @@ int amdgpu_device_initialize(int fd,
153 return r; 154 return r;
154 } 155 }
155 if ((flag_auth) && (!flag_authexist)) { 156 if ((flag_auth) && (!flag_authexist)) {
156 dev->flink_fd = fd; 157 dev->flink_fd = dup(fd);
157 } 158 }
158 *major_version = dev->major_version; 159 *major_version = dev->major_version;
159 *minor_version = dev->minor_version; 160 *minor_version = dev->minor_version;
@@ -168,6 +169,9 @@ int amdgpu_device_initialize(int fd,
168 return -ENOMEM; 169 return -ENOMEM;
169 } 170 }
170 171
172 dev->fd = -1;
173 dev->flink_fd = -1;
174
171 atomic_set(&dev->refcount, 1); 175 atomic_set(&dev->refcount, 1);
172 176
173 version = drmGetVersion(fd); 177 version = drmGetVersion(fd);
@@ -183,8 +187,8 @@ int amdgpu_device_initialize(int fd,
183 goto cleanup; 187 goto cleanup;
184 } 188 }
185 189
186 dev->fd = fd; 190 dev->fd = dup(fd);
187 dev->flink_fd = fd; 191 dev->flink_fd = dev->fd;
188 dev->major_version = version->version_major; 192 dev->major_version = version->version_major;
189 dev->minor_version = version->version_minor; 193 dev->minor_version = version->version_minor;
190 drmFreeVersion(version); 194 drmFreeVersion(version);
@@ -212,12 +216,14 @@ int amdgpu_device_initialize(int fd,
212 *major_version = dev->major_version; 216 *major_version = dev->major_version;
213 *minor_version = dev->minor_version; 217 *minor_version = dev->minor_version;
214 *device_handle = dev; 218 *device_handle = dev;
215 util_hash_table_set(fd_tab, UINT_TO_PTR(fd), dev); 219 util_hash_table_set(fd_tab, UINT_TO_PTR(dev->fd), dev);
216 pthread_mutex_unlock(&fd_mutex); 220 pthread_mutex_unlock(&fd_mutex);
217 221
218 return 0; 222 return 0;
219 223
220cleanup: 224cleanup:
225 if (dev->fd >= 0)
226 close(dev->fd);
221 free(dev); 227 free(dev);
222 pthread_mutex_unlock(&fd_mutex); 228 pthread_mutex_unlock(&fd_mutex);
223 return r; 229 return r;
@@ -230,6 +236,9 @@ void amdgpu_device_free_internal(amdgpu_device_handle dev)
230 util_hash_table_destroy(dev->bo_handles); 236 util_hash_table_destroy(dev->bo_handles);
231 pthread_mutex_destroy(&dev->bo_table_mutex); 237 pthread_mutex_destroy(&dev->bo_table_mutex);
232 util_hash_table_remove(fd_tab, UINT_TO_PTR(dev->fd)); 238 util_hash_table_remove(fd_tab, UINT_TO_PTR(dev->fd));
239 close(dev->fd);
240 if ((dev->flink_fd >= 0) && (dev->fd != dev->flink_fd))
241 close(dev->flink_fd);
233 free(dev); 242 free(dev);
234} 243}
235 244