i965: Mark shader programs for capture in the error state.
authorMatt Turner <mattst88@gmail.com>
Tue, 25 Apr 2017 17:00:19 +0000 (10:00 -0700)
committerMatt Turner <mattst88@gmail.com>
Mon, 15 May 2017 18:42:41 +0000 (11:42 -0700)
When the GPU hangs, the kernel saves some state for us. Until now it has
not included the shader programs, which are very often the reason the
GPU hang occurred. With the programs saved in the error state, we should
be more capable of debugging hangs.

Thanks to Chris Wilson and Ben Widawsky who provided the kernel support
for this feature ("drm/i915: Copy user requested buffers into the error
state"), which will be in kernel v4.13.

Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
src/mesa/drivers/dri/i965/brw_bufmgr.c
src/mesa/drivers/dri/i965/brw_bufmgr.h
src/mesa/drivers/dri/i965/brw_program_cache.c
src/mesa/drivers/dri/i965/intel_batchbuffer.c
src/mesa/drivers/dri/i965/intel_screen.c
src/mesa/drivers/dri/i965/intel_screen.h

index 4b6433178d06ca576e9efc8f09c32d62c76a1a98..2f179347009b5b85215a13c064d872d388c162b3 100644 (file)
@@ -599,6 +599,7 @@ bo_unreference_final(struct brw_bo *bo, time_t time)
       bo->free_time = time;
 
       bo->name = NULL;
+      bo->kflags = 0;
 
       list_addtail(&bo->head, &bucket->head);
    } else {
index 1b1790a8cb4257953d2565a9a28d19183659daf4..56ec206d303593a283308a2e8380d5cbfe590f65 100644 (file)
@@ -97,6 +97,11 @@ struct brw_bo {
    int refcount;
    const char *name;
 
+#ifndef EXEC_OBJECT_CAPTURE
+#define EXEC_OBJECT_CAPTURE            (1<<7)
+#endif
+   uint64_t kflags;
+
    /**
     * Kenel-assigned global name for this object
     *
index b0e2962f88f38da39a53bc5792253b52771f7f5b..d3555b4239150a5fbcc6e7c12caeac40165ad93f 100644 (file)
@@ -216,6 +216,8 @@ brw_cache_new_bo(struct brw_cache *cache, uint32_t new_size)
    struct brw_bo *new_bo;
 
    new_bo = brw_bo_alloc(brw->bufmgr, "program cache", new_size, 64);
+   if (can_do_exec_capture(brw->screen))
+      new_bo->kflags = EXEC_OBJECT_CAPTURE;
    if (brw->has_llc)
       brw_bo_map_unsynchronized(brw, new_bo);
 
@@ -407,6 +409,8 @@ brw_init_caches(struct brw_context *brw)
       calloc(cache->size, sizeof(struct brw_cache_item *));
 
    cache->bo = brw_bo_alloc(brw->bufmgr, "program cache",  4096, 64);
+   if (can_do_exec_capture(brw->screen))
+      cache->bo->kflags = EXEC_OBJECT_CAPTURE;
    if (brw->has_llc)
       brw_bo_map_unsynchronized(brw, cache->bo);
 }
index 2818458384d7104b7f1e1ccd5bc153332dd568de..36faa7ae6f514d01358291501851be7f2dac5b0b 100644 (file)
@@ -550,7 +550,7 @@ add_exec_bo(struct intel_batchbuffer *batch, struct brw_bo *bo)
    }
    validation_entry->alignment = bo->align;
    validation_entry->offset = bo->offset64;
-   validation_entry->flags = 0;
+   validation_entry->flags = bo->kflags;
    validation_entry->rsvd1 = 0;
    validation_entry->rsvd2 = 0;
 
index 371772867e9119204d7f1fe9cfa45dad5f50b03a..91ed128f8320dffb413db2fbb8b4cfd67bc7d801 100644 (file)
@@ -2029,6 +2029,14 @@ __DRIconfig **intelInitScreen2(__DRIscreen *dri_screen)
       screen->cmd_parser_version = 0;
    }
 
+   /* Kernel 4.13 retuired for exec object capture */
+#ifndef I915_PARAM_HAS_EXEC_CAPTURE
+#define I915_PARAM_HAS_EXEC_CAPTURE 45
+#endif
+   if (intel_get_boolean(screen, I915_PARAM_HAS_EXEC_CAPTURE)) {
+      screen->kernel_features |= KERNEL_ALLOWS_EXEC_CAPTURE;
+   }
+
    if (!intel_detect_pipelined_so(screen)) {
       /* We can't do anything, so the effective version is 0. */
       screen->cmd_parser_version = 0;
index fe0e0444b2d1e23b4359a2bddadf879b8a19e858..f9c1db6df1237f673ef35a9d472f234e61d58b5a 100644 (file)
@@ -74,6 +74,7 @@ struct intel_screen
 #define KERNEL_ALLOWS_MI_MATH_AND_LRR               (1<<2)
 #define KERNEL_ALLOWS_HSW_SCRATCH1_AND_ROW_CHICKEN3 (1<<3)
 #define KERNEL_ALLOWS_COMPUTE_DISPATCH              (1<<4)
+#define KERNEL_ALLOWS_EXEC_CAPTURE                  (1<<5)
 
    struct brw_bufmgr *bufmgr;
 
@@ -155,6 +156,12 @@ can_do_predicate_writes(const struct intel_screen *screen)
    return screen->kernel_features & KERNEL_ALLOWS_PREDICATE_WRITES;
 }
 
+static inline bool
+can_do_exec_capture(const struct intel_screen *screen)
+{
+   return screen->kernel_features & KERNEL_ALLOWS_EXEC_CAPTURE;
+}
+
 #ifdef __cplusplus
 }
 #endif