Mesa (master): ilo: add ILO_DEBUG=hang

Chia-I Wu olv at kemper.freedesktop.org
Wed Mar 4 20:55:44 UTC 2015


Module: Mesa
Branch: master
Commit: 68d2e395d9e18898ef74a635a93dfc4501c1c507
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=68d2e395d9e18898ef74a635a93dfc4501c1c507

Author: Chia-I Wu <olvaffe at gmail.com>
Date:   Wed Mar  4 13:07:55 2015 -0700

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 0de7b5d..c902a8f 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 23a7080..1ed964f 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 67de95b..f78fd1f 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 04b3ad5..dcab55b 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 95e34d3..c9577c8 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" },




More information about the mesa-commit mailing list