This adds a hint on where the call trace originated from with a helper macro GUESS_ORIGIN. As its name says, it is more of a guess, but still, it seems to be quite accurate on most of the traces.
The results of the heuristics are printed at the end of the decoding: ... 0x00062fe8: 0x00000000: MI_NOOP 0x00062fec: 0x00000000: MI_NOOP 0x00062ff0: 0x00000000: MI_NOOP 0x00062ff4: 0x00000000: MI_NOOP 0x00062ff8: 0x00000000: MI_NOOP 0x00062ffc: 0x00000000: MI_NOOP Heuristics analysis: Possible origin: mesa (indicated by 3DSTATE_CONSTANT_VS_STATE) Possible origin: mesa (indicated by 3DSTATE_VS_STATE) Signed-off-by: Eugeni Dodonov <eugeni.dodo...@intel.com> --- tools/intel_decode.c | 54 ++++++++++++++++++++++++++++++++++++++++++- tools/intel_decode.h | 1 + tools/intel_error_decode.c | 1 + 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/tools/intel_decode.c b/tools/intel_decode.c index d1218cd..c519888 100644 --- a/tools/intel_decode.c +++ b/tools/intel_decode.c @@ -46,6 +46,48 @@ static uint32_t tail_offset = 0xffffffff; /* undefined */ return count; \ } while (0) +struct _heuristic_t { + char *possible_origin; + char *opcode_name; + int opcode; +} heuristics[10]; +int cur_heuristic=0; + +/** + * This macro attempts to guess origin of the hang, or original caller of the + * batchbuffer by matching the opcodes to possible origins defined below + */ +#define GUESS_ORIGIN(opcode, opcodes) for (int i=0; i < ARRAY_SIZE(opcodes); i++) \ + if (opcode == opcodes[i].opcode) \ + if (opcodes[i].possible_origin && cur_heuristic < ARRAY_SIZE(heuristics)) { \ + int duplicate = 0; \ + for (int j=0; j < cur_heuristic; j++) { \ + if (heuristics[j].opcode == opcode) \ + duplicate = 1; \ + } \ + if (!duplicate) { \ + struct _heuristic_t tmp = { opcodes[i].possible_origin, opcodes[i].name, opcodes[i].opcode }; \ + heuristics[cur_heuristic++] = tmp; \ + } \ + } + +void +print_heuristics() +{ + int i; + fprintf(out, "Heuristics analysis:\n"); + if (cur_heuristic == 0) + fprintf(out, "Nothing suspicious.\n"); + else { + for (i=0; i < cur_heuristic; i++) { + fprintf(out, "Possible origin: %s (indicated by %s)\n", + heuristics[i].possible_origin, + heuristics[i].opcode_name); + } + if (i == ARRAY_SIZE(heuristics)) + fprintf(out, "Heuristics buffer full, additional guesses not attempted\n"); + } +} static float int_as_float(uint32_t intval) @@ -94,6 +136,7 @@ decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures) int min_len; int max_len; char *name; + char *possible_origin; } opcodes_mi[] = { { 0x08, 0, 1, 1, "MI_ARB_ON_OFF" }, { 0x0a, 0, 1, 1, "MI_BATCH_BUFFER_END" }, @@ -223,6 +266,7 @@ decode_2d(uint32_t *data, int count, uint32_t hw_offset, int *failures) int min_len; int max_len; char *name; + char *possible_origin; } opcodes_2d[] = { { 0x40, 5, 5, "COLOR_BLT" }, { 0x43, 6, 6, "SRC_COPY_BLT" }, @@ -993,6 +1037,7 @@ decode_3d_1d(uint32_t *data, int count, int min_len; int max_len; char *name; + char *possible_origin; } opcodes_3d_1d[] = { { 0x86, 0, 4, 4, "3DSTATE_CHROMA_KEY" }, { 0x88, 0, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" }, @@ -1836,6 +1881,7 @@ decode_3d(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid, int *fa int min_len; int max_len; char *name; + char *possible_origin; } opcodes_3d[] = { { 0x06, 1, 1, "3DSTATE_ANTI_ALIASING" }, { 0x08, 1, 1, "3DSTATE_BACKFACE_STENCIL_OPS" }, @@ -2061,6 +2107,7 @@ decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid, int int min_len; int max_len; char *name; + char *possible_origin; } opcodes_3d[] = { { 0x6000, 3, 3, "URB_FENCE" }, { 0x6001, 2, 2, "CS_URB_STATE" }, @@ -2094,12 +2141,12 @@ decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid, int { 0x780d, 4, 4, "3DSTATE_VIEWPORT_STATE_POINTERS" }, { 0x780e, 4, 4, "3DSTATE_CC_STATE_POINTERS" }, { 0x780f, 2, 2, "3DSTATE_SCISSOR_STATE_POINTERS" }, - { 0x7810, 6, 6, "3DSTATE_VS_STATE" }, + { 0x7810, 6, 6, "3DSTATE_VS_STATE", "mesa" }, { 0x7811, 7, 7, "3DSTATE_GS_STATE" }, { 0x7812, 4, 4, "3DSTATE_CLIP_STATE" }, { 0x7813, 20, 20, "3DSTATE_SF_STATE" }, { 0x7814, 9, 9, "3DSTATE_WM_STATE" }, - { 0x7815, 5, 5, "3DSTATE_CONSTANT_VS_STATE" }, + { 0x7815, 5, 5, "3DSTATE_CONSTANT_VS_STATE", "mesa" }, { 0x7816, 5, 5, "3DSTATE_CONSTANT_GS_STATE" }, { 0x7817, 5, 5, "3DSTATE_CONSTANT_PS_STATE" }, { 0x7818, 2, 2, "3DSTATE_SAMPLE_MASK" }, @@ -2108,6 +2155,8 @@ decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid, int len = (data[0] & 0x0000ffff) + 2; opcode = (data[0] & 0xffff0000) >> 16; + /* Try to guess where the issue comes from */ + GUESS_ORIGIN(opcode, opcodes_3d); switch (opcode) { case 0x6000: len = (data[0] & 0x000000ff) + 2; @@ -2710,6 +2759,7 @@ decode_3d_i830(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid, in int min_len; int max_len; char *name; + char *possible_origin; } opcodes_3d[] = { { 0x02, 1, 1, "3DSTATE_MODES_3" }, { 0x03, 1, 1, "3DSTATE_ENABLES_1"}, diff --git a/tools/intel_decode.h b/tools/intel_decode.h index 1dec8fe..b5ef79c 100644 --- a/tools/intel_decode.h +++ b/tools/intel_decode.h @@ -33,3 +33,4 @@ int intel_decode(uint32_t *data, int count, uint32_t ignore_end_of_batchbuffer); void intel_decode_context_set_head_tail(uint32_t head, uint32_t tail); void intel_decode_context_reset(void); +void print_heuristics(void); diff --git a/tools/intel_error_decode.c b/tools/intel_error_decode.c index 0ad6645..6bdaf33 100644 --- a/tools/intel_error_decode.c +++ b/tools/intel_error_decode.c @@ -369,6 +369,7 @@ read_data_file (FILE *file) if (count) { printf("%s at 0x%08x:\n", buffer_type[is_batch], gtt_offset); intel_decode (data, count, gtt_offset, devid, 0); + print_heuristics(); } free (data); -- 1.7.7 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx