aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_gem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_gem.c')
-rw-r--r--drivers/gpu/drm/drm_gem.c70
1 files changed, 49 insertions, 21 deletions
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 8bf3770f294e..aa89d4b0b4c4 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -192,9 +192,7 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle)
192 idr_remove(&filp->object_idr, handle); 192 idr_remove(&filp->object_idr, handle);
193 spin_unlock(&filp->table_lock); 193 spin_unlock(&filp->table_lock);
194 194
195 mutex_lock(&dev->struct_mutex); 195 drm_gem_object_handle_unreference_unlocked(obj);
196 drm_gem_object_handle_unreference(obj);
197 mutex_unlock(&dev->struct_mutex);
198 196
199 return 0; 197 return 0;
200} 198}
@@ -325,9 +323,7 @@ again:
325 } 323 }
326 324
327err: 325err:
328 mutex_lock(&dev->struct_mutex); 326 drm_gem_object_unreference_unlocked(obj);
329 drm_gem_object_unreference(obj);
330 mutex_unlock(&dev->struct_mutex);
331 return ret; 327 return ret;
332} 328}
333 329
@@ -358,9 +354,7 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data,
358 return -ENOENT; 354 return -ENOENT;
359 355
360 ret = drm_gem_handle_create(file_priv, obj, &handle); 356 ret = drm_gem_handle_create(file_priv, obj, &handle);
361 mutex_lock(&dev->struct_mutex); 357 drm_gem_object_unreference_unlocked(obj);
362 drm_gem_object_unreference(obj);
363 mutex_unlock(&dev->struct_mutex);
364 if (ret) 358 if (ret)
365 return ret; 359 return ret;
366 360
@@ -390,7 +384,7 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)
390{ 384{
391 struct drm_gem_object *obj = ptr; 385 struct drm_gem_object *obj = ptr;
392 386
393 drm_gem_object_handle_unreference(obj); 387 drm_gem_object_handle_unreference_unlocked(obj);
394 388
395 return 0; 389 return 0;
396} 390}
@@ -403,16 +397,25 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)
403void 397void
404drm_gem_release(struct drm_device *dev, struct drm_file *file_private) 398drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
405{ 399{
406 mutex_lock(&dev->struct_mutex);
407 idr_for_each(&file_private->object_idr, 400 idr_for_each(&file_private->object_idr,
408 &drm_gem_object_release_handle, NULL); 401 &drm_gem_object_release_handle, NULL);
409 402
410 idr_destroy(&file_private->object_idr); 403 idr_destroy(&file_private->object_idr);
411 mutex_unlock(&dev->struct_mutex); 404}
405
406static void
407drm_gem_object_free_common(struct drm_gem_object *obj)
408{
409 struct drm_device *dev = obj->dev;
410 fput(obj->filp);
411 atomic_dec(&dev->object_count);
412 atomic_sub(obj->size, &dev->object_memory);
413 kfree(obj);
412} 414}
413 415
414/** 416/**
415 * Called after the last reference to the object has been lost. 417 * Called after the last reference to the object has been lost.
418 * Must be called holding struct_ mutex
416 * 419 *
417 * Frees the object 420 * Frees the object
418 */ 421 */
@@ -427,14 +430,40 @@ drm_gem_object_free(struct kref *kref)
427 if (dev->driver->gem_free_object != NULL) 430 if (dev->driver->gem_free_object != NULL)
428 dev->driver->gem_free_object(obj); 431 dev->driver->gem_free_object(obj);
429 432
430 fput(obj->filp); 433 drm_gem_object_free_common(obj);
431 atomic_dec(&dev->object_count);
432 atomic_sub(obj->size, &dev->object_memory);
433 kfree(obj);
434} 434}
435EXPORT_SYMBOL(drm_gem_object_free); 435EXPORT_SYMBOL(drm_gem_object_free);
436 436
437/** 437/**
438 * Called after the last reference to the object has been lost.
439 * Must be called without holding struct_mutex
440 *
441 * Frees the object
442 */
443void
444drm_gem_object_free_unlocked(struct kref *kref)
445{
446 struct drm_gem_object *obj = (struct drm_gem_object *) kref;
447 struct drm_device *dev = obj->dev;
448
449 if (dev->driver->gem_free_object_unlocked != NULL)
450 dev->driver->gem_free_object_unlocked(obj);
451 else if (dev->driver->gem_free_object != NULL) {
452 mutex_lock(&dev->struct_mutex);
453 dev->driver->gem_free_object(obj);
454 mutex_unlock(&dev->struct_mutex);
455 }
456
457 drm_gem_object_free_common(obj);
458}
459EXPORT_SYMBOL(drm_gem_object_free_unlocked);
460
461static void drm_gem_object_ref_bug(struct kref *list_kref)
462{
463 BUG();
464}
465
466/**
438 * Called after the last handle to the object has been closed 467 * Called after the last handle to the object has been closed
439 * 468 *
440 * Removes any name for the object. Note that this must be 469 * Removes any name for the object. Note that this must be
@@ -458,8 +487,10 @@ drm_gem_object_handle_free(struct kref *kref)
458 /* 487 /*
459 * The object name held a reference to this object, drop 488 * The object name held a reference to this object, drop
460 * that now. 489 * that now.
490 *
491 * This cannot be the last reference, since the handle holds one too.
461 */ 492 */
462 drm_gem_object_unreference(obj); 493 kref_put(&obj->refcount, drm_gem_object_ref_bug);
463 } else 494 } else
464 spin_unlock(&dev->object_name_lock); 495 spin_unlock(&dev->object_name_lock);
465 496
@@ -477,11 +508,8 @@ EXPORT_SYMBOL(drm_gem_vm_open);
477void drm_gem_vm_close(struct vm_area_struct *vma) 508void drm_gem_vm_close(struct vm_area_struct *vma)
478{ 509{
479 struct drm_gem_object *obj = vma->vm_private_data; 510 struct drm_gem_object *obj = vma->vm_private_data;
480 struct drm_device *dev = obj->dev;
481 511
482 mutex_lock(&dev->struct_mutex); 512 drm_gem_object_unreference_unlocked(obj);
483 drm_gem_object_unreference(obj);
484 mutex_unlock(&dev->struct_mutex);
485} 513}
486EXPORT_SYMBOL(drm_gem_vm_close); 514EXPORT_SYMBOL(drm_gem_vm_close);
487 515