if (!kref_get_unless_zero(&obj->base.refcount))
                        continue;
 
-               rcu_read_unlock();
-               i915_gem_object_lock(obj);
+               spin_lock(&obj->lut_lock);
                list_for_each_entry(lut, &obj->lut_list, obj_link) {
                        if (lut->ctx != ctx)
                                continue;
                        list_del(&lut->obj_link);
                        break;
                }
-               i915_gem_object_unlock(obj);
-               rcu_read_lock();
+               spin_unlock(&obj->lut_lock);
 
                if (&lut->obj_link != &obj->lut_list) {
                        i915_lut_handle_free(lut);
 
                if (err == 0) { /* And nor has this handle */
                        struct drm_i915_gem_object *obj = vma->obj;
 
-                       i915_gem_object_lock(obj);
+                       spin_lock(&obj->lut_lock);
                        if (idr_find(&eb->file->object_idr, handle) == obj) {
                                list_add(&lut->obj_link, &obj->lut_list);
                        } else {
                                radix_tree_delete(&ctx->handles_vma, handle);
                                err = -ENOENT;
                        }
-                       i915_gem_object_unlock(obj);
+                       spin_unlock(&obj->lut_lock);
                }
                mutex_unlock(&ctx->mutex);
        }
 
        INIT_LIST_HEAD(&obj->mm.link);
 
        INIT_LIST_HEAD(&obj->lut_list);
+       spin_lock_init(&obj->lut_lock);
 
        spin_lock_init(&obj->mmo.lock);
        obj->mmo.offsets = RB_ROOT;
 {
        struct drm_i915_gem_object *obj = to_intel_bo(gem);
        struct drm_i915_file_private *fpriv = file->driver_priv;
+       struct i915_lut_handle bookmark = {};
        struct i915_mmap_offset *mmo, *mn;
        struct i915_lut_handle *lut, *ln;
        LIST_HEAD(close);
 
-       i915_gem_object_lock(obj);
+       spin_lock(&obj->lut_lock);
        list_for_each_entry_safe(lut, ln, &obj->lut_list, obj_link) {
                struct i915_gem_context *ctx = lut->ctx;
 
-               if (ctx->file_priv != fpriv)
-                       continue;
+               if (ctx && ctx->file_priv == fpriv) {
+                       i915_gem_context_get(ctx);
+                       list_move(&lut->obj_link, &close);
+               }
 
-               i915_gem_context_get(ctx);
-               list_move(&lut->obj_link, &close);
+               /* Break long locks, and carefully continue on from this spot */
+               if (&ln->obj_link != &obj->lut_list) {
+                       list_add_tail(&bookmark.obj_link, &ln->obj_link);
+                       if (cond_resched_lock(&obj->lut_lock))
+                               list_safe_reset_next(&bookmark, ln, obj_link);
+                       __list_del_entry(&bookmark.obj_link);
+               }
        }
-       i915_gem_object_unlock(obj);
+       spin_unlock(&obj->lut_lock);
 
        spin_lock(&obj->mmo.lock);
        rbtree_postorder_for_each_entry_safe(mmo, mn, &obj->mmo.offsets, offset)