diff options
Diffstat (limited to 'drivers/gpu/drm/drm_gem.c')
-rw-r--r-- | drivers/gpu/drm/drm_gem.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index adb9eda4fa1a..d47aa774d64b 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -308,23 +308,26 @@ int drm_gem_dumb_destroy(struct drm_file *file, | |||
308 | EXPORT_SYMBOL(drm_gem_dumb_destroy); | 308 | EXPORT_SYMBOL(drm_gem_dumb_destroy); |
309 | 309 | ||
310 | /** | 310 | /** |
311 | * Create a handle for this object. This adds a handle reference | 311 | * drm_gem_handle_create_tail - internal functions to create a handle |
312 | * to the object, which includes a regular reference count. Callers | 312 | * |
313 | * will likely want to dereference the object afterwards. | 313 | * This expects the dev->object_name_lock to be held already and will drop it |
314 | * before returning. Used to avoid races in establishing new handles when | ||
315 | * importing an object from either an flink name or a dma-buf. | ||
314 | */ | 316 | */ |
315 | int | 317 | int |
316 | drm_gem_handle_create(struct drm_file *file_priv, | 318 | drm_gem_handle_create_tail(struct drm_file *file_priv, |
317 | struct drm_gem_object *obj, | 319 | struct drm_gem_object *obj, |
318 | u32 *handlep) | 320 | u32 *handlep) |
319 | { | 321 | { |
320 | struct drm_device *dev = obj->dev; | 322 | struct drm_device *dev = obj->dev; |
321 | int ret; | 323 | int ret; |
322 | 324 | ||
325 | WARN_ON(!mutex_is_locked(&dev->object_name_lock)); | ||
326 | |||
323 | /* | 327 | /* |
324 | * Get the user-visible handle using idr. Preload and perform | 328 | * Get the user-visible handle using idr. Preload and perform |
325 | * allocation under our spinlock. | 329 | * allocation under our spinlock. |
326 | */ | 330 | */ |
327 | mutex_lock(&dev->object_name_lock); | ||
328 | idr_preload(GFP_KERNEL); | 331 | idr_preload(GFP_KERNEL); |
329 | spin_lock(&file_priv->table_lock); | 332 | spin_lock(&file_priv->table_lock); |
330 | 333 | ||
@@ -351,6 +354,21 @@ drm_gem_handle_create(struct drm_file *file_priv, | |||
351 | 354 | ||
352 | return 0; | 355 | return 0; |
353 | } | 356 | } |
357 | |||
358 | /** | ||
359 | * Create a handle for this object. This adds a handle reference | ||
360 | * to the object, which includes a regular reference count. Callers | ||
361 | * will likely want to dereference the object afterwards. | ||
362 | */ | ||
363 | int | ||
364 | drm_gem_handle_create(struct drm_file *file_priv, | ||
365 | struct drm_gem_object *obj, | ||
366 | u32 *handlep) | ||
367 | { | ||
368 | mutex_lock(&obj->dev->object_name_lock); | ||
369 | |||
370 | return drm_gem_handle_create_tail(file_priv, obj, handlep); | ||
371 | } | ||
354 | EXPORT_SYMBOL(drm_gem_handle_create); | 372 | EXPORT_SYMBOL(drm_gem_handle_create); |
355 | 373 | ||
356 | 374 | ||
@@ -627,13 +645,15 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data, | |||
627 | 645 | ||
628 | mutex_lock(&dev->object_name_lock); | 646 | mutex_lock(&dev->object_name_lock); |
629 | obj = idr_find(&dev->object_name_idr, (int) args->name); | 647 | obj = idr_find(&dev->object_name_idr, (int) args->name); |
630 | if (obj) | 648 | if (obj) { |
631 | drm_gem_object_reference(obj); | 649 | drm_gem_object_reference(obj); |
632 | mutex_unlock(&dev->object_name_lock); | 650 | } else { |
633 | if (!obj) | 651 | mutex_unlock(&dev->object_name_lock); |
634 | return -ENOENT; | 652 | return -ENOENT; |
653 | } | ||
635 | 654 | ||
636 | ret = drm_gem_handle_create(file_priv, obj, &handle); | 655 | /* drm_gem_handle_create_tail unlocks dev->object_name_lock. */ |
656 | ret = drm_gem_handle_create_tail(file_priv, obj, &handle); | ||
637 | drm_gem_object_unreference_unlocked(obj); | 657 | drm_gem_object_unreference_unlocked(obj); |
638 | if (ret) | 658 | if (ret) |
639 | return ret; | 659 | return ret; |