From 68d2e395d9e18898ef74a635a93dfc4501c1c507 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Wed, 4 Mar 2015 13:07:55 -0700 Subject: [PATCH] ilo: add ILO_DEBUG=hang When set, detect and dump the hanging batch bufffer. --- src/gallium/drivers/ilo/ilo_builder.h | 2 +- src/gallium/drivers/ilo/ilo_common.h | 3 ++- src/gallium/drivers/ilo/ilo_cp.c | 38 ++++++++++++++++++++++++++- src/gallium/drivers/ilo/ilo_cp.h | 3 +++ src/gallium/drivers/ilo/ilo_screen.c | 3 ++- 5 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/gallium/drivers/ilo/ilo_builder.h b/src/gallium/drivers/ilo/ilo_builder.h index 0de7b5dedc6..c902a8f3cf2 100644 --- a/src/gallium/drivers/ilo/ilo_builder.h +++ b/src/gallium/drivers/ilo/ilo_builder.h @@ -171,7 +171,7 @@ ilo_builder_writer_checked_record(struct ilo_builder *builder, enum ilo_builder_item_type item, unsigned offset, unsigned size) { - if (unlikely(ilo_debug & ILO_DEBUG_BATCH)) { + if (unlikely(ilo_debug & (ILO_DEBUG_BATCH | ILO_DEBUG_HANG))) { if (!ilo_builder_writer_record(builder, which, item, offset, size)) { builder->unrecoverable_error = true; builder->writers[which].item_used = 0; diff --git a/src/gallium/drivers/ilo/ilo_common.h b/src/gallium/drivers/ilo/ilo_common.h index 23a70805c2a..1ed964f2eca 100644 --- a/src/gallium/drivers/ilo/ilo_common.h +++ b/src/gallium/drivers/ilo/ilo_common.h @@ -63,6 +63,7 @@ enum ilo_debug { ILO_DEBUG_CS = 1 << 4, ILO_DEBUG_DRAW = ILO_DEBUG_HOT << 5, ILO_DEBUG_SUBMIT = 1 << 6, + ILO_DEBUG_HANG = 1 << 7, /* flags that affect the behaviors of the driver */ ILO_DEBUG_NOHW = 1 << 20, @@ -82,7 +83,7 @@ struct ilo_dev_info { bool has_timestamp; bool has_gen7_sol_reset; - /* use ilo_dev_gen() */ + /* use ilo_dev_gen() to access */ int gen_opaque; int gt; diff --git a/src/gallium/drivers/ilo/ilo_cp.c b/src/gallium/drivers/ilo/ilo_cp.c index 67de95b98c9..f78fd1f62f9 100644 --- a/src/gallium/drivers/ilo/ilo_cp.c +++ b/src/gallium/drivers/ilo/ilo_cp.c @@ -105,6 +105,35 @@ ilo_cp_end_batch(struct ilo_cp *cp, unsigned *used) return bo; } +static bool +ilo_cp_detect_hang(struct ilo_cp *cp) +{ + uint32_t active_lost, pending_lost; + bool guilty = false; + + if (likely(!(ilo_debug & ILO_DEBUG_HANG))) + return false; + + /* wait and get reset stats */ + if (intel_bo_wait(cp->last_submitted_bo, -1) || + intel_winsys_get_reset_stats(cp->winsys, cp->render_ctx, + &active_lost, &pending_lost)) + return false; + + if (cp->active_lost != active_lost) { + ilo_err("GPU hang caused by bo %p\n", cp->last_submitted_bo); + cp->active_lost = active_lost; + guilty = true; + } + + if (cp->pending_lost != pending_lost) { + ilo_err("GPU hang detected\n"); + cp->pending_lost = pending_lost; + } + + return guilty; +} + /** * Flush the command parser and execute the commands. When the parser buffer * is empty, the callback is not invoked. @@ -132,13 +161,20 @@ ilo_cp_submit_internal(struct ilo_cp *cp) cp->one_off_flags = 0; if (!err) { + bool guilty; + if (cp->last_submitted_bo) intel_bo_unreference(cp->last_submitted_bo); cp->last_submitted_bo = bo; intel_bo_reference(cp->last_submitted_bo); - if (ilo_debug & ILO_DEBUG_BATCH) + guilty = ilo_cp_detect_hang(cp); + + if (unlikely((ilo_debug & ILO_DEBUG_BATCH) || guilty)) { ilo_builder_decode(&cp->builder); + if (guilty) + abort(); + } if (cp->submit_callback) cp->submit_callback(cp, cp->submit_callback_data); diff --git a/src/gallium/drivers/ilo/ilo_cp.h b/src/gallium/drivers/ilo/ilo_cp.h index 04b3ad5f836..dcab55b6ee2 100644 --- a/src/gallium/drivers/ilo/ilo_cp.h +++ b/src/gallium/drivers/ilo/ilo_cp.h @@ -72,6 +72,9 @@ struct ilo_cp { struct ilo_builder builder; struct intel_bo *last_submitted_bo; + + uint32_t active_lost; + uint32_t pending_lost; }; struct ilo_cp * diff --git a/src/gallium/drivers/ilo/ilo_screen.c b/src/gallium/drivers/ilo/ilo_screen.c index 95e34d3e4de..c9577c8be41 100644 --- a/src/gallium/drivers/ilo/ilo_screen.c +++ b/src/gallium/drivers/ilo/ilo_screen.c @@ -48,13 +48,14 @@ struct ilo_fence { int ilo_debug; static const struct debug_named_value ilo_debug_flags[] = { - { "batch", ILO_DEBUG_BATCH, "Dump batch/state/surface/instruction buffers" }, + { "batch", ILO_DEBUG_BATCH, "Dump batch/dynamic/surface/instruction buffers" }, { "vs", ILO_DEBUG_VS, "Dump vertex shaders" }, { "gs", ILO_DEBUG_GS, "Dump geometry shaders" }, { "fs", ILO_DEBUG_FS, "Dump fragment shaders" }, { "cs", ILO_DEBUG_CS, "Dump compute shaders" }, { "draw", ILO_DEBUG_DRAW, "Show draw information" }, { "submit", ILO_DEBUG_SUBMIT, "Show batch buffer submissions" }, + { "hang", ILO_DEBUG_HANG, "Detect GPU hangs" }, { "nohw", ILO_DEBUG_NOHW, "Do not send commands to HW" }, { "nocache", ILO_DEBUG_NOCACHE, "Always invalidate HW caches" }, { "nohiz", ILO_DEBUG_NOHIZ, "Disable HiZ" }, -- 2.30.2