Rev 4126 | Rev 5060 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4126 | Rev 4560 | ||
---|---|---|---|
Line 213... | Line 213... | ||
213 | err_puts(m, "\n"); |
213 | err_puts(m, "\n"); |
214 | err++; |
214 | err++; |
215 | } |
215 | } |
216 | } |
216 | } |
Line -... | Line 217... | ||
- | 217 | ||
- | 218 | static const char *hangcheck_action_to_str(enum intel_ring_hangcheck_action a) |
|
- | 219 | { |
|
- | 220 | switch (a) { |
|
- | 221 | case HANGCHECK_IDLE: |
|
- | 222 | return "idle"; |
|
- | 223 | case HANGCHECK_WAIT: |
|
- | 224 | return "wait"; |
|
- | 225 | case HANGCHECK_ACTIVE: |
|
- | 226 | return "active"; |
|
- | 227 | case HANGCHECK_KICK: |
|
- | 228 | return "kick"; |
|
- | 229 | case HANGCHECK_HUNG: |
|
- | 230 | return "hung"; |
|
- | 231 | } |
|
- | 232 | ||
- | 233 | return "unknown"; |
|
- | 234 | } |
|
217 | 235 | ||
218 | static void i915_ring_error_state(struct drm_i915_error_state_buf *m, |
236 | static void i915_ring_error_state(struct drm_i915_error_state_buf *m, |
219 | struct drm_device *dev, |
237 | struct drm_device *dev, |
220 | struct drm_i915_error_state *error, |
238 | struct drm_i915_error_state *error, |
221 | unsigned ring) |
239 | unsigned ring) |
222 | { |
240 | { |
- | 241 | BUG_ON(ring >= I915_NUM_RINGS); /* shut up confused gcc */ |
|
- | 242 | if (!error->ring[ring].valid) |
|
- | 243 | return; |
|
223 | BUG_ON(ring >= I915_NUM_RINGS); /* shut up confused gcc */ |
244 | |
224 | err_printf(m, "%s command stream:\n", ring_str(ring)); |
245 | err_printf(m, "%s command stream:\n", ring_str(ring)); |
225 | err_printf(m, " HEAD: 0x%08x\n", error->head[ring]); |
246 | err_printf(m, " HEAD: 0x%08x\n", error->head[ring]); |
226 | err_printf(m, " TAIL: 0x%08x\n", error->tail[ring]); |
247 | err_printf(m, " TAIL: 0x%08x\n", error->tail[ring]); |
227 | err_printf(m, " CTL: 0x%08x\n", error->ctl[ring]); |
248 | err_printf(m, " CTL: 0x%08x\n", error->ctl[ring]); |
228 | err_printf(m, " ACTHD: 0x%08x\n", error->acthd[ring]); |
249 | err_printf(m, " ACTHD: 0x%08x\n", error->acthd[ring]); |
229 | err_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]); |
250 | err_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]); |
230 | err_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]); |
251 | err_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]); |
231 | err_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]); |
252 | err_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]); |
232 | if (ring == RCS && INTEL_INFO(dev)->gen >= 4) |
253 | if (INTEL_INFO(dev)->gen >= 4) { |
233 | err_printf(m, " BBADDR: 0x%08llx\n", error->bbaddr); |
- | |
234 | 254 | err_printf(m, " BBADDR: 0x%08llx\n", error->bbaddr[ring]); |
|
235 | if (INTEL_INFO(dev)->gen >= 4) |
255 | err_printf(m, " BB_STATE: 0x%08x\n", error->bbstate[ring]); |
- | 256 | err_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]); |
|
236 | err_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]); |
257 | } |
237 | err_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]); |
258 | err_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]); |
238 | err_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]); |
259 | err_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]); |
239 | if (INTEL_INFO(dev)->gen >= 6) { |
260 | if (INTEL_INFO(dev)->gen >= 6) { |
240 | err_printf(m, " RC PSMI: 0x%08x\n", error->rc_psmi[ring]); |
261 | err_printf(m, " RC PSMI: 0x%08x\n", error->rc_psmi[ring]); |
Line 253... | Line 274... | ||
253 | } |
274 | } |
254 | err_printf(m, " seqno: 0x%08x\n", error->seqno[ring]); |
275 | err_printf(m, " seqno: 0x%08x\n", error->seqno[ring]); |
255 | err_printf(m, " waiting: %s\n", yesno(error->waiting[ring])); |
276 | err_printf(m, " waiting: %s\n", yesno(error->waiting[ring])); |
256 | err_printf(m, " ring->head: 0x%08x\n", error->cpu_ring_head[ring]); |
277 | err_printf(m, " ring->head: 0x%08x\n", error->cpu_ring_head[ring]); |
257 | err_printf(m, " ring->tail: 0x%08x\n", error->cpu_ring_tail[ring]); |
278 | err_printf(m, " ring->tail: 0x%08x\n", error->cpu_ring_tail[ring]); |
- | 279 | err_printf(m, " hangcheck: %s [%d]\n", |
|
- | 280 | hangcheck_action_to_str(error->hangcheck_action[ring]), |
|
- | 281 | error->hangcheck_score[ring]); |
|
258 | } |
282 | } |
Line 259... | Line 283... | ||
259 | 283 | ||
260 | void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...) |
284 | void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...) |
261 | { |
285 | { |
Line 270... | Line 294... | ||
270 | const struct i915_error_state_file_priv *error_priv) |
294 | const struct i915_error_state_file_priv *error_priv) |
271 | { |
295 | { |
272 | struct drm_device *dev = error_priv->dev; |
296 | struct drm_device *dev = error_priv->dev; |
273 | drm_i915_private_t *dev_priv = dev->dev_private; |
297 | drm_i915_private_t *dev_priv = dev->dev_private; |
274 | struct drm_i915_error_state *error = error_priv->error; |
298 | struct drm_i915_error_state *error = error_priv->error; |
275 | struct intel_ring_buffer *ring; |
- | |
276 | int i, j, page, offset, elt; |
299 | int i, j, page, offset, elt; |
Line 277... | Line 300... | ||
277 | 300 | ||
278 | if (!error) { |
301 | if (!error) { |
279 | err_printf(m, "no error state collected\n"); |
302 | err_printf(m, "no error state collected\n"); |
280 | goto out; |
303 | goto out; |
Line 281... | Line 304... | ||
281 | } |
304 | } |
282 | 305 | ||
283 | err_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, |
306 | err_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, |
284 | error->time.tv_usec); |
307 | error->time.tv_usec); |
285 | err_printf(m, "Kernel: " UTS_RELEASE "\n"); |
308 | err_printf(m, "Kernel: " UTS_RELEASE "\n"); |
286 | err_printf(m, "PCI ID: 0x%04x\n", dev->pci_device); |
309 | err_printf(m, "PCI ID: 0x%04x\n", dev->pdev->device); |
287 | err_printf(m, "EIR: 0x%08x\n", error->eir); |
310 | err_printf(m, "EIR: 0x%08x\n", error->eir); |
288 | err_printf(m, "IER: 0x%08x\n", error->ier); |
311 | err_printf(m, "IER: 0x%08x\n", error->ier); |
289 | err_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); |
312 | err_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); |
290 | err_printf(m, "FORCEWAKE: 0x%08x\n", error->forcewake); |
313 | err_printf(m, "FORCEWAKE: 0x%08x\n", error->forcewake); |
- | 314 | err_printf(m, "DERRMR: 0x%08x\n", error->derrmr); |
|
Line 291... | Line 315... | ||
291 | err_printf(m, "DERRMR: 0x%08x\n", error->derrmr); |
315 | err_printf(m, "CCID: 0x%08x\n", error->ccid); |
292 | err_printf(m, "CCID: 0x%08x\n", error->ccid); |
316 | err_printf(m, "Missed interrupts: 0x%08lx\n", dev_priv->gpu_error.missed_irq_rings); |
Line 293... | Line 317... | ||
293 | 317 | ||
Line 304... | Line 328... | ||
304 | } |
328 | } |
Line 305... | Line 329... | ||
305 | 329 | ||
306 | if (INTEL_INFO(dev)->gen == 7) |
330 | if (INTEL_INFO(dev)->gen == 7) |
Line 307... | Line 331... | ||
307 | err_printf(m, "ERR_INT: 0x%08x\n", error->err_int); |
331 | err_printf(m, "ERR_INT: 0x%08x\n", error->err_int); |
308 | 332 | ||
Line 309... | Line 333... | ||
309 | for_each_ring(ring, dev_priv, i) |
333 | for (i = 0; i < ARRAY_SIZE(error->ring); i++) |
310 | i915_ring_error_state(m, dev, error, i); |
334 | i915_ring_error_state(m, dev, error, i); |
311 | 335 | ||
Line 361... | Line 385... | ||
361 | offset += 4; |
385 | offset += 4; |
362 | } |
386 | } |
363 | } |
387 | } |
364 | } |
388 | } |
Line 365... | Line 389... | ||
365 | 389 | ||
366 | obj = error->ring[i].ctx; |
- | |
367 | if (obj) { |
390 | if ((obj = error->ring[i].ctx)) { |
368 | err_printf(m, "%s --- HW Context = 0x%08x\n", |
391 | err_printf(m, "%s --- HW Context = 0x%08x\n", |
369 | dev_priv->ring[i].name, |
392 | dev_priv->ring[i].name, |
370 | obj->gtt_offset); |
393 | obj->gtt_offset); |
371 | offset = 0; |
394 | offset = 0; |
Line 599... | Line 622... | ||
599 | struct drm_i915_private *dev_priv = dev->dev_private; |
622 | struct drm_i915_private *dev_priv = dev->dev_private; |
600 | int i; |
623 | int i; |
Line 601... | Line 624... | ||
601 | 624 | ||
602 | /* Fences */ |
625 | /* Fences */ |
- | 626 | switch (INTEL_INFO(dev)->gen) { |
|
603 | switch (INTEL_INFO(dev)->gen) { |
627 | case 8: |
604 | case 7: |
628 | case 7: |
605 | case 6: |
629 | case 6: |
606 | for (i = 0; i < dev_priv->num_fence_regs; i++) |
630 | for (i = 0; i < dev_priv->num_fence_regs; i++) |
607 | error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); |
631 | error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); |
Line 642... | Line 666... | ||
642 | 666 | ||
643 | if (WARN_ON(ring->id != RCS)) |
667 | if (WARN_ON(ring->id != RCS)) |
Line 644... | Line 668... | ||
644 | return NULL; |
668 | return NULL; |
- | 669 | ||
645 | 670 | obj = ring->scratch.obj; |
|
646 | obj = ring->scratch.obj; |
671 | if (obj != NULL && |
647 | if (acthd >= i915_gem_obj_ggtt_offset(obj) && |
672 | acthd >= i915_gem_obj_ggtt_offset(obj) && |
648 | acthd < i915_gem_obj_ggtt_offset(obj) + obj->base.size) |
673 | acthd < i915_gem_obj_ggtt_offset(obj) + obj->base.size) |
Line 649... | Line 674... | ||
649 | return i915_error_object_create(dev_priv, obj); |
674 | return i915_error_object_create(dev_priv, obj); |
Line 699... | Line 724... | ||
699 | error->faddr[ring->id] = I915_READ(RING_DMA_FADD(ring->mmio_base)); |
724 | error->faddr[ring->id] = I915_READ(RING_DMA_FADD(ring->mmio_base)); |
700 | error->ipeir[ring->id] = I915_READ(RING_IPEIR(ring->mmio_base)); |
725 | error->ipeir[ring->id] = I915_READ(RING_IPEIR(ring->mmio_base)); |
701 | error->ipehr[ring->id] = I915_READ(RING_IPEHR(ring->mmio_base)); |
726 | error->ipehr[ring->id] = I915_READ(RING_IPEHR(ring->mmio_base)); |
702 | error->instdone[ring->id] = I915_READ(RING_INSTDONE(ring->mmio_base)); |
727 | error->instdone[ring->id] = I915_READ(RING_INSTDONE(ring->mmio_base)); |
703 | error->instps[ring->id] = I915_READ(RING_INSTPS(ring->mmio_base)); |
728 | error->instps[ring->id] = I915_READ(RING_INSTPS(ring->mmio_base)); |
- | 729 | error->bbaddr[ring->id] = I915_READ(RING_BBADDR(ring->mmio_base)); |
|
704 | if (ring->id == RCS) |
730 | if (INTEL_INFO(dev)->gen >= 8) |
- | 731 | error->bbaddr[ring->id] |= (u64) I915_READ(RING_BBADDR_UDW(ring->mmio_base)) << 32; |
|
705 | error->bbaddr = I915_READ64(BB_ADDR); |
732 | error->bbstate[ring->id] = I915_READ(RING_BBSTATE(ring->mmio_base)); |
706 | } else { |
733 | } else { |
707 | error->faddr[ring->id] = I915_READ(DMA_FADD_I8XX); |
734 | error->faddr[ring->id] = I915_READ(DMA_FADD_I8XX); |
708 | error->ipeir[ring->id] = I915_READ(IPEIR); |
735 | error->ipeir[ring->id] = I915_READ(IPEIR); |
709 | error->ipehr[ring->id] = I915_READ(IPEHR); |
736 | error->ipehr[ring->id] = I915_READ(IPEHR); |
710 | error->instdone[ring->id] = I915_READ(INSTDONE); |
737 | error->instdone[ring->id] = I915_READ(INSTDONE); |
Line 718... | Line 745... | ||
718 | error->tail[ring->id] = I915_READ_TAIL(ring); |
745 | error->tail[ring->id] = I915_READ_TAIL(ring); |
719 | error->ctl[ring->id] = I915_READ_CTL(ring); |
746 | error->ctl[ring->id] = I915_READ_CTL(ring); |
Line 720... | Line 747... | ||
720 | 747 | ||
721 | error->cpu_ring_head[ring->id] = ring->head; |
748 | error->cpu_ring_head[ring->id] = ring->head; |
- | 749 | error->cpu_ring_tail[ring->id] = ring->tail; |
|
- | 750 | ||
- | 751 | error->hangcheck_score[ring->id] = ring->hangcheck.score; |
|
722 | error->cpu_ring_tail[ring->id] = ring->tail; |
752 | error->hangcheck_action[ring->id] = ring->hangcheck.action; |
Line 723... | Line 753... | ||
723 | } |
753 | } |
724 | 754 | ||
Line 745... | Line 775... | ||
745 | 775 | ||
746 | static void i915_gem_record_rings(struct drm_device *dev, |
776 | static void i915_gem_record_rings(struct drm_device *dev, |
747 | struct drm_i915_error_state *error) |
777 | struct drm_i915_error_state *error) |
748 | { |
778 | { |
749 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
750 | struct intel_ring_buffer *ring; |
779 | struct drm_i915_private *dev_priv = dev->dev_private; |
751 | struct drm_i915_gem_request *request; |
780 | struct drm_i915_gem_request *request; |
Line -... | Line 781... | ||
- | 781 | int i, count; |
|
752 | int i, count; |
782 | |
- | 783 | for (i = 0; i < I915_NUM_RINGS; i++) { |
|
- | 784 | struct intel_ring_buffer *ring = &dev_priv->ring[i]; |
|
- | 785 | ||
- | 786 | if (ring->dev == NULL) |
|
- | 787 | continue; |
|
- | 788 | ||
753 | 789 | error->ring[i].valid = true; |
|
Line 754... | Line 790... | ||
754 | for_each_ring(ring, dev_priv, i) { |
790 | |
755 | i915_record_ring_state(dev, error, ring); |
791 | i915_record_ring_state(dev, error, ring); |
Line 767... | Line 803... | ||
767 | list_for_each_entry(request, &ring->request_list, list) |
803 | list_for_each_entry(request, &ring->request_list, list) |
768 | count++; |
804 | count++; |
Line 769... | Line 805... | ||
769 | 805 | ||
770 | error->ring[i].num_requests = count; |
806 | error->ring[i].num_requests = count; |
771 | error->ring[i].requests = |
807 | error->ring[i].requests = |
772 | kmalloc(count*sizeof(struct drm_i915_error_request), |
808 | kcalloc(count, sizeof(*error->ring[i].requests), |
773 | GFP_ATOMIC); |
809 | GFP_ATOMIC); |
774 | if (error->ring[i].requests == NULL) { |
810 | if (error->ring[i].requests == NULL) { |
775 | error->ring[i].num_requests = 0; |
811 | error->ring[i].num_requests = 0; |
776 | continue; |
812 | continue; |
Line 809... | Line 845... | ||
809 | if (obj->pin_count) |
845 | if (obj->pin_count) |
810 | i++; |
846 | i++; |
811 | error->pinned_bo_count[ndx] = i - error->active_bo_count[ndx]; |
847 | error->pinned_bo_count[ndx] = i - error->active_bo_count[ndx]; |
Line 812... | Line 848... | ||
812 | 848 | ||
813 | if (i) { |
849 | if (i) { |
814 | active_bo = kmalloc(sizeof(*active_bo)*i, GFP_ATOMIC); |
850 | active_bo = kcalloc(i, sizeof(*active_bo), GFP_ATOMIC); |
815 | if (active_bo) |
851 | if (active_bo) |
816 | pinned_bo = active_bo + error->active_bo_count[ndx]; |
852 | pinned_bo = active_bo + error->active_bo_count[ndx]; |
Line 817... | Line 853... | ||
817 | } |
853 | } |
Line 883... | Line 919... | ||
883 | if (!error) { |
919 | if (!error) { |
884 | DRM_DEBUG_DRIVER("out of memory, not capturing error state\n"); |
920 | DRM_DEBUG_DRIVER("out of memory, not capturing error state\n"); |
885 | return; |
921 | return; |
886 | } |
922 | } |
Line 887... | Line 923... | ||
887 | 923 | ||
888 | DRM_INFO("capturing error event; look for more information in " |
924 | DRM_INFO("GPU crash dump saved to /sys/class/drm/card%d/error\n", |
- | 925 | dev->primary->index); |
|
- | 926 | DRM_INFO("GPU hangs can indicate a bug anywhere in the entire gfx stack, including userspace.\n"); |
|
- | 927 | DRM_INFO("Please file a _new_ bug report on bugs.freedesktop.org against DRI -> DRM/Intel\n"); |
|
- | 928 | DRM_INFO("drm/i915 developers can then reassign to the right component if it's not a kernel issue.\n"); |
|
Line 889... | Line 929... | ||
889 | "/sys/class/drm/card%d/error\n", dev->primary->index); |
929 | DRM_INFO("The gpu crash dump is required to analyze gpu hangs, so please always attach it.\n"); |
890 | 930 | ||
891 | kref_init(&error->ref); |
931 | kref_init(&error->ref); |
892 | error->eir = I915_READ(EIR); |
932 | error->eir = I915_READ(EIR); |
Line 986... | Line 1026... | ||
986 | { |
1026 | { |
987 | switch (type) { |
1027 | switch (type) { |
988 | case I915_CACHE_NONE: return " uncached"; |
1028 | case I915_CACHE_NONE: return " uncached"; |
989 | case I915_CACHE_LLC: return " snooped or LLC"; |
1029 | case I915_CACHE_LLC: return " snooped or LLC"; |
990 | case I915_CACHE_L3_LLC: return " L3+LLC"; |
1030 | case I915_CACHE_L3_LLC: return " L3+LLC"; |
- | 1031 | case I915_CACHE_WT: return " WT"; |
|
991 | default: return ""; |
1032 | default: return ""; |
992 | } |
1033 | } |
993 | } |
1034 | } |
994 | #endif |
1035 | #endif |
Line 1011... | Line 1052... | ||
1011 | instdone[1] = I915_READ(INSTDONE1); |
1052 | instdone[1] = I915_READ(INSTDONE1); |
1012 | break; |
1053 | break; |
1013 | default: |
1054 | default: |
1014 | WARN_ONCE(1, "Unsupported platform\n"); |
1055 | WARN_ONCE(1, "Unsupported platform\n"); |
1015 | case 7: |
1056 | case 7: |
- | 1057 | case 8: |
|
1016 | instdone[0] = I915_READ(GEN7_INSTDONE_1); |
1058 | instdone[0] = I915_READ(GEN7_INSTDONE_1); |
1017 | instdone[1] = I915_READ(GEN7_SC_INSTDONE); |
1059 | instdone[1] = I915_READ(GEN7_SC_INSTDONE); |
1018 | instdone[2] = I915_READ(GEN7_SAMPLER_INSTDONE); |
1060 | instdone[2] = I915_READ(GEN7_SAMPLER_INSTDONE); |
1019 | instdone[3] = I915_READ(GEN7_ROW_INSTDONE); |
1061 | instdone[3] = I915_READ(GEN7_ROW_INSTDONE); |
1020 | break; |
1062 | break; |