From 92ceff4dceae1d17bd326f0eb2cfb93e3d20249b Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Thu, 25 Jul 2024 14:08:14 -0400 Subject: [PATCH] freedreno/crashdec: Handle hangs where the SQE is in RB This is by far the most common cause of missing an "ESTIMATED HANG LOCATION" - the SQE is processing kernel commands, even if the rest of the GPU isn't. Part-of: --- src/freedreno/decode/cffdec.c | 12 ++++++++---- src/freedreno/decode/cffdec.h | 5 +++++ src/freedreno/decode/crashdec-prefetch.c | 5 +++++ src/freedreno/decode/crashdec.c | 4 ++++ 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/freedreno/decode/cffdec.c b/src/freedreno/decode/cffdec.c index 6c1693d9fb8..0dad7412579 100644 --- a/src/freedreno/decode/cffdec.c +++ b/src/freedreno/decode/cffdec.c @@ -152,7 +152,7 @@ static void dump_tex_const(uint32_t *texsamp, int num_unit, int level); static bool highlight_addr(uint32_t *hostaddr) { - if (!options->ibs[ib].base) + if (!options->ibs[ib].base && (ib != 0 || !options->rb_host_base)) return false; if ((ib > 0) && options->ibs[ib - 1].base && @@ -165,11 +165,15 @@ highlight_addr(uint32_t *hostaddr) if (ibs[ib].triggered) return options->color; - if (options->ibs[ib].base != ibs[ib].base) + if (ib != 0 && options->ibs[ib].base != ibs[ib].base) return false; - uint32_t *start = ibs[ib].host_base + (ibs[ib].size - options->ibs[ib].rem); - uint32_t *end = ibs[ib].host_base + ibs[ib].size; + uint32_t *host_base = (ib != 0) ? ibs[ib].host_base : + options->rb_host_base; + uint32_t size = options->ibs[ib].size ? options->ibs[ib].size : + ibs[ib].size; + uint32_t *start = host_base + (size - options->ibs[ib].rem); + uint32_t *end = host_base + size; bool triggered = (start <= hostaddr) && (hostaddr <= end); diff --git a/src/freedreno/decode/cffdec.h b/src/freedreno/decode/cffdec.h index 95748307cba..6788326a299 100644 --- a/src/freedreno/decode/cffdec.h +++ b/src/freedreno/decode/cffdec.h @@ -63,8 +63,13 @@ struct cffdec_options { struct { uint64_t base; uint32_t rem; + uint32_t size; bool crash_found : 1; } ibs[4]; + + /* Ringbuffer addresses are non-contiguous so we use the host address. + */ + uint32_t *rb_host_base; }; /** diff --git a/src/freedreno/decode/crashdec-prefetch.c b/src/freedreno/decode/crashdec-prefetch.c index 8061cd3ba99..f6f52007107 100644 --- a/src/freedreno/decode/crashdec-prefetch.c +++ b/src/freedreno/decode/crashdec-prefetch.c @@ -176,6 +176,11 @@ void handle_prefetch(uint32_t *dwords, uint32_t sizedwords) { struct prefetch_state rb_state = {}; + + /* If the GPU crashed in RB, skip processing IB1 */ + if (!options.ibs[1].rem) + return; + struct ib *ib1 = scan_cmdstream(&rb_state, 1, dwords, sizedwords); if (!ib1) diff --git a/src/freedreno/decode/crashdec.c b/src/freedreno/decode/crashdec.c index 3eb18c5de11..8b5e675dafc 100644 --- a/src/freedreno/decode/crashdec.c +++ b/src/freedreno/decode/crashdec.c @@ -445,6 +445,10 @@ dump_cmdstream(void) buf[idx] = ringbuffers[id].buf[p]; } + options.rb_host_base = buf; + options.ibs[0].rem = mod_add(ringbuffers[id].wptr, -rb_rptr); + options.ibs[0].size = cmdszdw; + handle_prefetch(buf, cmdszdw); dump_commands(buf, cmdszdw, 0); free(buf);