diff options
-rw-r--r-- | drivers/gpu/drm/msm/msm_gem.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/msm_gem.h | 14 |
2 files changed, 13 insertions, 9 deletions
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 5514aca98dd0..520e4b7b812e 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -1020,8 +1020,6 @@ static void msm_gem_free_object(struct drm_gem_object *obj) list_del(&msm_obj->mm_list); mutex_unlock(&priv->mm_lock); - msm_gem_lock(obj); - /* object should not be on active list: */ GEM_WARN_ON(is_active(msm_obj)); @@ -1037,17 +1035,11 @@ static void msm_gem_free_object(struct drm_gem_object *obj) put_iova_vmas(obj); - /* dma_buf_detach() grabs resv lock, so we need to unlock - * prior to drm_prime_gem_destroy - */ - msm_gem_unlock(obj); - drm_prime_gem_destroy(obj, msm_obj->sgt); } else { msm_gem_vunmap(obj); put_pages(obj); put_iova_vmas(obj); - msm_gem_unlock(obj); } drm_gem_object_release(obj); 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) |