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));
 
 
                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);
 
 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)