All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
To: Chris Wilson <chris@chris-wilson.co.uk>, intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH] drm/i915/selftests: Exercise potential false lite-restore
Date: Tue, 1 Oct 2019 13:16:19 +0100	[thread overview]
Message-ID: <527dcfb5-ca40-ceb9-9351-80456591b752@linux.intel.com> (raw)
In-Reply-To: <20191001095111.3912-1-chris@chris-wilson.co.uk>


On 01/10/2019 10:51, Chris Wilson wrote:
> If execlists's lite-restore is based on the common GEM context tag
> rather than the per-intel_context LRCA, then a context switch between
> two intel_contexts on the same engine derived from the same GEM context
> will perform a lite-restore instead of a full context switch. We can
> exploit this by poisoning the ringbuffer of the first context and trying
> to trick a simple RING_TAIL update (i.e. lite-restore)
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> ---
> Then switch back to ce[0] for fun.
> ---
>   drivers/gpu/drm/i915/gt/selftest_lrc.c | 132 +++++++++++++++++++++++++
>   1 file changed, 132 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/gt/selftest_lrc.c b/drivers/gpu/drm/i915/gt/selftest_lrc.c
> index 93f2fcdc49bf..b90b970a44b9 100644
> --- a/drivers/gpu/drm/i915/gt/selftest_lrc.c
> +++ b/drivers/gpu/drm/i915/gt/selftest_lrc.c
> @@ -79,6 +79,137 @@ static int live_sanitycheck(void *arg)
>   	return err;
>   }
>   
> +static int live_unlite_restore(void *arg)
> +{
> +	struct drm_i915_private *i915 = arg;
> +	struct intel_engine_cs *engine;
> +	struct i915_gem_context *ctx;
> +	enum intel_engine_id id;
> +	intel_wakeref_t wakeref;
> +	struct igt_spinner spin;
> +	int err = -ENOMEM;
> +
> +	/*
> +	 * Check that we can correctly context switch between 2 instances
> +	 * on the same engine from the same parent context.
> +	 */
> +
> +	mutex_lock(&i915->drm.struct_mutex);
> +	wakeref = intel_runtime_pm_get(&i915->runtime_pm);
> +
> +	if (igt_spinner_init(&spin, &i915->gt))
> +		goto err_unlock;
> +
> +	ctx = kernel_context(i915);
> +	if (!ctx)
> +		goto err_spin;
> +
> +	for_each_engine(engine, i915, id) {
> +		struct intel_context *ce[2] = {};
> +		struct i915_request *rq[3];
> +		struct igt_live_test t;
> +		int n;
> +
> +		if (!intel_engine_can_store_dword(engine))
> +			continue;
> +
> +		if (igt_live_test_begin(&t, i915, __func__, engine->name)) {
> +			err = -EIO;
> +			break;
> +		}
> +
> +		for (n = 0; n < ARRAY_SIZE(ce); n++) {
> +			ce[n] = intel_context_create(ctx, engine);
> +			if (IS_ERR(ce[n])) {
> +				err = PTR_ERR(ce[n]);
> +				goto err_ce;
> +			}
> +
> +			err = intel_context_pin(ce[n]);
> +			if (err)
> +				goto err_ce;

If pinning fails err_ce path will underflow the unpin. Perhaps you need 
to only store in ce[] when both steps have passed and keep it in a local 
until then.

> +
> +			/*
> +			 * Setup the pair of contexts such that if we
> +			 * lite-restore using the RING_TAIL from ce[1] it
> +			 * will execute garbage from ce[0]->ring.
> +			 */
> +			memset(ce[n]->ring->vaddr,
> +			       POISON_INUSE,
> +			       ce[n]->ring->vma->size);
> +		}
> +		intel_ring_reset(ce[1]->ring, ce[1]->ring->vma->size / 2);
> +		__execlists_update_reg_state(ce[1], engine);
> +
> +		rq[0] = igt_spinner_create_request(&spin, ce[0], MI_ARB_CHECK);
> +		if (IS_ERR(rq[0])) {
> +			err = PTR_ERR(rq[0]);
> +			goto err_ce;
> +		}
> +
> +		GEM_BUG_ON(rq[0]->tail > ce[1]->ring->emit);
> +		i915_request_get(rq[0]);
> +		i915_request_add(rq[0]);
> +
> +		if (!igt_wait_for_spinner(&spin, rq[0])) {
> +			i915_request_put(rq[0]);
> +			goto err_ce;
> +		}
> +
> +		rq[1] = i915_request_create(ce[1]);
> +		if (IS_ERR(rq[1])) {
> +			err = PTR_ERR(rq[1]);
> +			i915_request_put(rq[0]);
> +			goto err_ce;
> +		}
> +		GEM_BUG_ON(rq[1]->tail <= rq[0]->tail);
> +
> +		/* Ensure we do a completion switch from ce[0] to ce[1] */
> +		i915_request_await_dma_fence(rq[1], &rq[0]->fence);

What do you mean by completion switch? You are setting up a dependency 
so rq[1] (and rq[2]) won't be put into the elsp until spinner is ended 
so it may not even be a context switch. Wouldn't you actually need the 
opposite? I was expecting you would let the spinner run, make sure rq[1] 
is in elsp and then count on time slicing to trigger a context switch.

Regards,

Tvrtko

> +		i915_request_put(rq[0]);
> +
> +		i915_request_get(rq[1]);
> +		i915_request_add(rq[1]);
> +
> +		/* And switch back to ce[0] for good measure */
> +		rq[2] = i915_request_create(ce[0]);
> +		if (IS_ERR(rq[2])) {
> +			err = PTR_ERR(rq[2]);
> +			i915_request_put(rq[1]);
> +			goto err_ce;
> +		}
> +		GEM_BUG_ON(rq[2]->tail > rq[1]->tail);
> +
> +		i915_request_await_dma_fence(rq[2], &rq[1]->fence);
> +		i915_request_put(rq[1]);
> +
> +		i915_request_add(rq[2]);
> +
> +err_ce:
> +		igt_spinner_end(&spin);
> +		for (n = 0; n < ARRAY_SIZE(ce); n++) {
> +			if (IS_ERR_OR_NULL(ce[n]))
> +				break;
> +
> +			intel_context_unpin(ce[n]);
> +			intel_context_put(ce[n]);
> +		}
> +
> +		if (igt_live_test_end(&t))
> +			err = -EIO;
> +		if (err)
> +			break;
> +	}
> +
> +	kernel_context_close(ctx);
> +err_spin:
> +	igt_spinner_fini(&spin);
> +err_unlock:
> +	intel_runtime_pm_put(&i915->runtime_pm, wakeref);
> +	mutex_unlock(&i915->drm.struct_mutex);
> +	return err;
> +}
> +
>   static int
>   emit_semaphore_chain(struct i915_request *rq, struct i915_vma *vma, int idx)
>   {
> @@ -2178,6 +2309,7 @@ int intel_execlists_live_selftests(struct drm_i915_private *i915)
>   {
>   	static const struct i915_subtest tests[] = {
>   		SUBTEST(live_sanitycheck),
> +		SUBTEST(live_unlite_restore),
>   		SUBTEST(live_timeslice_preempt),
>   		SUBTEST(live_busywait_preempt),
>   		SUBTEST(live_preempt),
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2019-10-01 12:16 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-01  9:45 [PATCH] drm/i915/selftests: Exercise potential false lite-restore Chris Wilson
2019-10-01  9:51 ` Chris Wilson
2019-10-01 12:16   ` Tvrtko Ursulin [this message]
2019-10-01 12:22     ` Chris Wilson
2019-10-01 12:30       ` Tvrtko Ursulin
2019-10-01 12:43 ` [PATCH v2] " Chris Wilson
2019-10-01 12:59   ` Tvrtko Ursulin
2019-10-01 13:08     ` Chris Wilson
2019-10-01 15:53 ` Chris Wilson
2019-10-01 21:10   ` [PATCH v3] " Chris Wilson
2019-10-02  7:35   ` Chris Wilson
2019-10-02  8:38   ` Chris Wilson
2019-10-02 13:56   ` Chris Wilson
2019-10-02 18:34   ` Chris Wilson
2019-10-01 20:30 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915/selftests: Exercise potential false lite-restore (rev4) Patchwork
2019-10-01 20:57 ` ✗ Fi.CI.BAT: failure " Patchwork
2019-10-01 23:45 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915/selftests: Exercise potential false lite-restore (rev5) Patchwork
2019-10-02  0:11 ` ✗ Fi.CI.BAT: failure " Patchwork
2019-10-02  8:03 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915/selftests: Exercise potential false lite-restore (rev6) Patchwork
2019-10-02  8:29 ` ✗ Fi.CI.BAT: failure " Patchwork
2019-10-02  8:51 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915/selftests: Exercise potential false lite-restore (rev7) Patchwork
2019-10-02  9:17 ` ✗ Fi.CI.BAT: failure " Patchwork
2019-10-02 18:24 ` ✗ Fi.CI.BAT: failure for drm/i915/selftests: Exercise potential false lite-restore (rev8) Patchwork
2019-10-02 23:21 ` ✓ Fi.CI.BAT: success for drm/i915/selftests: Exercise potential false lite-restore (rev9) Patchwork
2019-10-03  8:03 ` ✗ Fi.CI.IGT: failure " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=527dcfb5-ca40-ceb9-9351-80456591b752@linux.intel.com \
    --to=tvrtko.ursulin@linux.intel.com \
    --cc=chris@chris-wilson.co.uk \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.