Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix i915 hangs on TGL #32

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions drivers/gpu/drm/i915/display/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -3431,6 +3431,14 @@ initial_plane_vma(struct drm_i915_private *i915,
if (IS_ERR(obj))
return NULL;

/*
* Mark it WT ahead of time to avoid changing the
* cache_level during fbdev initialization. The
* unbind there would get stuck waiting for rcu.
*/
i915_gem_object_set_cache_coherency(obj, HAS_WT(i915) ?
I915_CACHE_WT : I915_CACHE_NONE);

switch (plane_config->tiling) {
case I915_TILING_NONE:
break;
Expand Down
31 changes: 24 additions & 7 deletions drivers/gpu/drm/i915/gt/intel_lrc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2504,11 +2504,23 @@ invalidate_csb_entries(const u32 *first, const u32 *last)
static inline bool
gen12_csb_parse(const struct intel_engine_execlists *execlists, const u32 *csb)
{
u32 lower_dw = csb[0];
u32 upper_dw = csb[1];
bool ctx_to_valid = GEN12_CSB_CTX_VALID(lower_dw);
bool ctx_away_valid = GEN12_CSB_CTX_VALID(upper_dw);
bool new_queue = lower_dw & GEN12_CTX_STATUS_SWITCHED_TO_NEW_QUEUE;
bool ctx_away_valid;
bool new_queue;
u64 entry;

/* HSD#22011248461 */
entry = READ_ONCE(*csb);
if (unlikely(entry == -1)) {
preempt_disable();
if (wait_for_atomic_us((entry = READ_ONCE(*csb)) != -1, 50))
GEM_WARN_ON("50us CSB timeout");
preempt_enable();
}
WRITE_ONCE(*(u64 *)csb, -1);

ctx_away_valid = GEN12_CSB_CTX_VALID(upper_32_bits(entry));
new_queue =
lower_32_bits(entry) & GEN12_CTX_STATUS_SWITCHED_TO_NEW_QUEUE;

/*
* The context switch detail is not guaranteed to be 5 when a preemption
Expand All @@ -2518,7 +2530,7 @@ gen12_csb_parse(const struct intel_engine_execlists *execlists, const u32 *csb)
* would require some extra handling, but we don't support that.
*/
if (!ctx_away_valid || new_queue) {
GEM_BUG_ON(!ctx_to_valid);
GEM_BUG_ON(!GEN12_CSB_CTX_VALID(lower_32_bits(entry)));
return true;
}

Expand All @@ -2527,7 +2539,7 @@ gen12_csb_parse(const struct intel_engine_execlists *execlists, const u32 *csb)
* context switch on an unsuccessful wait instruction since we always
* use polling mode.
*/
GEM_BUG_ON(GEN12_CTX_SWITCH_DETAIL(upper_dw));
GEM_BUG_ON(GEN12_CTX_SWITCH_DETAIL(upper_32_bits(entry)));
return false;
}

Expand Down Expand Up @@ -2633,6 +2645,9 @@ static void process_csb(struct intel_engine_cs *engine)
smp_wmb(); /* complete the seqlock */
WRITE_ONCE(execlists->active, execlists->inflight);

/* XXX Magic delay for tgl */
ENGINE_POSTING_READ(engine, RING_CONTEXT_STATUS_PTR);

WRITE_ONCE(execlists->pending[0], NULL);
} else {
GEM_BUG_ON(!*execlists->active);
Expand Down Expand Up @@ -3966,6 +3981,8 @@ static void reset_csb_pointers(struct intel_engine_cs *engine)
WRITE_ONCE(*execlists->csb_write, reset_value);
wmb(); /* Make sure this is visible to HW (paranoia?) */

/* Check that the GPU does indeed update the CSB entries! */
memset(execlists->csb_status, -1, (reset_value + 1) * sizeof(u64));
invalidate_csb_entries(&execlists->csb_status[0],
&execlists->csb_status[reset_value]);

Expand Down