drm/i915: Move per ring error state to ring_error

v2: Moved num_requests up (Chris)
Rebased on new hws page capture which required a rename since it made
two members named, 'hws' in the per ring error state. (Ben)

Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
Ben Widawsky 2014-01-30 00:19:38 -08:00 committed by Daniel Vetter
parent 585b028871
commit 362b8af7ad
2 changed files with 104 additions and 103 deletions

View File

@ -313,48 +313,50 @@ struct drm_i915_error_state {
struct intel_overlay_error_state *overlay; struct intel_overlay_error_state *overlay;
struct intel_display_error_state *display; struct intel_display_error_state *display;
/* Per ring register state
* TODO: Move these to per ring */
u32 tail[I915_NUM_RINGS];
u32 head[I915_NUM_RINGS];
u32 ctl[I915_NUM_RINGS];
u32 hws[I915_NUM_RINGS];
u32 ipeir[I915_NUM_RINGS];
u32 ipehr[I915_NUM_RINGS];
u32 instdone[I915_NUM_RINGS];
u32 acthd[I915_NUM_RINGS];
u32 bbstate[I915_NUM_RINGS];
u32 instpm[I915_NUM_RINGS];
u32 instps[I915_NUM_RINGS];
u32 seqno[I915_NUM_RINGS];
u64 bbaddr[I915_NUM_RINGS];
u32 fault_reg[I915_NUM_RINGS];
u32 faddr[I915_NUM_RINGS];
u32 rc_psmi[I915_NUM_RINGS]; /* sleep state */
u32 semaphore_mboxes[I915_NUM_RINGS][I915_NUM_RINGS - 1];
/* Software tracked state */
bool waiting[I915_NUM_RINGS];
int hangcheck_score[I915_NUM_RINGS];
enum intel_ring_hangcheck_action hangcheck_action[I915_NUM_RINGS];
/* our own tracking of ring head and tail */
u32 cpu_ring_head[I915_NUM_RINGS];
u32 cpu_ring_tail[I915_NUM_RINGS];
u32 semaphore_seqno[I915_NUM_RINGS][I915_NUM_RINGS - 1];
struct drm_i915_error_ring { struct drm_i915_error_ring {
bool valid; bool valid;
/* Software tracked state */
bool waiting;
int hangcheck_score;
enum intel_ring_hangcheck_action hangcheck_action;
int num_requests;
/* our own tracking of ring head and tail */
u32 cpu_ring_head;
u32 cpu_ring_tail;
u32 semaphore_seqno[I915_NUM_RINGS - 1];
/* Register state */
u32 tail;
u32 head;
u32 ctl;
u32 hws;
u32 ipeir;
u32 ipehr;
u32 instdone;
u32 acthd;
u32 bbstate;
u32 instpm;
u32 instps;
u32 seqno;
u64 bbaddr;
u32 fault_reg;
u32 faddr;
u32 rc_psmi; /* sleep state */
u32 semaphore_mboxes[I915_NUM_RINGS - 1];
struct drm_i915_error_object { struct drm_i915_error_object {
int page_count; int page_count;
u32 gtt_offset; u32 gtt_offset;
u32 *pages[0]; u32 *pages[0];
} *ringbuffer, *batchbuffer, *ctx, *hws; } *ringbuffer, *batchbuffer, *ctx, *hws_page;
struct drm_i915_error_request { struct drm_i915_error_request {
long jiffies; long jiffies;
u32 seqno; u32 seqno;
u32 tail; u32 tail;
} *requests; } *requests;
int num_requests;
} ring[I915_NUM_RINGS]; } ring[I915_NUM_RINGS];
struct drm_i915_error_buffer { struct drm_i915_error_buffer {
u32 size; u32 size;

View File

@ -235,51 +235,48 @@ static const char *hangcheck_action_to_str(enum intel_ring_hangcheck_action a)
static void i915_ring_error_state(struct drm_i915_error_state_buf *m, static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
struct drm_device *dev, struct drm_device *dev,
struct drm_i915_error_state *error, struct drm_i915_error_ring *ring)
unsigned ring)
{ {
BUG_ON(ring >= I915_NUM_RINGS); /* shut up confused gcc */ if (!ring->valid)
if (!error->ring[ring].valid)
return; return;
err_printf(m, "%s command stream:\n", ring_str(ring)); err_printf(m, " HEAD: 0x%08x\n", ring->head);
err_printf(m, " HEAD: 0x%08x\n", error->head[ring]); err_printf(m, " TAIL: 0x%08x\n", ring->tail);
err_printf(m, " TAIL: 0x%08x\n", error->tail[ring]); err_printf(m, " CTL: 0x%08x\n", ring->ctl);
err_printf(m, " CTL: 0x%08x\n", error->ctl[ring]); err_printf(m, " HWS: 0x%08x\n", ring->hws);
err_printf(m, " HWS: 0x%08x\n", error->hws[ring]); err_printf(m, " ACTHD: 0x%08x\n", ring->acthd);
err_printf(m, " ACTHD: 0x%08x\n", error->acthd[ring]); err_printf(m, " IPEIR: 0x%08x\n", ring->ipeir);
err_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]); err_printf(m, " IPEHR: 0x%08x\n", ring->ipehr);
err_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]); err_printf(m, " INSTDONE: 0x%08x\n", ring->instdone);
err_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]);
if (INTEL_INFO(dev)->gen >= 4) { if (INTEL_INFO(dev)->gen >= 4) {
err_printf(m, " BBADDR: 0x%08llx\n", error->bbaddr[ring]); err_printf(m, " BBADDR: 0x%08llx\n", ring->bbaddr);
err_printf(m, " BB_STATE: 0x%08x\n", error->bbstate[ring]); err_printf(m, " BB_STATE: 0x%08x\n", ring->bbstate);
err_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]); err_printf(m, " INSTPS: 0x%08x\n", ring->instps);
} }
err_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]); err_printf(m, " INSTPM: 0x%08x\n", ring->instpm);
err_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]); err_printf(m, " FADDR: 0x%08x\n", ring->faddr);
if (INTEL_INFO(dev)->gen >= 6) { if (INTEL_INFO(dev)->gen >= 6) {
err_printf(m, " RC PSMI: 0x%08x\n", error->rc_psmi[ring]); err_printf(m, " RC PSMI: 0x%08x\n", ring->rc_psmi);
err_printf(m, " FAULT_REG: 0x%08x\n", error->fault_reg[ring]); err_printf(m, " FAULT_REG: 0x%08x\n", ring->fault_reg);
err_printf(m, " SYNC_0: 0x%08x [last synced 0x%08x]\n", err_printf(m, " SYNC_0: 0x%08x [last synced 0x%08x]\n",
error->semaphore_mboxes[ring][0], ring->semaphore_mboxes[0],
error->semaphore_seqno[ring][0]); ring->semaphore_seqno[0]);
err_printf(m, " SYNC_1: 0x%08x [last synced 0x%08x]\n", err_printf(m, " SYNC_1: 0x%08x [last synced 0x%08x]\n",
error->semaphore_mboxes[ring][1], ring->semaphore_mboxes[1],
error->semaphore_seqno[ring][1]); ring->semaphore_seqno[1]);
if (HAS_VEBOX(dev)) { if (HAS_VEBOX(dev)) {
err_printf(m, " SYNC_2: 0x%08x [last synced 0x%08x]\n", err_printf(m, " SYNC_2: 0x%08x [last synced 0x%08x]\n",
error->semaphore_mboxes[ring][2], ring->semaphore_mboxes[2],
error->semaphore_seqno[ring][2]); ring->semaphore_seqno[2]);
} }
} }
err_printf(m, " seqno: 0x%08x\n", error->seqno[ring]); err_printf(m, " seqno: 0x%08x\n", ring->seqno);
err_printf(m, " waiting: %s\n", yesno(error->waiting[ring])); err_printf(m, " waiting: %s\n", yesno(ring->waiting));
err_printf(m, " ring->head: 0x%08x\n", error->cpu_ring_head[ring]); err_printf(m, " ring->head: 0x%08x\n", ring->cpu_ring_head);
err_printf(m, " ring->tail: 0x%08x\n", error->cpu_ring_tail[ring]); err_printf(m, " ring->tail: 0x%08x\n", ring->cpu_ring_tail);
err_printf(m, " hangcheck: %s [%d]\n", err_printf(m, " hangcheck: %s [%d]\n",
hangcheck_action_to_str(error->hangcheck_action[ring]), hangcheck_action_to_str(ring->hangcheck_action),
error->hangcheck_score[ring]); ring->hangcheck_score);
} }
void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...) void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...)
@ -331,8 +328,10 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
if (INTEL_INFO(dev)->gen == 7) if (INTEL_INFO(dev)->gen == 7)
err_printf(m, "ERR_INT: 0x%08x\n", error->err_int); err_printf(m, "ERR_INT: 0x%08x\n", error->err_int);
for (i = 0; i < ARRAY_SIZE(error->ring); i++) for (i = 0; i < ARRAY_SIZE(error->ring); i++) {
i915_ring_error_state(m, dev, error, i); err_printf(m, "%s command stream:\n", ring_str(i));
i915_ring_error_state(m, dev, &error->ring[i]);
}
if (error->active_bo) if (error->active_bo)
print_error_buffers(m, "Active", print_error_buffers(m, "Active",
@ -388,7 +387,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
} }
} }
if ((obj = error->ring[i].hws)) { if ((obj = error->ring[i].hws_page)) {
err_printf(m, "%s --- HW Status = 0x%08x\n", err_printf(m, "%s --- HW Status = 0x%08x\n",
dev_priv->ring[i].name, dev_priv->ring[i].name,
obj->gtt_offset); obj->gtt_offset);
@ -486,7 +485,7 @@ static void i915_error_state_free(struct kref *error_ref)
for (i = 0; i < ARRAY_SIZE(error->ring); i++) { for (i = 0; i < ARRAY_SIZE(error->ring); i++) {
i915_error_object_free(error->ring[i].batchbuffer); i915_error_object_free(error->ring[i].batchbuffer);
i915_error_object_free(error->ring[i].ringbuffer); i915_error_object_free(error->ring[i].ringbuffer);
i915_error_object_free(error->ring[i].hws); i915_error_object_free(error->ring[i].hws_page);
i915_error_object_free(error->ring[i].ctx); i915_error_object_free(error->ring[i].ctx);
kfree(error->ring[i].requests); kfree(error->ring[i].requests);
} }
@ -755,52 +754,52 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv,
} }
static void i915_record_ring_state(struct drm_device *dev, static void i915_record_ring_state(struct drm_device *dev,
struct drm_i915_error_state *error, struct intel_ring_buffer *ring,
struct intel_ring_buffer *ring) struct drm_i915_error_ring *ering)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
if (INTEL_INFO(dev)->gen >= 6) { if (INTEL_INFO(dev)->gen >= 6) {
error->rc_psmi[ring->id] = I915_READ(ring->mmio_base + 0x50); ering->rc_psmi = I915_READ(ring->mmio_base + 0x50);
error->fault_reg[ring->id] = I915_READ(RING_FAULT_REG(ring)); ering->fault_reg = I915_READ(RING_FAULT_REG(ring));
error->semaphore_mboxes[ring->id][0] ering->semaphore_mboxes[0]
= I915_READ(RING_SYNC_0(ring->mmio_base)); = I915_READ(RING_SYNC_0(ring->mmio_base));
error->semaphore_mboxes[ring->id][1] ering->semaphore_mboxes[1]
= I915_READ(RING_SYNC_1(ring->mmio_base)); = I915_READ(RING_SYNC_1(ring->mmio_base));
error->semaphore_seqno[ring->id][0] = ring->sync_seqno[0]; ering->semaphore_seqno[0] = ring->sync_seqno[0];
error->semaphore_seqno[ring->id][1] = ring->sync_seqno[1]; ering->semaphore_seqno[1] = ring->sync_seqno[1];
} }
if (HAS_VEBOX(dev)) { if (HAS_VEBOX(dev)) {
error->semaphore_mboxes[ring->id][2] = ering->semaphore_mboxes[2] =
I915_READ(RING_SYNC_2(ring->mmio_base)); I915_READ(RING_SYNC_2(ring->mmio_base));
error->semaphore_seqno[ring->id][2] = ring->sync_seqno[2]; ering->semaphore_seqno[2] = ring->sync_seqno[2];
} }
if (INTEL_INFO(dev)->gen >= 4) { if (INTEL_INFO(dev)->gen >= 4) {
error->faddr[ring->id] = I915_READ(RING_DMA_FADD(ring->mmio_base)); ering->faddr = I915_READ(RING_DMA_FADD(ring->mmio_base));
error->ipeir[ring->id] = I915_READ(RING_IPEIR(ring->mmio_base)); ering->ipeir = I915_READ(RING_IPEIR(ring->mmio_base));
error->ipehr[ring->id] = I915_READ(RING_IPEHR(ring->mmio_base)); ering->ipehr = I915_READ(RING_IPEHR(ring->mmio_base));
error->instdone[ring->id] = I915_READ(RING_INSTDONE(ring->mmio_base)); ering->instdone = I915_READ(RING_INSTDONE(ring->mmio_base));
error->instps[ring->id] = I915_READ(RING_INSTPS(ring->mmio_base)); ering->instps = I915_READ(RING_INSTPS(ring->mmio_base));
error->bbaddr[ring->id] = I915_READ(RING_BBADDR(ring->mmio_base)); ering->bbaddr = I915_READ(RING_BBADDR(ring->mmio_base));
if (INTEL_INFO(dev)->gen >= 8) if (INTEL_INFO(dev)->gen >= 8)
error->bbaddr[ring->id] |= (u64) I915_READ(RING_BBADDR_UDW(ring->mmio_base)) << 32; ering->bbaddr |= (u64) I915_READ(RING_BBADDR_UDW(ring->mmio_base)) << 32;
error->bbstate[ring->id] = I915_READ(RING_BBSTATE(ring->mmio_base)); ering->bbstate = I915_READ(RING_BBSTATE(ring->mmio_base));
} else { } else {
error->faddr[ring->id] = I915_READ(DMA_FADD_I8XX); ering->faddr = I915_READ(DMA_FADD_I8XX);
error->ipeir[ring->id] = I915_READ(IPEIR); ering->ipeir = I915_READ(IPEIR);
error->ipehr[ring->id] = I915_READ(IPEHR); ering->ipehr = I915_READ(IPEHR);
error->instdone[ring->id] = I915_READ(INSTDONE); ering->instdone = I915_READ(INSTDONE);
} }
error->waiting[ring->id] = waitqueue_active(&ring->irq_queue); ering->waiting = waitqueue_active(&ring->irq_queue);
error->instpm[ring->id] = I915_READ(RING_INSTPM(ring->mmio_base)); ering->instpm = I915_READ(RING_INSTPM(ring->mmio_base));
error->seqno[ring->id] = ring->get_seqno(ring, false); ering->seqno = ring->get_seqno(ring, false);
error->acthd[ring->id] = intel_ring_get_active_head(ring); ering->acthd = intel_ring_get_active_head(ring);
error->head[ring->id] = I915_READ_HEAD(ring); ering->head = I915_READ_HEAD(ring);
error->tail[ring->id] = I915_READ_TAIL(ring); ering->tail = I915_READ_TAIL(ring);
error->ctl[ring->id] = I915_READ_CTL(ring); ering->ctl = I915_READ_CTL(ring);
if (I915_NEED_GFX_HWS(dev)) { if (I915_NEED_GFX_HWS(dev)) {
int mmio; int mmio;
@ -828,14 +827,14 @@ static void i915_record_ring_state(struct drm_device *dev,
mmio = RING_HWS_PGA(ring->mmio_base); mmio = RING_HWS_PGA(ring->mmio_base);
} }
error->hws[ring->id] = I915_READ(mmio); ering->hws = I915_READ(mmio);
} }
error->cpu_ring_head[ring->id] = ring->head; ering->cpu_ring_head = ring->head;
error->cpu_ring_tail[ring->id] = ring->tail; ering->cpu_ring_tail = ring->tail;
error->hangcheck_score[ring->id] = ring->hangcheck.score; ering->hangcheck_score = ring->hangcheck.score;
error->hangcheck_action[ring->id] = ring->hangcheck.action; ering->hangcheck_action = ring->hangcheck.action;
} }
@ -876,7 +875,7 @@ static void i915_gem_record_rings(struct drm_device *dev,
error->ring[i].valid = true; error->ring[i].valid = true;
i915_record_ring_state(dev, error, ring); i915_record_ring_state(dev, ring, &error->ring[i]);
error->ring[i].batchbuffer = error->ring[i].batchbuffer =
i915_error_first_batchbuffer(dev_priv, ring); i915_error_first_batchbuffer(dev_priv, ring);
@ -885,7 +884,7 @@ static void i915_gem_record_rings(struct drm_device *dev,
i915_error_ggtt_object_create(dev_priv, ring->obj); i915_error_ggtt_object_create(dev_priv, ring->obj);
if (ring->status_page.obj) if (ring->status_page.obj)
error->ring[i].hws = error->ring[i].hws_page =
i915_error_ggtt_object_create(dev_priv, ring->status_page.obj); i915_error_ggtt_object_create(dev_priv, ring->status_page.obj);
i915_gem_record_active_context(ring, error, &error->ring[i]); i915_gem_record_active_context(ring, error, &error->ring[i]);