diff options
author | Luca Barbieri <luca@luca-barbieri.com> | 2010-02-09 00:49:11 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-02-10 23:21:24 -0500 |
commit | c3ae90c099bb62387507e86da7cf799850444b08 (patch) | |
tree | 4f546a65e35fddea09a97fbfd28ce724ea86f7c2 /drivers/gpu/drm/drm_gem.c | |
parent | 77c1ff3982c6b36961725dd19e872a1c07df7f3b (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.c | 49 |
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 | ||
414 | static void | ||
415 | drm_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 | } |
435 | EXPORT_SYMBOL(drm_gem_object_free); | 443 | EXPORT_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 | */ | ||
451 | void | ||
452 | drm_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 | } | ||
467 | EXPORT_SYMBOL(drm_gem_object_free_unlocked); | ||
468 | |||
469 | static 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 | ||