[Intel-gfx] [RFC 13/37] drm/i915/guc: Improve action error reporting, add preemption debug
John.C.Harrison at Intel.com
John.C.Harrison at Intel.com
Mon Nov 23 03:41:48 PST 2015
From: Dave Gordon <david.s.gordon at intel.com>
For: VIZ-2021
Signed-off-by: Dave Gordon <david.s.gordon at intel.com>
---
drivers/gpu/drm/i915/i915_debugfs.c | 20 +++++++++++++------
drivers/gpu/drm/i915/i915_guc_submission.c | 32 ++++++++++++++++++++----------
drivers/gpu/drm/i915/intel_guc.h | 12 +++++++++--
3 files changed, 45 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 9e8f624..e9372ac 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2693,7 +2693,7 @@ static int i915_guc_info(struct seq_file *m, void *data)
struct i915_guc_client preempt = {};
struct intel_engine_cs *ring;
enum intel_ring_id i;
- u64 total = 0;
+ u64 total = 0, preempts = 0;
if (!HAS_GUC_SCHED(dev_priv->dev))
return 0;
@@ -2714,19 +2714,27 @@ static int i915_guc_info(struct seq_file *m, void *data)
spin_unlock(&dev_priv->guc.host2guc_lock);
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_ring(ring, dev_priv, i) {
- seq_printf(m, "\t%-24s: %10llu, last seqno 0x%08x %9d\n",
- ring->name, guc.submissions[i],
+ seq_printf(m, "\t%-24s: %10llu, last %-8s 0x%08x %9d\n",
+ ring->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: %llu\n", "Total", total);
+ 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 4035ac6..38c431d 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;
@@ -101,6 +100,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
@@ -110,15 +111,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;
spin_unlock(&dev_priv->guc.host2guc_lock);
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
@@ -141,7 +142,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))
@@ -672,8 +673,17 @@ int i915_guc_submit(struct i915_guc_client *client,
spin_unlock_irqrestore(&client->wq_lock, flags);
spin_lock(&guc->host2guc_lock);
- guc->submissions[ring_id] += 1;
- guc->last_seqno[ring_id] = rq->seqno;
+ if (preemptive) {
+ guc->preemptions[ring_id] += 1;
+ guc->last_preempt[ring_id] = rq->seqno;
+ if (q_ret)
+ guc->preempt_failures[ring_id] += 1;
+ } else {
+ guc->submissions[ring_id] += 1;
+ guc->last_seqno[ring_id] = rq->seqno;
+ if (q_ret)
+ guc->failures[ring_id] += 1;
+ }
spin_unlock(&guc->host2guc_lock);
return q_ret;
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index f56e0d9..0793713 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -105,11 +105,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[I915_NUM_RINGS];
uint32_t last_seqno[I915_NUM_RINGS];
+ uint32_t failures[I915_NUM_RINGS];
+ uint32_t preemptions[I915_NUM_RINGS];
+ uint32_t last_preempt[I915_NUM_RINGS];
+ uint32_t preempt_failures[I915_NUM_RINGS];
};
/* intel_guc_loader.c */
--
1.9.1
More information about the Intel-gfx
mailing list