summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Gordon <david.s.gordon@intel.com>2015-09-25 12:06:20 +0100
committerJohn Harrison <John.C.Harrison@Intel.com>2016-06-28 17:19:16 +0100
commit4800b00c6079665bf3c27198fb91cdc48a9656a0 (patch)
treeb44a5f9aee8b9aaf0a58970ba7f25fe4d071f40e
parent8c90128707ae182a663d1a05ebdb8f10afd0592e (diff)
drm/i915/guc: Improve action error reporting, add preemption debug
For: VIZ-2021 Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c31
-rw-r--r--drivers/gpu/drm/i915/i915_guc_submission.c32
-rw-r--r--drivers/gpu/drm/i915/intel_guc.h12
3 files changed, 51 insertions, 24 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index e90ee473ec9b..067c22276e4f 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2702,8 +2702,8 @@ static int i915_guc_info(struct seq_file *m, void *data)
struct i915_guc_client client = {};
struct i915_guc_client preempt = {};
struct intel_engine_cs *engine;
- enum intel_engine_id i;
- u64 total = 0;
+ enum intel_engine_id r, i;
+ u64 total = 0, preempts = 0;
if (!HAS_GUC_SCHED(dev_priv->dev))
return 0;
@@ -2721,19 +2721,28 @@ static int i915_guc_info(struct seq_file *m, void *data)
mutex_unlock(&dev->struct_mutex);
seq_printf(m, "GuC total action count: %llu\n", guc.action_count);
- seq_printf(m, "GuC action failure count: %u\n", guc.action_fail);
seq_printf(m, "GuC last action command: 0x%x\n", guc.action_cmd);
seq_printf(m, "GuC last action status: 0x%x\n", guc.action_status);
- seq_printf(m, "GuC last action error code: %d\n", guc.action_err);
+
+ seq_printf(m, "GuC action failure count: %u\n", guc.action_fail_count);
+ seq_printf(m, "GuC last failed action: 0x%x\n", guc.action_fail_cmd);
+ seq_printf(m, "GuC last failed status: 0x%x\n", guc.action_fail_status);
+ seq_printf(m, "GuC last error code: %d\n", guc.action_err);
seq_printf(m, "\nGuC submissions:\n");
- for_each_engine(engine, dev_priv, i) {
- seq_printf(m, "\t%-24s: %10llu, last seqno 0x%08x\n",
- engine->name, guc.submissions[engine->guc_id],
- guc.last_seqno[engine->guc_id]);
- total += guc.submissions[engine->guc_id];
- }
- seq_printf(m, "\t%s: %llu\n", "Total", total);
+ for_each_engine(engine, dev_priv, r) {
+ i = engine->guc_id;
+ seq_printf(m, "\t%-24s: %10llu, last %-8s 0x%08x %9d\n",
+ engine->name, guc.submissions[i], "seqno",
+ guc.last_seqno[i], guc.last_seqno[i]);
+ seq_printf(m, "\t%-24s: %10u, last %-8s 0x%08x %9d\n",
+ " preemptions", guc.preemptions[i], "preempt",
+ guc.last_preempt[i], guc.last_preempt[i]);
+ total += guc.submissions[i];
+ preempts += guc.preemptions[i];
+ }
+ seq_printf(m, "\t%s: %10llu\n", "Total regular", total);
+ seq_printf(m, "\t%s: %10llu\n", " preempts", preempts);
seq_printf(m, "\nGuC execbuf client @ %p:\n", guc.execbuf_client);
i915_guc_client_info(m, dev_priv, &client);
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
index a4c30667c5d1..438d15128d93 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -78,9 +78,8 @@ static inline bool host2guc_action_response(struct drm_i915_private *dev_priv,
static int host2guc_action(struct intel_guc *guc, u32 *data, u32 len)
{
struct drm_i915_private *dev_priv = guc_to_i915(guc);
- u32 status;
- int i;
- int ret;
+ u32 status, response;
+ int ret, i;
if (WARN_ON(len < 1 || len > 15))
return -EINVAL;
@@ -100,6 +99,8 @@ static int host2guc_action(struct intel_guc *guc, u32 *data, u32 len)
/* No HOST2GUC command should take longer than 10ms */
ret = wait_for_atomic(host2guc_action_response(dev_priv, &status), 10);
+ response = I915_READ(SOFT_SCRATCH(15));
+ dev_priv->guc.action_status = status;
if (status != GUC2HOST_STATUS_SUCCESS) {
/*
* Either the GuC explicitly returned an error (which
@@ -109,15 +110,15 @@ static int host2guc_action(struct intel_guc *guc, u32 *data, u32 len)
if (ret != -ETIMEDOUT)
ret = -EIO;
- DRM_ERROR("GUC: host2guc action 0x%X failed. ret=%d "
+ DRM_ERROR("GuC: host2guc action 0x%X failed. ret=%d "
"status=0x%08X response=0x%08X\n",
- data[0], ret, status,
- I915_READ(SOFT_SCRATCH(15)));
+ data[0], ret, status, response);
- dev_priv->guc.action_fail += 1;
+ dev_priv->guc.action_fail_count += 1;
+ dev_priv->guc.action_fail_cmd = data[0];
+ dev_priv->guc.action_fail_status = status;
dev_priv->guc.action_err = ret;
}
- dev_priv->guc.action_status = status;
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
@@ -139,7 +140,7 @@ host2guc_preempt(struct i915_guc_client *client,
struct intel_ringbuffer *ringbuf = ctx->engine[engine_id].ringbuf;
struct guc_process_desc *desc;
void *base;
- u32 data[7];
+ u32 data[8];
int ret;
if (WARN_ON(!ctx_obj || !ringbuf))
@@ -642,8 +643,17 @@ int i915_guc_submit(struct i915_guc_client *client,
client->retcode = 0;
rq->elsp_submitted += 1;
}
- guc->submissions[engine_id] += 1;
- guc->last_seqno[engine_id] = rq->seqno;
+ if (preemptive) {
+ guc->preemptions[engine_id] += 1;
+ guc->last_preempt[engine_id] = rq->seqno;
+ if (q_ret)
+ guc->preempt_failures[engine_id] += 1;
+ } else {
+ guc->submissions[engine_id] += 1;
+ guc->last_seqno[engine_id] = rq->seqno;
+ if (q_ret)
+ guc->failures[engine_id] += 1;
+ }
return q_ret;
}
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index 47658d2d4514..e9bfb65be7a6 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -106,11 +106,19 @@ struct intel_guc {
uint64_t action_count; /* Total commands issued */
uint32_t action_cmd; /* Last command word */
uint32_t action_status; /* Last return status */
- uint32_t action_fail; /* Total number of failures */
- int32_t action_err; /* Last error code */
+ uint32_t action_fail_count; /* Total number of failures */
+ uint32_t action_fail_cmd; /* Last failed command */
+ uint32_t action_fail_status; /* Last bad return status */
+ int32_t action_err; /* Last (nonzero) error code */
+
+ /* Submission status & statistics */
uint64_t submissions[GUC_MAX_ENGINES_NUM];
uint32_t last_seqno[GUC_MAX_ENGINES_NUM];
+ uint32_t failures[GUC_MAX_ENGINES_NUM];
+ uint32_t preemptions[GUC_MAX_ENGINES_NUM];
+ uint32_t last_preempt[GUC_MAX_ENGINES_NUM];
+ uint32_t preempt_failures[GUC_MAX_ENGINES_NUM];
};
/* intel_guc_loader.c */