Skip to content

Commit

Permalink
drm/i915: Move i915_vma_lock in the selftests to avoid lock inversion…
Browse files Browse the repository at this point in the history
…, v3.

Make sure vma_lock is not used as inner lock when kernel context is used,
and add ww handling where appropriate.

Ensure that execbuf selftests keep passing by using ww handling.

Changes since v2:
- Fix i915_gem_context finally.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Thomas Hellström <thomas.hellstrom@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200819140904.1708856-22-maarten.lankhorst@linux.intel.com
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
  • Loading branch information
Maarten Lankhorst authored and Joonas Lahtinen committed Sep 7, 2020
1 parent 8a929c9 commit 15b6c92
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 96 deletions.
26 changes: 14 additions & 12 deletions drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,25 +201,25 @@ static int gpu_set(struct context *ctx, unsigned long offset, u32 v)

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) {
Expand All @@ -240,14 +240,16 @@ static int gpu_set(struct context *ctx, unsigned long offset, u32 v)
}
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;
}
Expand Down
106 changes: 50 additions & 56 deletions drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -893,104 +893,97 @@ static int igt_shared_ctx_exec(void *arg)
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++ = lower_32_bits(vma->node.start);
*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
emit_rpcs_query(struct drm_i915_gem_object *obj,
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;

Expand All @@ -1006,23 +999,24 @@ emit_rpcs_query(struct drm_i915_gem_object *obj,
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;
}

Expand Down
41 changes: 31 additions & 10 deletions drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,31 +528,42 @@ static int make_obj_busy(struct drm_i915_gem_object *obj)
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;
}
Expand Down Expand Up @@ -1123,28 +1134,31 @@ static int __igt_mmap_gpu(struct drm_i915_private *i915,
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)) {
err = PTR_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)) {
err = PTR_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);
Expand All @@ -1166,6 +1180,13 @@ static int __igt_mmap_gpu(struct drm_i915_private *i915,

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;
}
Expand Down
Loading

0 comments on commit 15b6c92

Please sign in to comment.