i915_gem_object_lock(ctx->obj, NULL);
        err = i915_gem_object_set_to_gtt_domain(ctx->obj, true);
-       i915_gem_object_unlock(ctx->obj);
        if (err)
-               return err;
+               goto out_unlock;
 
        vma = i915_gem_object_ggtt_pin(ctx->obj, NULL, 0, 0, 0);
-       if (IS_ERR(vma))
-               return PTR_ERR(vma);
+       if (IS_ERR(vma)) {
+               err = PTR_ERR(vma);
+               goto out_unlock;
+       }
 
        rq = intel_engine_create_kernel_request(ctx->engine);
        if (IS_ERR(rq)) {
-               i915_vma_unpin(vma);
-               return PTR_ERR(rq);
+               err = PTR_ERR(rq);
+               goto out_unpin;
        }
 
        cs = intel_ring_begin(rq, 4);
        if (IS_ERR(cs)) {
-               i915_request_add(rq);
-               i915_vma_unpin(vma);
-               return PTR_ERR(cs);
+               err = PTR_ERR(cs);
+               goto out_rq;
        }
 
        if (INTEL_GEN(ctx->engine->i915) >= 8) {
        }
        intel_ring_advance(rq, cs);
 
-       i915_vma_lock(vma);
        err = i915_request_await_object(rq, vma->obj, true);
        if (err == 0)
                err = i915_vma_move_to_active(vma, rq, EXEC_OBJECT_WRITE);
-       i915_vma_unlock(vma);
-       i915_vma_unpin(vma);
 
+out_rq:
        i915_request_add(rq);
+out_unpin:
+       i915_vma_unpin(vma);
+out_unlock:
+       i915_gem_object_unlock(ctx->obj);
 
        return err;
 }
 
        return err;
 }
 
-static struct i915_vma *rpcs_query_batch(struct i915_vma *vma)
+static int rpcs_query_batch(struct drm_i915_gem_object *rpcs, struct i915_vma *vma)
 {
-       struct drm_i915_gem_object *obj;
        u32 *cmd;
-       int err;
 
-       if (INTEL_GEN(vma->vm->i915) < 8)
-               return ERR_PTR(-EINVAL);
+       GEM_BUG_ON(INTEL_GEN(vma->vm->i915) < 8);
 
-       obj = i915_gem_object_create_internal(vma->vm->i915, PAGE_SIZE);
-       if (IS_ERR(obj))
-               return ERR_CAST(obj);
-
-       cmd = i915_gem_object_pin_map(obj, I915_MAP_WB);
-       if (IS_ERR(cmd)) {
-               err = PTR_ERR(cmd);
-               goto err;
-       }
+       cmd = i915_gem_object_pin_map(rpcs, I915_MAP_WB);
+       if (IS_ERR(cmd))
+               return PTR_ERR(cmd);
 
        *cmd++ = MI_STORE_REGISTER_MEM_GEN8;
        *cmd++ = i915_mmio_reg_offset(GEN8_R_PWR_CLK_STATE);
        *cmd++ = upper_32_bits(vma->node.start);
        *cmd = MI_BATCH_BUFFER_END;
 
-       __i915_gem_object_flush_map(obj, 0, 64);
-       i915_gem_object_unpin_map(obj);
+       __i915_gem_object_flush_map(rpcs, 0, 64);
+       i915_gem_object_unpin_map(rpcs);
 
        intel_gt_chipset_flush(vma->vm->gt);
 
-       vma = i915_vma_instance(obj, vma->vm, NULL);
-       if (IS_ERR(vma)) {
-               err = PTR_ERR(vma);
-               goto err;
-       }
-
-       err = i915_vma_pin(vma, 0, 0, PIN_USER);
-       if (err)
-               goto err;
-
-       return vma;
-
-err:
-       i915_gem_object_put(obj);
-       return ERR_PTR(err);
+       return 0;
 }
 
 static int
                struct intel_context *ce,
                struct i915_request **rq_out)
 {
+       struct drm_i915_private *i915 = to_i915(obj->base.dev);
        struct i915_request *rq;
+       struct i915_gem_ww_ctx ww;
        struct i915_vma *batch;
        struct i915_vma *vma;
+       struct drm_i915_gem_object *rpcs;
        int err;
 
        GEM_BUG_ON(!intel_engine_can_store_dword(ce->engine));
 
+       if (INTEL_GEN(i915) < 8)
+               return -EINVAL;
+
        vma = i915_vma_instance(obj, ce->vm, NULL);
        if (IS_ERR(vma))
                return PTR_ERR(vma);
 
-       i915_gem_object_lock(obj, NULL);
-       err = i915_gem_object_set_to_gtt_domain(obj, false);
-       i915_gem_object_unlock(obj);
-       if (err)
-               return err;
+       rpcs = i915_gem_object_create_internal(i915, PAGE_SIZE);
+       if (IS_ERR(rpcs))
+               return PTR_ERR(rpcs);
 
-       err = i915_vma_pin(vma, 0, 0, PIN_USER);
-       if (err)
-               return err;
-
-       batch = rpcs_query_batch(vma);
+       batch = i915_vma_instance(rpcs, ce->vm, NULL);
        if (IS_ERR(batch)) {
                err = PTR_ERR(batch);
-               goto err_vma;
+               goto err_put;
        }
 
+       i915_gem_ww_ctx_init(&ww, false);
+retry:
+       err = i915_gem_object_lock(obj, &ww);
+       if (!err)
+               err = i915_gem_object_lock(rpcs, &ww);
+       if (!err)
+               err = i915_gem_object_set_to_gtt_domain(obj, false);
+       if (!err)
+               err = i915_vma_pin_ww(vma, &ww, 0, 0, PIN_USER);
+       if (err)
+               goto err_put;
+
+       err = i915_vma_pin_ww(batch, &ww, 0, 0, PIN_USER);
+       if (err)
+               goto err_vma;
+
+       err = rpcs_query_batch(rpcs, vma);
+       if (err)
+               goto err_batch;
+
        rq = i915_request_create(ce);
        if (IS_ERR(rq)) {
                err = PTR_ERR(rq);
                goto err_batch;
        }
 
-       i915_vma_lock(batch);
        err = i915_request_await_object(rq, batch->obj, false);
        if (err == 0)
                err = i915_vma_move_to_active(batch, rq, 0);
-       i915_vma_unlock(batch);
        if (err)
                goto skip_request;
 
-       i915_vma_lock(vma);
        err = i915_request_await_object(rq, vma->obj, true);
        if (err == 0)
                err = i915_vma_move_to_active(vma, rq, EXEC_OBJECT_WRITE);
-       i915_vma_unlock(vma);
        if (err)
                goto skip_request;
 
        if (err)
                goto skip_request;
 
-       i915_vma_unpin_and_release(&batch, 0);
-       i915_vma_unpin(vma);
-
        *rq_out = i915_request_get(rq);
 
-       i915_request_add(rq);
-
-       return 0;
-
 skip_request:
-       i915_request_set_error_once(rq, err);
+       if (err)
+               i915_request_set_error_once(rq, err);
        i915_request_add(rq);
 err_batch:
-       i915_vma_unpin_and_release(&batch, 0);
+       i915_vma_unpin(batch);
 err_vma:
        i915_vma_unpin(vma);
-
+err_put:
+       if (err == -EDEADLK) {
+               err = i915_gem_ww_ctx_backoff(&ww);
+               if (!err)
+                       goto retry;
+       }
+       i915_gem_ww_ctx_fini(&ww);
+       i915_gem_object_put(rpcs);
        return err;
 }
 
 
        for_each_uabi_engine(engine, i915) {
                struct i915_request *rq;
                struct i915_vma *vma;
+               struct i915_gem_ww_ctx ww;
                int err;
 
                vma = i915_vma_instance(obj, &engine->gt->ggtt->vm, NULL);
                if (IS_ERR(vma))
                        return PTR_ERR(vma);
 
-               err = i915_vma_pin(vma, 0, 0, PIN_USER);
+               i915_gem_ww_ctx_init(&ww, false);
+retry:
+               err = i915_gem_object_lock(obj, &ww);
+               if (!err)
+                       err = i915_vma_pin_ww(vma, &ww, 0, 0, PIN_USER);
                if (err)
-                       return err;
+                       goto err;
 
                rq = intel_engine_create_kernel_request(engine);
                if (IS_ERR(rq)) {
-                       i915_vma_unpin(vma);
-                       return PTR_ERR(rq);
+                       err = PTR_ERR(rq);
+                       goto err_unpin;
                }
 
-               i915_vma_lock(vma);
                err = i915_request_await_object(rq, vma->obj, true);
                if (err == 0)
                        err = i915_vma_move_to_active(vma, rq,
                                                      EXEC_OBJECT_WRITE);
-               i915_vma_unlock(vma);
 
                i915_request_add(rq);
+err_unpin:
                i915_vma_unpin(vma);
+err:
+               if (err == -EDEADLK) {
+                       err = i915_gem_ww_ctx_backoff(&ww);
+                       if (!err)
+                               goto retry;
+               }
+               i915_gem_ww_ctx_fini(&ww);
                if (err)
                        return err;
        }
        for_each_uabi_engine(engine, i915) {
                struct i915_request *rq;
                struct i915_vma *vma;
+               struct i915_gem_ww_ctx ww;
 
                vma = i915_vma_instance(obj, engine->kernel_context->vm, NULL);
                if (IS_ERR(vma)) {
                        goto out_unmap;
                }
 
-               err = i915_vma_pin(vma, 0, 0, PIN_USER);
+               i915_gem_ww_ctx_init(&ww, false);
+retry:
+               err = i915_gem_object_lock(obj, &ww);
+               if (!err)
+                       err = i915_vma_pin_ww(vma, &ww, 0, 0, PIN_USER);
                if (err)
-                       goto out_unmap;
+                       goto out_ww;
 
                rq = i915_request_create(engine->kernel_context);
                if (IS_ERR(rq)) {
                        goto out_unpin;
                }
 
-               i915_vma_lock(vma);
                err = i915_request_await_object(rq, vma->obj, false);
                if (err == 0)
                        err = i915_vma_move_to_active(vma, rq, 0);
-               i915_vma_unlock(vma);
 
                err = engine->emit_bb_start(rq, vma->node.start, 0, 0);
                i915_request_get(rq);
 
 out_unpin:
                i915_vma_unpin(vma);
+out_ww:
+               if (err == -EDEADLK) {
+                       err = i915_gem_ww_ctx_backoff(&ww);
+                       if (!err)
+                               goto retry;
+               }
+               i915_gem_ww_ctx_fini(&ww);
                if (err)
                        goto out_unmap;
        }
 
 
        vma = i915_vma_instance(obj, vm, NULL);
        if (IS_ERR(vma)) {
-               i915_gem_object_put(obj);
-               return vma;
+               err = PTR_ERR(vma);
+               goto err_put;
        }
 
        err = i915_vma_pin(vma, 0, 0, PIN_USER);
-       if (err) {
-               i915_vma_put(vma);
-               return ERR_PTR(err);
-       }
+       if (err)
+               goto err_unlock;
+
+       i915_vma_lock(vma);
 
        base = i915_gem_object_pin_map(obj, I915_MAP_WC);
        if (IS_ERR(base)) {
-               i915_gem_object_put(obj);
-               return ERR_CAST(base);
+               err = PTR_ERR(base);
+               goto err_unpin;
        }
        cs = base;
 
        *cancel = base + loop;
        *counter = srm ? memset32(base + end, 0, 1) : NULL;
        return vma;
+
+err_unpin:
+       i915_vma_unpin(vma);
+err_unlock:
+       i915_vma_unlock(vma);
+err_put:
+       i915_gem_object_put(obj);
+       return ERR_PTR(err);
 }
 
 static u8 wait_for_freq(struct intel_rps *rps, u8 freq, int timeout_ms)
                        goto err_vma;
                }
 
-               i915_vma_lock(vma);
                err = i915_request_await_object(rq, vma->obj, false);
                if (!err)
                        err = i915_vma_move_to_active(vma, rq, 0);
                        err = rq->engine->emit_bb_start(rq,
                                                        vma->node.start,
                                                        PAGE_SIZE, 0);
-               i915_vma_unlock(vma);
                i915_request_add(rq);
                if (err)
                        goto err_vma;
                i915_gem_object_flush_map(vma->obj);
                i915_gem_object_unpin_map(vma->obj);
                i915_vma_unpin(vma);
+               i915_vma_unlock(vma);
                i915_vma_put(vma);
 
                st_engine_heartbeat_enable(engine);
                        goto err_vma;
                }
 
-               i915_vma_lock(vma);
                err = i915_request_await_object(rq, vma->obj, false);
                if (!err)
                        err = i915_vma_move_to_active(vma, rq, 0);
                        err = rq->engine->emit_bb_start(rq,
                                                        vma->node.start,
                                                        PAGE_SIZE, 0);
-               i915_vma_unlock(vma);
                i915_request_add(rq);
                if (err)
                        goto err_vma;
                i915_gem_object_flush_map(vma->obj);
                i915_gem_object_unpin_map(vma->obj);
                i915_vma_unpin(vma);
+               i915_vma_unlock(vma);
                i915_vma_put(vma);
 
                st_engine_heartbeat_enable(engine);
 
                goto out_free;
        }
 
+       i915_vma_lock(batch);
+
        idx = 0;
        for_each_uabi_engine(engine, i915) {
                request[idx] = intel_engine_create_kernel_request(engine);
                        goto out_request;
                }
 
-               i915_vma_lock(batch);
                err = i915_request_await_object(request[idx], batch->obj, 0);
                if (err == 0)
                        err = i915_vma_move_to_active(batch, request[idx], 0);
-               i915_vma_unlock(batch);
                GEM_BUG_ON(err);
 
                err = engine->emit_bb_start(request[idx],
                idx++;
        }
 
+       i915_vma_unlock(batch);
+
        idx = 0;
        for_each_uabi_engine(engine, i915) {
                if (i915_request_completed(request[idx])) {
                        goto out_free;
                }
 
+               i915_vma_lock(batch);
                request[idx] = intel_engine_create_kernel_request(engine);
                if (IS_ERR(request[idx])) {
                        err = PTR_ERR(request[idx]);
                        pr_err("%s: Request allocation failed for %s with err=%d\n",
                               __func__, engine->name, err);
-                       goto out_request;
+                       goto out_unlock;
                }
 
                if (prev) {
                                i915_request_add(request[idx]);
                                pr_err("%s: Request await failed for %s with err=%d\n",
                                       __func__, engine->name, err);
-                               goto out_request;
+                               goto out_unlock;
                        }
                }
 
-               i915_vma_lock(batch);
                err = i915_request_await_object(request[idx],
                                                batch->obj, false);
                if (err == 0)
                        err = i915_vma_move_to_active(batch, request[idx], 0);
-               i915_vma_unlock(batch);
                GEM_BUG_ON(err);
 
                err = engine->emit_bb_start(request[idx],
 
                prev = request[idx];
                idx++;
+
+out_unlock:
+               i915_vma_unlock(batch);
+               if (err)
+                       goto out_request;
        }
 
        idx = 0;