drm: Use kref_put_mutex in drm_gem_object_unreference_unlocked
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Tue, 7 Apr 2015 13:56:07 +0000 (15:56 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 7 Apr 2015 16:11:25 +0000 (18:11 +0200)
If kref_put_mutex returns true then the caller or the put function is responsible
for unlocking the mutex. The usual pattern assumes that the free
callback unlocks the mutex, but since that is shared with the locked
variant we need to explicitly unlock here.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
include/drm/drm_gem.h

index 1e6ae1458f7ab98ef42cd66ef9834cef8f276718..7a592d7e398b0e4c1c1eca5dd50bff816a634972 100644 (file)
@@ -149,14 +149,16 @@ drm_gem_object_unreference(struct drm_gem_object *obj)
 static inline void
 drm_gem_object_unreference_unlocked(struct drm_gem_object *obj)
 {
-       if (obj && !atomic_add_unless(&obj->refcount.refcount, -1, 1)) {
-               struct drm_device *dev = obj->dev;
+       struct drm_device *dev;
+
+       if (!obj)
+               return;
 
-               mutex_lock(&dev->struct_mutex);
-               if (likely(atomic_dec_and_test(&obj->refcount.refcount)))
-                       drm_gem_object_free(&obj->refcount);
+       dev = obj->dev;
+       if (kref_put_mutex(&obj->refcount, drm_gem_object_free, &dev->struct_mutex))
                mutex_unlock(&dev->struct_mutex);
-       }
+       else
+               might_lock(&dev->struct_mutex);
 }
 
 int drm_gem_handle_create(struct drm_file *file_priv,