aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-04-25 23:09:02 -0400
committerDave Airlie <airlied@redhat.com>2017-06-13 22:11:04 -0400
commit3ee45a3b533a20ed9fcc11ddb880fc4b30d28f51 (patch)
tree9cece82033c4a5d5ca25ad68a4fe69390df25eb8
parente9083420bbacce27e43d418064d0d2dfb4b37aaa (diff)
drm/syncobj: add sync_file interaction. (v1.2)
This interface allows importing the fence from a sync_file into an existing drm sync object, or exporting the fence attached to an existing drm sync object into a new sync file object. This should only be used to interact with sync files where necessary. v1.1: fence put fixes (Chris), drop fence from ioctl names (Chris) fixup for new fence replace API. Reviewed-by: Sean Paul <seanpaul@chromium.org> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/drm_syncobj.c75
-rw-r--r--include/uapi/drm/drm.h2
2 files changed, 75 insertions, 2 deletions
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 7144825d45f2..89441bc78591 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -45,6 +45,7 @@
45#include <linux/file.h> 45#include <linux/file.h>
46#include <linux/fs.h> 46#include <linux/fs.h>
47#include <linux/anon_inodes.h> 47#include <linux/anon_inodes.h>
48#include <linux/sync_file.h>
48 49
49#include "drm_internal.h" 50#include "drm_internal.h"
50#include <drm/drm_syncobj.h> 51#include <drm/drm_syncobj.h>
@@ -276,6 +277,59 @@ static int drm_syncobj_fd_to_handle(struct drm_file *file_private,
276 return 0; 277 return 0;
277} 278}
278 279
280int drm_syncobj_import_sync_file_fence(struct drm_file *file_private,
281 int fd, int handle)
282{
283 struct dma_fence *fence = sync_file_get_fence(fd);
284 struct drm_syncobj *syncobj;
285
286 if (!fence)
287 return -EINVAL;
288
289 syncobj = drm_syncobj_find(file_private, handle);
290 if (!syncobj) {
291 dma_fence_put(fence);
292 return -ENOENT;
293 }
294
295 drm_syncobj_replace_fence(file_private, syncobj, fence);
296 dma_fence_put(fence);
297 drm_syncobj_put(syncobj);
298 return 0;
299}
300
301int drm_syncobj_export_sync_file(struct drm_file *file_private,
302 int handle, int *p_fd)
303{
304 int ret;
305 struct dma_fence *fence;
306 struct sync_file *sync_file;
307 int fd = get_unused_fd_flags(O_CLOEXEC);
308
309 if (fd < 0)
310 return fd;
311
312 ret = drm_syncobj_fence_get(file_private, handle, &fence);
313 if (ret)
314 goto err_put_fd;
315
316 sync_file = sync_file_create(fence);
317
318 dma_fence_put(fence);
319
320 if (!sync_file) {
321 ret = -EINVAL;
322 goto err_put_fd;
323 }
324
325 fd_install(fd, sync_file->file);
326
327 *p_fd = fd;
328 return 0;
329err_put_fd:
330 put_unused_fd(fd);
331 return ret;
332}
279/** 333/**
280 * drm_syncobj_open - initalizes syncobj file-private structures at devnode open time 334 * drm_syncobj_open - initalizes syncobj file-private structures at devnode open time
281 * @dev: drm_device which is being opened by userspace 335 * @dev: drm_device which is being opened by userspace
@@ -358,9 +412,17 @@ drm_syncobj_handle_to_fd_ioctl(struct drm_device *dev, void *data,
358 if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) 412 if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
359 return -ENODEV; 413 return -ENODEV;
360 414
361 if (args->pad || args->flags) 415 if (args->pad)
362 return -EINVAL; 416 return -EINVAL;
363 417
418 if (args->flags != 0 &&
419 args->flags != DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE)
420 return -EINVAL;
421
422 if (args->flags & DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE)
423 return drm_syncobj_export_sync_file(file_private, args->handle,
424 &args->fd);
425
364 return drm_syncobj_handle_to_fd(file_private, args->handle, 426 return drm_syncobj_handle_to_fd(file_private, args->handle,
365 &args->fd); 427 &args->fd);
366} 428}
@@ -374,9 +436,18 @@ drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, void *data,
374 if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) 436 if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
375 return -ENODEV; 437 return -ENODEV;
376 438
377 if (args->pad || args->flags) 439 if (args->pad)
440 return -EINVAL;
441
442 if (args->flags != 0 &&
443 args->flags != DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE)
378 return -EINVAL; 444 return -EINVAL;
379 445
446 if (args->flags & DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE)
447 return drm_syncobj_import_sync_file_fence(file_private,
448 args->fd,
449 args->handle);
450
380 return drm_syncobj_fd_to_handle(file_private, args->fd, 451 return drm_syncobj_fd_to_handle(file_private, args->fd,
381 &args->handle); 452 &args->handle);
382} 453}
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 96c5c789e73d..101593ab10ac 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -708,6 +708,8 @@ struct drm_syncobj_destroy {
708 __u32 pad; 708 __u32 pad;
709}; 709};
710 710
711#define DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE (1 << 0)
712#define DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE (1 << 0)
711struct drm_syncobj_handle { 713struct drm_syncobj_handle {
712 __u32 handle; 714 __u32 handle;
713 __u32 flags; 715 __u32 flags;