summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/msm_gem.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/msm_gem.h')
-rw-r--r--drivers/gpu/drm/msm/msm_gem.h14
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h
index d608339c1643..432032ad4aed 100644
--- a/drivers/gpu/drm/msm/msm_gem.h
+++ b/drivers/gpu/drm/msm/msm_gem.h
@@ -229,7 +229,19 @@ msm_gem_unlock(struct drm_gem_object *obj)
static inline bool
msm_gem_is_locked(struct drm_gem_object *obj)
{
- return dma_resv_is_locked(obj->resv);
+ /*
+ * Destroying the object is a special case.. msm_gem_free_object()
+ * calls many things that WARN_ON if the obj lock is not held. But
+ * acquiring the obj lock in msm_gem_free_object() can cause a
+ * locking order inversion between reservation_ww_class_mutex and
+ * fs_reclaim.
+ *
+ * This deadlock is not actually possible, because no one should
+ * be already holding the lock when msm_gem_free_object() is called.
+ * Unfortunately lockdep is not aware of this detail. So when the
+ * refcount drops to zero, we pretend it is already locked.
+ */
+ return dma_resv_is_locked(obj->resv) || (kref_read(&obj->refcount) == 0);
}
static inline bool is_active(struct msm_gem_object *msm_obj)