drm/i915/selftests: Reorder request allocation vs vma pinning

Impose a restraint that we have all vma pinned for a request prior to
its allocation. This is to simplify request construction, and should
facilitate unravelling the lock interdependencies later.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181204141522.13640-3-chris@chris-wilson.co.uk
This commit is contained in:
Chris Wilson 2018-12-04 14:15:18 +00:00
parent 4377d4e0d3
commit 8f98d4baf0
3 changed files with 143 additions and 145 deletions

View File

@ -972,7 +972,6 @@ static int gpu_write(struct i915_vma *vma,
{ {
struct i915_request *rq; struct i915_request *rq;
struct i915_vma *batch; struct i915_vma *batch;
int flags = 0;
int err; int err;
GEM_BUG_ON(!intel_engine_can_store_dword(engine)); GEM_BUG_ON(!intel_engine_can_store_dword(engine));
@ -981,14 +980,14 @@ static int gpu_write(struct i915_vma *vma,
if (err) if (err)
return err; return err;
rq = i915_request_alloc(engine, ctx);
if (IS_ERR(rq))
return PTR_ERR(rq);
batch = gpu_write_dw(vma, dword * sizeof(u32), value); batch = gpu_write_dw(vma, dword * sizeof(u32), value);
if (IS_ERR(batch)) { if (IS_ERR(batch))
err = PTR_ERR(batch); return PTR_ERR(batch);
goto err_request;
rq = i915_request_alloc(engine, ctx);
if (IS_ERR(rq)) {
err = PTR_ERR(rq);
goto err_batch;
} }
err = i915_vma_move_to_active(batch, rq, 0); err = i915_vma_move_to_active(batch, rq, 0);
@ -996,21 +995,21 @@ static int gpu_write(struct i915_vma *vma,
goto err_request; goto err_request;
i915_gem_object_set_active_reference(batch->obj); i915_gem_object_set_active_reference(batch->obj);
i915_vma_unpin(batch);
i915_vma_close(batch);
err = engine->emit_bb_start(rq,
batch->node.start, batch->node.size,
flags);
if (err)
goto err_request;
err = i915_vma_move_to_active(vma, rq, EXEC_OBJECT_WRITE); err = i915_vma_move_to_active(vma, rq, EXEC_OBJECT_WRITE);
if (err) if (err)
i915_request_skip(rq, err); goto err_request;
err = engine->emit_bb_start(rq,
batch->node.start, batch->node.size,
0);
err_request: err_request:
if (err)
i915_request_skip(rq, err);
i915_request_add(rq); i915_request_add(rq);
err_batch:
i915_vma_unpin(batch);
i915_vma_close(batch);
return err; return err;
} }

View File

@ -68,49 +68,66 @@ static u64 hws_address(const struct i915_vma *hws,
return hws->node.start + seqno_offset(rq->fence.context); return hws->node.start + seqno_offset(rq->fence.context);
} }
static int emit_recurse_batch(struct igt_spinner *spin, static int move_to_active(struct i915_vma *vma,
struct i915_request *rq, struct i915_request *rq,
u32 arbitration_command) unsigned int flags)
{ {
struct i915_address_space *vm = &rq->gem_context->ppgtt->vm;
struct i915_vma *hws, *vma;
u32 *batch;
int err; int err;
vma = i915_vma_instance(spin->obj, vm, NULL); err = i915_vma_move_to_active(vma, rq, flags);
if (IS_ERR(vma))
return PTR_ERR(vma);
hws = i915_vma_instance(spin->hws, vm, NULL);
if (IS_ERR(hws))
return PTR_ERR(hws);
err = i915_vma_pin(vma, 0, 0, PIN_USER);
if (err) if (err)
return err; return err;
err = i915_vma_pin(hws, 0, 0, PIN_USER);
if (err)
goto unpin_vma;
err = i915_vma_move_to_active(vma, rq, 0);
if (err)
goto unpin_hws;
if (!i915_gem_object_has_active_reference(vma->obj)) { if (!i915_gem_object_has_active_reference(vma->obj)) {
i915_gem_object_get(vma->obj); i915_gem_object_get(vma->obj);
i915_gem_object_set_active_reference(vma->obj); i915_gem_object_set_active_reference(vma->obj);
} }
err = i915_vma_move_to_active(hws, rq, 0); return 0;
if (err) }
goto unpin_hws;
if (!i915_gem_object_has_active_reference(hws->obj)) { struct i915_request *
i915_gem_object_get(hws->obj); igt_spinner_create_request(struct igt_spinner *spin,
i915_gem_object_set_active_reference(hws->obj); struct i915_gem_context *ctx,
struct intel_engine_cs *engine,
u32 arbitration_command)
{
struct i915_address_space *vm = &ctx->ppgtt->vm;
struct i915_request *rq = NULL;
struct i915_vma *hws, *vma;
u32 *batch;
int err;
vma = i915_vma_instance(spin->obj, vm, NULL);
if (IS_ERR(vma))
return ERR_CAST(vma);
hws = i915_vma_instance(spin->hws, vm, NULL);
if (IS_ERR(hws))
return ERR_CAST(hws);
err = i915_vma_pin(vma, 0, 0, PIN_USER);
if (err)
return ERR_PTR(err);
err = i915_vma_pin(hws, 0, 0, PIN_USER);
if (err)
goto unpin_vma;
rq = i915_request_alloc(engine, ctx);
if (IS_ERR(rq)) {
err = PTR_ERR(rq);
goto unpin_hws;
} }
err = move_to_active(vma, rq, 0);
if (err)
goto cancel_rq;
err = move_to_active(hws, rq, 0);
if (err)
goto cancel_rq;
batch = spin->batch; batch = spin->batch;
*batch++ = MI_STORE_DWORD_IMM_GEN4; *batch++ = MI_STORE_DWORD_IMM_GEN4;
@ -127,35 +144,18 @@ static int emit_recurse_batch(struct igt_spinner *spin,
i915_gem_chipset_flush(spin->i915); i915_gem_chipset_flush(spin->i915);
err = rq->engine->emit_bb_start(rq, vma->node.start, PAGE_SIZE, 0); err = engine->emit_bb_start(rq, vma->node.start, PAGE_SIZE, 0);
cancel_rq:
if (err) {
i915_request_skip(rq, err);
i915_request_add(rq);
}
unpin_hws: unpin_hws:
i915_vma_unpin(hws); i915_vma_unpin(hws);
unpin_vma: unpin_vma:
i915_vma_unpin(vma); i915_vma_unpin(vma);
return err; return err ? ERR_PTR(err) : rq;
}
struct i915_request *
igt_spinner_create_request(struct igt_spinner *spin,
struct i915_gem_context *ctx,
struct intel_engine_cs *engine,
u32 arbitration_command)
{
struct i915_request *rq;
int err;
rq = i915_request_alloc(engine, ctx);
if (IS_ERR(rq))
return rq;
err = emit_recurse_batch(spin, rq, arbitration_command);
if (err) {
i915_request_add(rq);
return ERR_PTR(err);
}
return rq;
} }
static u32 static u32

View File

@ -103,53 +103,88 @@ static u64 hws_address(const struct i915_vma *hws,
return hws->node.start + offset_in_page(sizeof(u32)*rq->fence.context); return hws->node.start + offset_in_page(sizeof(u32)*rq->fence.context);
} }
static int emit_recurse_batch(struct hang *h, static int move_to_active(struct i915_vma *vma,
struct i915_request *rq) struct i915_request *rq,
unsigned int flags)
{ {
struct drm_i915_private *i915 = h->i915;
struct i915_address_space *vm =
rq->gem_context->ppgtt ?
&rq->gem_context->ppgtt->vm :
&i915->ggtt.vm;
struct i915_vma *hws, *vma;
unsigned int flags;
u32 *batch;
int err; int err;
vma = i915_vma_instance(h->obj, vm, NULL); err = i915_vma_move_to_active(vma, rq, flags);
if (IS_ERR(vma))
return PTR_ERR(vma);
hws = i915_vma_instance(h->hws, vm, NULL);
if (IS_ERR(hws))
return PTR_ERR(hws);
err = i915_vma_pin(vma, 0, 0, PIN_USER);
if (err) if (err)
return err; return err;
err = i915_vma_pin(hws, 0, 0, PIN_USER);
if (err)
goto unpin_vma;
err = i915_vma_move_to_active(vma, rq, 0);
if (err)
goto unpin_hws;
if (!i915_gem_object_has_active_reference(vma->obj)) { if (!i915_gem_object_has_active_reference(vma->obj)) {
i915_gem_object_get(vma->obj); i915_gem_object_get(vma->obj);
i915_gem_object_set_active_reference(vma->obj); i915_gem_object_set_active_reference(vma->obj);
} }
err = i915_vma_move_to_active(hws, rq, 0); return 0;
if (err) }
goto unpin_hws;
if (!i915_gem_object_has_active_reference(hws->obj)) { static struct i915_request *
i915_gem_object_get(hws->obj); hang_create_request(struct hang *h, struct intel_engine_cs *engine)
i915_gem_object_set_active_reference(hws->obj); {
struct drm_i915_private *i915 = h->i915;
struct i915_address_space *vm =
h->ctx->ppgtt ? &h->ctx->ppgtt->vm : &i915->ggtt.vm;
struct i915_request *rq = NULL;
struct i915_vma *hws, *vma;
unsigned int flags;
u32 *batch;
int err;
if (i915_gem_object_is_active(h->obj)) {
struct drm_i915_gem_object *obj;
void *vaddr;
obj = i915_gem_object_create_internal(h->i915, PAGE_SIZE);
if (IS_ERR(obj))
return ERR_CAST(obj);
vaddr = i915_gem_object_pin_map(obj,
i915_coherent_map_type(h->i915));
if (IS_ERR(vaddr)) {
i915_gem_object_put(obj);
return ERR_CAST(vaddr);
}
i915_gem_object_unpin_map(h->obj);
i915_gem_object_put(h->obj);
h->obj = obj;
h->batch = vaddr;
} }
vma = i915_vma_instance(h->obj, vm, NULL);
if (IS_ERR(vma))
return ERR_CAST(vma);
hws = i915_vma_instance(h->hws, vm, NULL);
if (IS_ERR(hws))
return ERR_CAST(hws);
err = i915_vma_pin(vma, 0, 0, PIN_USER);
if (err)
return ERR_PTR(err);
err = i915_vma_pin(hws, 0, 0, PIN_USER);
if (err)
goto unpin_vma;
rq = i915_request_alloc(engine, h->ctx);
if (IS_ERR(rq)) {
err = PTR_ERR(rq);
goto unpin_hws;
}
err = move_to_active(vma, rq, 0);
if (err)
goto cancel_rq;
err = move_to_active(hws, rq, 0);
if (err)
goto cancel_rq;
batch = h->batch; batch = h->batch;
if (INTEL_GEN(i915) >= 8) { if (INTEL_GEN(i915) >= 8) {
*batch++ = MI_STORE_DWORD_IMM_GEN4; *batch++ = MI_STORE_DWORD_IMM_GEN4;
@ -213,52 +248,16 @@ static int emit_recurse_batch(struct hang *h,
err = rq->engine->emit_bb_start(rq, vma->node.start, PAGE_SIZE, flags); err = rq->engine->emit_bb_start(rq, vma->node.start, PAGE_SIZE, flags);
cancel_rq:
if (err) {
i915_request_skip(rq, err);
i915_request_add(rq);
}
unpin_hws: unpin_hws:
i915_vma_unpin(hws); i915_vma_unpin(hws);
unpin_vma: unpin_vma:
i915_vma_unpin(vma); i915_vma_unpin(vma);
return err; return err ? ERR_PTR(err) : rq;
}
static struct i915_request *
hang_create_request(struct hang *h, struct intel_engine_cs *engine)
{
struct i915_request *rq;
int err;
if (i915_gem_object_is_active(h->obj)) {
struct drm_i915_gem_object *obj;
void *vaddr;
obj = i915_gem_object_create_internal(h->i915, PAGE_SIZE);
if (IS_ERR(obj))
return ERR_CAST(obj);
vaddr = i915_gem_object_pin_map(obj,
i915_coherent_map_type(h->i915));
if (IS_ERR(vaddr)) {
i915_gem_object_put(obj);
return ERR_CAST(vaddr);
}
i915_gem_object_unpin_map(h->obj);
i915_gem_object_put(h->obj);
h->obj = obj;
h->batch = vaddr;
}
rq = i915_request_alloc(engine, h->ctx);
if (IS_ERR(rq))
return rq;
err = emit_recurse_batch(h, rq);
if (err) {
i915_request_add(rq);
return ERR_PTR(err);
}
return rq;
} }
static u32 hws_seqno(const struct hang *h, const struct i915_request *rq) static u32 hws_seqno(const struct hang *h, const struct i915_request *rq)