Commit 06348d30 authored by Chris Wilson's avatar Chris Wilson

drm/i915/ringbuffer: Move double invalidate to after pd flush

Continuing the fun of trying to find exactly the delay that is
sufficient to ensure that the page directory is fully loaded between
context switches, move the extra flush added in commit 70b73f9a
("drm/i915/ringbuffer: Delay after invalidating gen6+ xcs") to just
after we flush the pd. Entirely based on the empirical data of running
failing tests in a loop until we survive a day (before the mtbf is 10-30
minutes).

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107769
References: 70b73f9a ("drm/i915/ringbuffer: Delay after invalidating gen6+ xcs")
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Acked-by: default avatarMika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180904063802.13880-1-chris@chris-wilson.co.uk
parent 7ef4ac6e
...@@ -1707,9 +1707,29 @@ static int switch_context(struct i915_request *rq) ...@@ -1707,9 +1707,29 @@ static int switch_context(struct i915_request *rq)
} }
if (ppgtt) { if (ppgtt) {
ret = engine->emit_flush(rq, EMIT_INVALIDATE);
if (ret)
goto err_mm;
ret = flush_pd_dir(rq); ret = flush_pd_dir(rq);
if (ret) if (ret)
goto err_mm; goto err_mm;
/*
* Not only do we need a full barrier (post-sync write) after
* invalidating the TLBs, but we need to wait a little bit
* longer. Whether this is merely delaying us, or the
* subsequent flush is a key part of serialising with the
* post-sync op, this extra pass appears vital before a
* mm switch!
*/
ret = engine->emit_flush(rq, EMIT_INVALIDATE);
if (ret)
goto err_mm;
ret = engine->emit_flush(rq, EMIT_FLUSH);
if (ret)
goto err_mm;
} }
if (ctx->remap_slice) { if (ctx->remap_slice) {
...@@ -1947,7 +1967,7 @@ static void gen6_bsd_submit_request(struct i915_request *request) ...@@ -1947,7 +1967,7 @@ static void gen6_bsd_submit_request(struct i915_request *request)
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
} }
static int emit_mi_flush_dw(struct i915_request *rq, u32 flags) static int mi_flush_dw(struct i915_request *rq, u32 flags)
{ {
u32 cmd, *cs; u32 cmd, *cs;
...@@ -1985,23 +2005,7 @@ static int emit_mi_flush_dw(struct i915_request *rq, u32 flags) ...@@ -1985,23 +2005,7 @@ static int emit_mi_flush_dw(struct i915_request *rq, u32 flags)
static int gen6_flush_dw(struct i915_request *rq, u32 mode, u32 invflags) static int gen6_flush_dw(struct i915_request *rq, u32 mode, u32 invflags)
{ {
int err; return mi_flush_dw(rq, mode & EMIT_INVALIDATE ? invflags : 0);
/*
* Not only do we need a full barrier (post-sync write) after
* invalidating the TLBs, but we need to wait a little bit
* longer. Whether this is merely delaying us, or the
* subsequent flush is a key part of serialising with the
* post-sync op, this extra pass appears vital before a
* mm switch!
*/
if (mode & EMIT_INVALIDATE) {
err = emit_mi_flush_dw(rq, invflags);
if (err)
return err;
}
return emit_mi_flush_dw(rq, 0);
} }
static int gen6_bsd_ring_flush(struct i915_request *rq, u32 mode) static int gen6_bsd_ring_flush(struct i915_request *rq, u32 mode)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment