@@ -1332,7 +1332,7 @@ gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring,
{
int ret;
- ret = intel_ring_begin(ring, 14);
+ ret = intel_ring_begin(ring, 18);
if (ret)
return ret;
@@ -1345,6 +1345,10 @@ gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring,
intel_ring_emit(ring, 0);
/* add breadcrumb here */
+ intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
+ intel_ring_emit(ring, (I915_GEM_WATCHDOG_CRUMB_RCS + ring->id) << MI_STORE_DWORD_INDEX_SHIFT);
+ intel_ring_emit(ring, i915_gem_next_request_seqno(ring));
+ intel_ring_emit(ring, MI_NOOP);
intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965);
/* bit0-7 is the length on GEN6+ */
@@ -183,6 +183,9 @@ intel_read_status_page(struct intel_ring_buffer *ring,
* The area from dword 0x20 to 0x3ff is available for driver usage.
*/
#define I915_GEM_HWS_INDEX 0x20
+#define I915_GEM_WATCHDOG_CRUMB_RCS 0x21
+#define I915_GEM_WATCHDOG_CRUMB_VCS 0x22
+#define I915_GEM_WATCHDOG_CRUMB_BCS 0x23
void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring);
Getting the watchdog interrupt is great, but knowing the exact batch the watchdog fired on is even better. There are other ways to do this without the watchdog, but having the watchdog makes it quite simple. The idea is to simply emit the seqno before the batchbuffer begins running, and if the watchdog fires we can read back the location where the seqno was emitted to see the batchbuffer which hangs. Signed-off-by: Ben Widawsky <ben@bwidawsk.net> --- drivers/gpu/drm/i915/intel_ringbuffer.c | 6 +++++- drivers/gpu/drm/i915/intel_ringbuffer.h | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-)