Skip to content

Commit d35ca60

Browse files
mbrost05danvet
authored andcommitted
drm/i915/guc: Ensure H2G buffer updates visible before tail update
Ensure H2G buffer updates are visible before descriptor tail updates by inserting a barrier between the H2G buffer update and the tail. The barrier is simple wmb() for SMEM and is register write for LMEM. This is needed if more than 1 H2G can be inflight at once. If this barrier is not inserted it is possible the descriptor tail update is scene by the GuC before H2G buffer update which results in the GuC reading a corrupt H2G value. This can bring down the H2G channel among other bad things. Signed-off-by: Matthew Brost <[email protected]> Cc: Michal Wajdeczko <[email protected]> Reviewed-by: John Harrison <[email protected]> Signed-off-by: Daniel Vetter <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 7c567bb commit d35ca60

File tree

1 file changed

+28
-0
lines changed

1 file changed

+28
-0
lines changed

drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,28 @@ static u32 ct_get_next_fence(struct intel_guc_ct *ct)
328328
return ++ct->requests.last_fence;
329329
}
330330

331+
static void write_barrier(struct intel_guc_ct *ct)
332+
{
333+
struct intel_guc *guc = ct_to_guc(ct);
334+
struct intel_gt *gt = guc_to_gt(guc);
335+
336+
if (i915_gem_object_is_lmem(guc->ct.vma->obj)) {
337+
GEM_BUG_ON(guc->send_regs.fw_domains);
338+
/*
339+
* This register is used by the i915 and GuC for MMIO based
340+
* communication. Once we are in this code CTBs are the only
341+
* method the i915 uses to communicate with the GuC so it is
342+
* safe to write to this register (a value of 0 is NOP for MMIO
343+
* communication). If we ever start mixing CTBs and MMIOs a new
344+
* register will have to be chosen.
345+
*/
346+
intel_uncore_write_fw(gt->uncore, GEN11_SOFT_SCRATCH(0), 0);
347+
} else {
348+
/* wmb() sufficient for a barrier if in smem */
349+
wmb();
350+
}
351+
}
352+
331353
/**
332354
* DOC: CTB Host to GuC request
333355
*
@@ -411,6 +433,12 @@ static int ct_write(struct intel_guc_ct *ct,
411433
}
412434
GEM_BUG_ON(tail > size);
413435

436+
/*
437+
* make sure H2G buffer update and LRC tail update (if this triggering a
438+
* submission) are visible before updating the descriptor tail
439+
*/
440+
write_barrier(ct);
441+
414442
/* now update desc tail (back in bytes) */
415443
desc->tail = tail * 4;
416444
return 0;

0 commit comments

Comments
 (0)