radv: dump the active shaders when a hang occured
Only the disassembly is currently dumped. Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
This commit is contained in:
@@ -81,13 +81,77 @@ radv_dump_trace(struct radv_device *device, struct radeon_winsys_cs *cs)
|
|||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
radv_dump_shader(struct radv_shader_variant *shader, gl_shader_stage stage,
|
||||||
|
FILE *f)
|
||||||
|
{
|
||||||
|
if (!shader)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fprintf(f, "%s:\n%s\n\n", radv_get_shader_name(shader, stage),
|
||||||
|
shader->disasm_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
radv_dump_shaders(struct radv_pipeline *pipeline,
|
||||||
|
struct radv_shader_variant *compute_shader, FILE *f)
|
||||||
|
{
|
||||||
|
unsigned mask;
|
||||||
|
|
||||||
|
/* Dump active graphics shaders. */
|
||||||
|
mask = pipeline->active_stages;
|
||||||
|
while (mask) {
|
||||||
|
int stage = u_bit_scan(&mask);
|
||||||
|
|
||||||
|
radv_dump_shader(pipeline->shaders[stage], stage, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
radv_dump_shader(compute_shader, MESA_SHADER_COMPUTE, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
radv_dump_graphics_state(struct radv_pipeline *graphics_pipeline,
|
||||||
|
struct radv_pipeline *compute_pipeline, FILE *f)
|
||||||
|
{
|
||||||
|
struct radv_shader_variant *compute_shader =
|
||||||
|
compute_pipeline ? compute_pipeline->shaders[MESA_SHADER_COMPUTE] : NULL;
|
||||||
|
|
||||||
|
if (!graphics_pipeline)
|
||||||
|
return;
|
||||||
|
|
||||||
|
radv_dump_shaders(graphics_pipeline, compute_shader, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
radv_dump_compute_state(struct radv_pipeline *compute_pipeline, FILE *f)
|
||||||
|
{
|
||||||
|
if (!compute_pipeline)
|
||||||
|
return;
|
||||||
|
|
||||||
|
radv_dump_shaders(compute_pipeline,
|
||||||
|
compute_pipeline->shaders[MESA_SHADER_COMPUTE], f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct radv_pipeline *
|
||||||
|
radv_get_saved_graphics_pipeline(struct radv_device *device)
|
||||||
|
{
|
||||||
|
uint64_t *ptr = (uint64_t *)device->trace_id_ptr;
|
||||||
|
|
||||||
|
return (struct radv_pipeline *)ptr[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct radv_pipeline *
|
||||||
|
radv_get_saved_compute_pipeline(struct radv_device *device)
|
||||||
|
{
|
||||||
|
uint64_t *ptr = (uint64_t *)device->trace_id_ptr;
|
||||||
|
|
||||||
|
return (struct radv_pipeline *)ptr[2];
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
radv_gpu_hang_occured(struct radv_queue *queue)
|
radv_gpu_hang_occured(struct radv_queue *queue, enum ring_type ring)
|
||||||
{
|
{
|
||||||
struct radeon_winsys *ws = queue->device->ws;
|
struct radeon_winsys *ws = queue->device->ws;
|
||||||
enum ring_type ring;
|
|
||||||
|
|
||||||
ring = radv_queue_family_to_ring(queue->queue_family_index);
|
|
||||||
|
|
||||||
if (!ws->ctx_wait_idle(queue->hw_ctx, ring, queue->queue_idx))
|
if (!ws->ctx_wait_idle(queue->hw_ctx, ring, queue->queue_idx))
|
||||||
return true;
|
return true;
|
||||||
@@ -98,10 +162,14 @@ radv_gpu_hang_occured(struct radv_queue *queue)
|
|||||||
void
|
void
|
||||||
radv_check_gpu_hangs(struct radv_queue *queue, struct radeon_winsys_cs *cs)
|
radv_check_gpu_hangs(struct radv_queue *queue, struct radeon_winsys_cs *cs)
|
||||||
{
|
{
|
||||||
|
struct radv_pipeline *graphics_pipeline, *compute_pipeline;
|
||||||
struct radv_device *device = queue->device;
|
struct radv_device *device = queue->device;
|
||||||
|
enum ring_type ring;
|
||||||
uint64_t addr;
|
uint64_t addr;
|
||||||
|
|
||||||
bool hang_occurred = radv_gpu_hang_occured(queue);
|
ring = radv_queue_family_to_ring(queue->queue_family_index);
|
||||||
|
|
||||||
|
bool hang_occurred = radv_gpu_hang_occured(queue, ring);
|
||||||
bool vm_fault_occurred = false;
|
bool vm_fault_occurred = false;
|
||||||
if (queue->device->instance->debug_flags & RADV_DEBUG_VM_FAULTS)
|
if (queue->device->instance->debug_flags & RADV_DEBUG_VM_FAULTS)
|
||||||
vm_fault_occurred = ac_vm_fault_occured(device->physical_device->rad_info.chip_class,
|
vm_fault_occurred = ac_vm_fault_occured(device->physical_device->rad_info.chip_class,
|
||||||
@@ -109,11 +177,27 @@ radv_check_gpu_hangs(struct radv_queue *queue, struct radeon_winsys_cs *cs)
|
|||||||
if (!hang_occurred && !vm_fault_occurred)
|
if (!hang_occurred && !vm_fault_occurred)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
graphics_pipeline = radv_get_saved_graphics_pipeline(device);
|
||||||
|
compute_pipeline = radv_get_saved_compute_pipeline(device);
|
||||||
|
|
||||||
if (vm_fault_occurred) {
|
if (vm_fault_occurred) {
|
||||||
fprintf(stderr, "VM fault report.\n\n");
|
fprintf(stderr, "VM fault report.\n\n");
|
||||||
fprintf(stderr, "Failing VM page: 0x%08"PRIx64"\n\n", addr);
|
fprintf(stderr, "Failing VM page: 0x%08"PRIx64"\n\n", addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (ring) {
|
||||||
|
case RING_GFX:
|
||||||
|
radv_dump_graphics_state(graphics_pipeline, compute_pipeline,
|
||||||
|
stderr);
|
||||||
|
break;
|
||||||
|
case RING_COMPUTE:
|
||||||
|
radv_dump_compute_state(compute_pipeline, stderr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
radv_dump_trace(queue->device, cs);
|
radv_dump_trace(queue->device, cs);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user