diff options
Diffstat (limited to 'drivers/gpu/drm/drm_syncobj.c')
-rw-r--r-- | drivers/gpu/drm/drm_syncobj.c | 77 |
1 files changed, 29 insertions, 48 deletions
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index f776fc1cc543..cb4d09c70fd4 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c | |||
@@ -369,40 +369,26 @@ static const struct file_operations drm_syncobj_file_fops = { | |||
369 | .release = drm_syncobj_file_release, | 369 | .release = drm_syncobj_file_release, |
370 | }; | 370 | }; |
371 | 371 | ||
372 | static int drm_syncobj_alloc_file(struct drm_syncobj *syncobj) | ||
373 | { | ||
374 | struct file *file = anon_inode_getfile("syncobj_file", | ||
375 | &drm_syncobj_file_fops, | ||
376 | syncobj, 0); | ||
377 | if (IS_ERR(file)) | ||
378 | return PTR_ERR(file); | ||
379 | |||
380 | drm_syncobj_get(syncobj); | ||
381 | if (cmpxchg(&syncobj->file, NULL, file)) { | ||
382 | /* lost the race */ | ||
383 | fput(file); | ||
384 | } | ||
385 | |||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | int drm_syncobj_get_fd(struct drm_syncobj *syncobj, int *p_fd) | 372 | int drm_syncobj_get_fd(struct drm_syncobj *syncobj, int *p_fd) |
390 | { | 373 | { |
391 | int ret; | 374 | struct file *file; |
392 | int fd; | 375 | int fd; |
393 | 376 | ||
394 | fd = get_unused_fd_flags(O_CLOEXEC); | 377 | fd = get_unused_fd_flags(O_CLOEXEC); |
395 | if (fd < 0) | 378 | if (fd < 0) |
396 | return fd; | 379 | return fd; |
397 | 380 | ||
398 | if (!syncobj->file) { | 381 | file = anon_inode_getfile("syncobj_file", |
399 | ret = drm_syncobj_alloc_file(syncobj); | 382 | &drm_syncobj_file_fops, |
400 | if (ret) { | 383 | syncobj, 0); |
401 | put_unused_fd(fd); | 384 | if (IS_ERR(file)) { |
402 | return ret; | 385 | put_unused_fd(fd); |
403 | } | 386 | return PTR_ERR(file); |
404 | } | 387 | } |
405 | fd_install(fd, syncobj->file); | 388 | |
389 | drm_syncobj_get(syncobj); | ||
390 | fd_install(fd, file); | ||
391 | |||
406 | *p_fd = fd; | 392 | *p_fd = fd; |
407 | return 0; | 393 | return 0; |
408 | } | 394 | } |
@@ -422,31 +408,24 @@ static int drm_syncobj_handle_to_fd(struct drm_file *file_private, | |||
422 | return ret; | 408 | return ret; |
423 | } | 409 | } |
424 | 410 | ||
425 | static struct drm_syncobj *drm_syncobj_fdget(int fd) | ||
426 | { | ||
427 | struct file *file = fget(fd); | ||
428 | |||
429 | if (!file) | ||
430 | return NULL; | ||
431 | if (file->f_op != &drm_syncobj_file_fops) | ||
432 | goto err; | ||
433 | |||
434 | return file->private_data; | ||
435 | err: | ||
436 | fput(file); | ||
437 | return NULL; | ||
438 | }; | ||
439 | |||
440 | static int drm_syncobj_fd_to_handle(struct drm_file *file_private, | 411 | static int drm_syncobj_fd_to_handle(struct drm_file *file_private, |
441 | int fd, u32 *handle) | 412 | int fd, u32 *handle) |
442 | { | 413 | { |
443 | struct drm_syncobj *syncobj = drm_syncobj_fdget(fd); | 414 | struct drm_syncobj *syncobj; |
415 | struct file *file; | ||
444 | int ret; | 416 | int ret; |
445 | 417 | ||
446 | if (!syncobj) | 418 | file = fget(fd); |
419 | if (!file) | ||
447 | return -EINVAL; | 420 | return -EINVAL; |
448 | 421 | ||
422 | if (file->f_op != &drm_syncobj_file_fops) { | ||
423 | fput(file); | ||
424 | return -EINVAL; | ||
425 | } | ||
426 | |||
449 | /* take a reference to put in the idr */ | 427 | /* take a reference to put in the idr */ |
428 | syncobj = file->private_data; | ||
450 | drm_syncobj_get(syncobj); | 429 | drm_syncobj_get(syncobj); |
451 | 430 | ||
452 | idr_preload(GFP_KERNEL); | 431 | idr_preload(GFP_KERNEL); |
@@ -455,12 +434,14 @@ static int drm_syncobj_fd_to_handle(struct drm_file *file_private, | |||
455 | spin_unlock(&file_private->syncobj_table_lock); | 434 | spin_unlock(&file_private->syncobj_table_lock); |
456 | idr_preload_end(); | 435 | idr_preload_end(); |
457 | 436 | ||
458 | if (ret < 0) { | 437 | if (ret > 0) { |
459 | fput(syncobj->file); | 438 | *handle = ret; |
460 | return ret; | 439 | ret = 0; |
461 | } | 440 | } else |
462 | *handle = ret; | 441 | drm_syncobj_put(syncobj); |
463 | return 0; | 442 | |
443 | fput(file); | ||
444 | return ret; | ||
464 | } | 445 | } |
465 | 446 | ||
466 | static int drm_syncobj_import_sync_file_fence(struct drm_file *file_private, | 447 | static int drm_syncobj_import_sync_file_fence(struct drm_file *file_private, |