aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_gem.c
diff options
context:
space:
mode:
authorLuca Barbieri <luca@luca-barbieri.com>2010-02-09 00:49:11 -0500
committerDave Airlie <airlied@redhat.com>2010-02-10 23:21:24 -0500
commitc3ae90c099bb62387507e86da7cf799850444b08 (patch)
tree4f546a65e35fddea09a97fbfd28ce724ea86f7c2 /drivers/gpu/drm/drm_gem.c
parent77c1ff3982c6b36961725dd19e872a1c07df7f3b (diff)
drm: introduce drm_gem_object_[handle_]unreference_unlocked
This patch introduces the drm_gem_object_unreference_unlocked and drm_gem_object_handle_unreference_unlocked functions that do not require holding struct_mutex. drm_gem_object_unreference_unlocked calls the new ->gem_free_object_unlocked entry point if available, and otherwise just takes struct_mutex and just calls ->gem_free_object Signed-off-by: Luca Barbieri <luca@luca-barbieri.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/drm_gem.c')
-rw-r--r--drivers/gpu/drm/drm_gem.c49
1 files changed, 44 insertions, 5 deletions
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 8bf3770f294e..4018b3bfc72e 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -411,8 +411,19 @@ drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
411 mutex_unlock(&dev->struct_mutex); 411 mutex_unlock(&dev->struct_mutex);
412} 412}
413 413
414static void
415drm_gem_object_free_common(struct drm_gem_object *obj)
416{
417 struct drm_device *dev = obj->dev;
418 fput(obj->filp);
419 atomic_dec(&dev->object_count);
420 atomic_sub(obj->size, &dev->object_memory);
421 kfree(obj);
422}
423
414/** 424/**
415 * Called after the last reference to the object has been lost. 425 * Called after the last reference to the object has been lost.
426 * Must be called holding struct_ mutex
416 * 427 *
417 * Frees the object 428 * Frees the object
418 */ 429 */
@@ -427,14 +438,40 @@ drm_gem_object_free(struct kref *kref)
427 if (dev->driver->gem_free_object != NULL) 438 if (dev->driver->gem_free_object != NULL)
428 dev->driver->gem_free_object(obj); 439 dev->driver->gem_free_object(obj);
429 440
430 fput(obj->filp); 441 drm_gem_object_free_common(obj);
431 atomic_dec(&dev->object_count);
432 atomic_sub(obj->size, &dev->object_memory);
433 kfree(obj);
434} 442}
435EXPORT_SYMBOL(drm_gem_object_free); 443EXPORT_SYMBOL(drm_gem_object_free);
436 444
437/** 445/**
446 * Called after the last reference to the object has been lost.
447 * Must be called without holding struct_mutex
448 *
449 * Frees the object
450 */
451void
452drm_gem_object_free_unlocked(struct kref *kref)
453{
454 struct drm_gem_object *obj = (struct drm_gem_object *) kref;
455 struct drm_device *dev = obj->dev;
456
457 if (dev->driver->gem_free_object_unlocked != NULL)
458 dev->driver->gem_free_object_unlocked(obj);
459 else if (dev->driver->gem_free_object != NULL) {
460 mutex_lock(&dev->struct_mutex);
461 dev->driver->gem_free_object(obj);
462 mutex_unlock(&dev->struct_mutex);
463 }
464
465 drm_gem_object_free_common(obj);
466}
467EXPORT_SYMBOL(drm_gem_object_free_unlocked);
468
469static void drm_gem_object_ref_bug(struct kref *list_kref)
470{
471 BUG();
472}
473
474/**
438 * Called after the last handle to the object has been closed 475 * Called after the last handle to the object has been closed
439 * 476 *
440 * Removes any name for the object. Note that this must be 477 * Removes any name for the object. Note that this must be
@@ -458,8 +495,10 @@ drm_gem_object_handle_free(struct kref *kref)
458 /* 495 /*
459 * The object name held a reference to this object, drop 496 * The object name held a reference to this object, drop
460 * that now. 497 * that now.
498 *
499 * This cannot be the last reference, since the handle holds one too.
461 */ 500 */
462 drm_gem_object_unreference(obj); 501 kref_put(&obj->refcount, drm_gem_object_ref_bug);
463 } else 502 } else
464 spin_unlock(&dev->object_name_lock); 503 spin_unlock(&dev->object_name_lock);
465 504