|
@@ -411,8 +411,19 @@ drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
|
|
|
mutex_unlock(&dev->struct_mutex);
|
|
|
}
|
|
|
|
|
|
+static void
|
|
|
+drm_gem_object_free_common(struct drm_gem_object *obj)
|
|
|
+{
|
|
|
+ struct drm_device *dev = obj->dev;
|
|
|
+ fput(obj->filp);
|
|
|
+ atomic_dec(&dev->object_count);
|
|
|
+ atomic_sub(obj->size, &dev->object_memory);
|
|
|
+ kfree(obj);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* Called after the last reference to the object has been lost.
|
|
|
+ * Must be called holding struct_ mutex
|
|
|
*
|
|
|
* Frees the object
|
|
|
*/
|
|
@@ -427,13 +438,39 @@ drm_gem_object_free(struct kref *kref)
|
|
|
if (dev->driver->gem_free_object != NULL)
|
|
|
dev->driver->gem_free_object(obj);
|
|
|
|
|
|
- fput(obj->filp);
|
|
|
- atomic_dec(&dev->object_count);
|
|
|
- atomic_sub(obj->size, &dev->object_memory);
|
|
|
- kfree(obj);
|
|
|
+ drm_gem_object_free_common(obj);
|
|
|
}
|
|
|
EXPORT_SYMBOL(drm_gem_object_free);
|
|
|
|
|
|
+/**
|
|
|
+ * Called after the last reference to the object has been lost.
|
|
|
+ * Must be called without holding struct_mutex
|
|
|
+ *
|
|
|
+ * Frees the object
|
|
|
+ */
|
|
|
+void
|
|
|
+drm_gem_object_free_unlocked(struct kref *kref)
|
|
|
+{
|
|
|
+ struct drm_gem_object *obj = (struct drm_gem_object *) kref;
|
|
|
+ struct drm_device *dev = obj->dev;
|
|
|
+
|
|
|
+ if (dev->driver->gem_free_object_unlocked != NULL)
|
|
|
+ dev->driver->gem_free_object_unlocked(obj);
|
|
|
+ else if (dev->driver->gem_free_object != NULL) {
|
|
|
+ mutex_lock(&dev->struct_mutex);
|
|
|
+ dev->driver->gem_free_object(obj);
|
|
|
+ mutex_unlock(&dev->struct_mutex);
|
|
|
+ }
|
|
|
+
|
|
|
+ drm_gem_object_free_common(obj);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(drm_gem_object_free_unlocked);
|
|
|
+
|
|
|
+static void drm_gem_object_ref_bug(struct kref *list_kref)
|
|
|
+{
|
|
|
+ BUG();
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* Called after the last handle to the object has been closed
|
|
|
*
|
|
@@ -458,8 +495,10 @@ drm_gem_object_handle_free(struct kref *kref)
|
|
|
/*
|
|
|
* The object name held a reference to this object, drop
|
|
|
* that now.
|
|
|
+ *
|
|
|
+ * This cannot be the last reference, since the handle holds one too.
|
|
|
*/
|
|
|
- drm_gem_object_unreference(obj);
|
|
|
+ kref_put(&obj->refcount, drm_gem_object_ref_bug);
|
|
|
} else
|
|
|
spin_unlock(&dev->object_name_lock);
|
|
|
|