215,24 → 215,6 |
} |
} |
|
static const char *hangcheck_action_to_str(enum intel_ring_hangcheck_action a) |
{ |
switch (a) { |
case HANGCHECK_IDLE: |
return "idle"; |
case HANGCHECK_WAIT: |
return "wait"; |
case HANGCHECK_ACTIVE: |
return "active"; |
case HANGCHECK_KICK: |
return "kick"; |
case HANGCHECK_HUNG: |
return "hung"; |
} |
|
return "unknown"; |
} |
|
static void i915_ring_error_state(struct drm_i915_error_state_buf *m, |
struct drm_device *dev, |
struct drm_i915_error_state *error, |
239,9 → 221,6 |
unsigned ring) |
{ |
BUG_ON(ring >= I915_NUM_RINGS); /* shut up confused gcc */ |
if (!error->ring[ring].valid) |
return; |
|
err_printf(m, "%s command stream:\n", ring_str(ring)); |
err_printf(m, " HEAD: 0x%08x\n", error->head[ring]); |
err_printf(m, " TAIL: 0x%08x\n", error->tail[ring]); |
250,11 → 229,11 |
err_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]); |
err_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]); |
err_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]); |
if (INTEL_INFO(dev)->gen >= 4) { |
err_printf(m, " BBADDR: 0x%08llx\n", error->bbaddr[ring]); |
err_printf(m, " BB_STATE: 0x%08x\n", error->bbstate[ring]); |
if (ring == RCS && INTEL_INFO(dev)->gen >= 4) |
err_printf(m, " BBADDR: 0x%08llx\n", error->bbaddr); |
|
if (INTEL_INFO(dev)->gen >= 4) |
err_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]); |
} |
err_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]); |
err_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]); |
if (INTEL_INFO(dev)->gen >= 6) { |
276,9 → 255,6 |
err_printf(m, " waiting: %s\n", yesno(error->waiting[ring])); |
err_printf(m, " ring->head: 0x%08x\n", error->cpu_ring_head[ring]); |
err_printf(m, " ring->tail: 0x%08x\n", error->cpu_ring_tail[ring]); |
err_printf(m, " hangcheck: %s [%d]\n", |
hangcheck_action_to_str(error->hangcheck_action[ring]), |
error->hangcheck_score[ring]); |
} |
|
void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...) |
296,6 → 272,7 |
struct drm_device *dev = error_priv->dev; |
drm_i915_private_t *dev_priv = dev->dev_private; |
struct drm_i915_error_state *error = error_priv->error; |
struct intel_ring_buffer *ring; |
int i, j, page, offset, elt; |
|
if (!error) { |
306,7 → 283,7 |
err_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, |
error->time.tv_usec); |
err_printf(m, "Kernel: " UTS_RELEASE "\n"); |
err_printf(m, "PCI ID: 0x%04x\n", dev->pdev->device); |
err_printf(m, "PCI ID: 0x%04x\n", dev->pci_device); |
err_printf(m, "EIR: 0x%08x\n", error->eir); |
err_printf(m, "IER: 0x%08x\n", error->ier); |
err_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); |
313,7 → 290,6 |
err_printf(m, "FORCEWAKE: 0x%08x\n", error->forcewake); |
err_printf(m, "DERRMR: 0x%08x\n", error->derrmr); |
err_printf(m, "CCID: 0x%08x\n", error->ccid); |
err_printf(m, "Missed interrupts: 0x%08lx\n", dev_priv->gpu_error.missed_irq_rings); |
|
for (i = 0; i < dev_priv->num_fence_regs; i++) |
err_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]); |
330,7 → 306,7 |
if (INTEL_INFO(dev)->gen == 7) |
err_printf(m, "ERR_INT: 0x%08x\n", error->err_int); |
|
for (i = 0; i < ARRAY_SIZE(error->ring); i++) |
for_each_ring(ring, dev_priv, i) |
i915_ring_error_state(m, dev, error, i); |
|
if (error->active_bo) |
387,7 → 363,8 |
} |
} |
|
if ((obj = error->ring[i].ctx)) { |
obj = error->ring[i].ctx; |
if (obj) { |
err_printf(m, "%s --- HW Context = 0x%08x\n", |
dev_priv->ring[i].name, |
obj->gtt_offset); |
624,7 → 601,6 |
|
/* Fences */ |
switch (INTEL_INFO(dev)->gen) { |
case 8: |
case 7: |
case 6: |
for (i = 0; i < dev_priv->num_fence_regs; i++) |
668,8 → 644,7 |
return NULL; |
|
obj = ring->scratch.obj; |
if (obj != NULL && |
acthd >= i915_gem_obj_ggtt_offset(obj) && |
if (acthd >= i915_gem_obj_ggtt_offset(obj) && |
acthd < i915_gem_obj_ggtt_offset(obj) + obj->base.size) |
return i915_error_object_create(dev_priv, obj); |
} |
726,10 → 701,8 |
error->ipehr[ring->id] = I915_READ(RING_IPEHR(ring->mmio_base)); |
error->instdone[ring->id] = I915_READ(RING_INSTDONE(ring->mmio_base)); |
error->instps[ring->id] = I915_READ(RING_INSTPS(ring->mmio_base)); |
error->bbaddr[ring->id] = I915_READ(RING_BBADDR(ring->mmio_base)); |
if (INTEL_INFO(dev)->gen >= 8) |
error->bbaddr[ring->id] |= (u64) I915_READ(RING_BBADDR_UDW(ring->mmio_base)) << 32; |
error->bbstate[ring->id] = I915_READ(RING_BBSTATE(ring->mmio_base)); |
if (ring->id == RCS) |
error->bbaddr = I915_READ64(BB_ADDR); |
} else { |
error->faddr[ring->id] = I915_READ(DMA_FADD_I8XX); |
error->ipeir[ring->id] = I915_READ(IPEIR); |
747,9 → 720,6 |
|
error->cpu_ring_head[ring->id] = ring->head; |
error->cpu_ring_tail[ring->id] = ring->tail; |
|
error->hangcheck_score[ring->id] = ring->hangcheck.score; |
error->hangcheck_action[ring->id] = ring->hangcheck.action; |
} |
|
|
777,17 → 747,11 |
struct drm_i915_error_state *error) |
{ |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct intel_ring_buffer *ring; |
struct drm_i915_gem_request *request; |
int i, count; |
|
for (i = 0; i < I915_NUM_RINGS; i++) { |
struct intel_ring_buffer *ring = &dev_priv->ring[i]; |
|
if (ring->dev == NULL) |
continue; |
|
error->ring[i].valid = true; |
|
for_each_ring(ring, dev_priv, i) { |
i915_record_ring_state(dev, error, ring); |
|
error->ring[i].batchbuffer = |
805,7 → 769,7 |
|
error->ring[i].num_requests = count; |
error->ring[i].requests = |
kcalloc(count, sizeof(*error->ring[i].requests), |
kmalloc(count*sizeof(struct drm_i915_error_request), |
GFP_ATOMIC); |
if (error->ring[i].requests == NULL) { |
error->ring[i].num_requests = 0; |
847,7 → 811,7 |
error->pinned_bo_count[ndx] = i - error->active_bo_count[ndx]; |
|
if (i) { |
active_bo = kcalloc(i, sizeof(*active_bo), GFP_ATOMIC); |
active_bo = kmalloc(sizeof(*active_bo)*i, GFP_ATOMIC); |
if (active_bo) |
pinned_bo = active_bo + error->active_bo_count[ndx]; |
} |
921,12 → 885,8 |
return; |
} |
|
DRM_INFO("GPU crash dump saved to /sys/class/drm/card%d/error\n", |
dev->primary->index); |
DRM_INFO("GPU hangs can indicate a bug anywhere in the entire gfx stack, including userspace.\n"); |
DRM_INFO("Please file a _new_ bug report on bugs.freedesktop.org against DRI -> DRM/Intel\n"); |
DRM_INFO("drm/i915 developers can then reassign to the right component if it's not a kernel issue.\n"); |
DRM_INFO("The gpu crash dump is required to analyze gpu hangs, so please always attach it.\n"); |
DRM_INFO("capturing error event; look for more information in " |
"/sys/class/drm/card%d/error\n", dev->primary->index); |
|
kref_init(&error->ref); |
error->eir = I915_READ(EIR); |
1028,7 → 988,6 |
case I915_CACHE_NONE: return " uncached"; |
case I915_CACHE_LLC: return " snooped or LLC"; |
case I915_CACHE_L3_LLC: return " L3+LLC"; |
case I915_CACHE_WT: return " WT"; |
default: return ""; |
} |
} |
1054,7 → 1013,6 |
default: |
WARN_ONCE(1, "Unsupported platform\n"); |
case 7: |
case 8: |
instdone[0] = I915_READ(GEN7_INSTDONE_1); |
instdone[1] = I915_READ(GEN7_SC_INSTDONE); |
instdone[2] = I915_READ(GEN7_SAMPLER_INSTDONE); |