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: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34063>
This commit is contained in:
Connor Abbott 2024-07-25 14:08:14 -04:00 committed by Marge Bot
parent 4667ec043b
commit 92ceff4dce
4 changed files with 22 additions and 4 deletions

View file

@ -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);

View file

@ -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;
};
/**

View file

@ -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)

View file

@ -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);