ilo: add ILO_DEBUG=hang
When set, detect and dump the hanging batch bufffer.
This commit is contained in:
@@ -171,7 +171,7 @@ ilo_builder_writer_checked_record(struct ilo_builder *builder,
|
||||
enum ilo_builder_item_type item,
|
||||
unsigned offset, unsigned size)
|
||||
{
|
||||
if (unlikely(ilo_debug & ILO_DEBUG_BATCH)) {
|
||||
if (unlikely(ilo_debug & (ILO_DEBUG_BATCH | ILO_DEBUG_HANG))) {
|
||||
if (!ilo_builder_writer_record(builder, which, item, offset, size)) {
|
||||
builder->unrecoverable_error = true;
|
||||
builder->writers[which].item_used = 0;
|
||||
|
||||
@@ -63,6 +63,7 @@ enum ilo_debug {
|
||||
ILO_DEBUG_CS = 1 << 4,
|
||||
ILO_DEBUG_DRAW = ILO_DEBUG_HOT << 5,
|
||||
ILO_DEBUG_SUBMIT = 1 << 6,
|
||||
ILO_DEBUG_HANG = 1 << 7,
|
||||
|
||||
/* flags that affect the behaviors of the driver */
|
||||
ILO_DEBUG_NOHW = 1 << 20,
|
||||
@@ -82,7 +83,7 @@ struct ilo_dev_info {
|
||||
bool has_timestamp;
|
||||
bool has_gen7_sol_reset;
|
||||
|
||||
/* use ilo_dev_gen() */
|
||||
/* use ilo_dev_gen() to access */
|
||||
int gen_opaque;
|
||||
|
||||
int gt;
|
||||
|
||||
@@ -105,6 +105,35 @@ ilo_cp_end_batch(struct ilo_cp *cp, unsigned *used)
|
||||
return bo;
|
||||
}
|
||||
|
||||
static bool
|
||||
ilo_cp_detect_hang(struct ilo_cp *cp)
|
||||
{
|
||||
uint32_t active_lost, pending_lost;
|
||||
bool guilty = false;
|
||||
|
||||
if (likely(!(ilo_debug & ILO_DEBUG_HANG)))
|
||||
return false;
|
||||
|
||||
/* wait and get reset stats */
|
||||
if (intel_bo_wait(cp->last_submitted_bo, -1) ||
|
||||
intel_winsys_get_reset_stats(cp->winsys, cp->render_ctx,
|
||||
&active_lost, &pending_lost))
|
||||
return false;
|
||||
|
||||
if (cp->active_lost != active_lost) {
|
||||
ilo_err("GPU hang caused by bo %p\n", cp->last_submitted_bo);
|
||||
cp->active_lost = active_lost;
|
||||
guilty = true;
|
||||
}
|
||||
|
||||
if (cp->pending_lost != pending_lost) {
|
||||
ilo_err("GPU hang detected\n");
|
||||
cp->pending_lost = pending_lost;
|
||||
}
|
||||
|
||||
return guilty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the command parser and execute the commands. When the parser buffer
|
||||
* is empty, the callback is not invoked.
|
||||
@@ -132,13 +161,20 @@ ilo_cp_submit_internal(struct ilo_cp *cp)
|
||||
cp->one_off_flags = 0;
|
||||
|
||||
if (!err) {
|
||||
bool guilty;
|
||||
|
||||
if (cp->last_submitted_bo)
|
||||
intel_bo_unreference(cp->last_submitted_bo);
|
||||
cp->last_submitted_bo = bo;
|
||||
intel_bo_reference(cp->last_submitted_bo);
|
||||
|
||||
if (ilo_debug & ILO_DEBUG_BATCH)
|
||||
guilty = ilo_cp_detect_hang(cp);
|
||||
|
||||
if (unlikely((ilo_debug & ILO_DEBUG_BATCH) || guilty)) {
|
||||
ilo_builder_decode(&cp->builder);
|
||||
if (guilty)
|
||||
abort();
|
||||
}
|
||||
|
||||
if (cp->submit_callback)
|
||||
cp->submit_callback(cp, cp->submit_callback_data);
|
||||
|
||||
@@ -72,6 +72,9 @@ struct ilo_cp {
|
||||
|
||||
struct ilo_builder builder;
|
||||
struct intel_bo *last_submitted_bo;
|
||||
|
||||
uint32_t active_lost;
|
||||
uint32_t pending_lost;
|
||||
};
|
||||
|
||||
struct ilo_cp *
|
||||
|
||||
@@ -48,13 +48,14 @@ struct ilo_fence {
|
||||
int ilo_debug;
|
||||
|
||||
static const struct debug_named_value ilo_debug_flags[] = {
|
||||
{ "batch", ILO_DEBUG_BATCH, "Dump batch/state/surface/instruction buffers" },
|
||||
{ "batch", ILO_DEBUG_BATCH, "Dump batch/dynamic/surface/instruction buffers" },
|
||||
{ "vs", ILO_DEBUG_VS, "Dump vertex shaders" },
|
||||
{ "gs", ILO_DEBUG_GS, "Dump geometry shaders" },
|
||||
{ "fs", ILO_DEBUG_FS, "Dump fragment shaders" },
|
||||
{ "cs", ILO_DEBUG_CS, "Dump compute shaders" },
|
||||
{ "draw", ILO_DEBUG_DRAW, "Show draw information" },
|
||||
{ "submit", ILO_DEBUG_SUBMIT, "Show batch buffer submissions" },
|
||||
{ "hang", ILO_DEBUG_HANG, "Detect GPU hangs" },
|
||||
{ "nohw", ILO_DEBUG_NOHW, "Do not send commands to HW" },
|
||||
{ "nocache", ILO_DEBUG_NOCACHE, "Always invalidate HW caches" },
|
||||
{ "nohiz", ILO_DEBUG_NOHIZ, "Disable HiZ" },
|
||||
|
||||
Reference in New Issue
Block a user