aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-11-22 03:07:02 -0500
committerChris Wilson <chris@chris-wilson.co.uk>2010-11-22 03:07:02 -0500
commitc724e8a9407683a8a2ee8eb00b972badf237bbe1 (patch)
treeaf28081e274dd5982ed956a988542f7d840ef966
parent3143a2bf18d12545f77dafa5b9f7fee83b001223 (diff)
drm/i915: Capture pinned buffers on error
The pinned buffers are useful for diagnosing errors in setting up state for the chipset, which may not necessarily be 'active' at the time of the error, e.g. the cursor buffer object. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c63
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h4
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c87
3 files changed, 98 insertions, 56 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 4c8fae9baaad..24a88ac63212 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -609,6 +609,36 @@ static const char *purgeable_flag(int purgeable)
609 return purgeable ? " purgeable" : ""; 609 return purgeable ? " purgeable" : "";
610} 610}
611 611
612static void print_error_buffers(struct seq_file *m,
613 const char *name,
614 struct drm_i915_error_buffer *err,
615 int count)
616{
617 seq_printf(m, "%s [%d]:\n", name, count);
618
619 while (count--) {
620 seq_printf(m, " %08x %8zd %04x %04x %08x%s%s%s%s%s",
621 err->gtt_offset,
622 err->size,
623 err->read_domains,
624 err->write_domain,
625 err->seqno,
626 pin_flag(err->pinned),
627 tiling_flag(err->tiling),
628 dirty_flag(err->dirty),
629 purgeable_flag(err->purgeable),
630 ring_str(err->ring));
631
632 if (err->name)
633 seq_printf(m, " (name: %d)", err->name);
634 if (err->fence_reg != I915_FENCE_REG_NONE)
635 seq_printf(m, " (fence: %d)", err->fence_reg);
636
637 seq_printf(m, "\n");
638 err++;
639 }
640}
641
612static int i915_error_state(struct seq_file *m, void *unused) 642static int i915_error_state(struct seq_file *m, void *unused)
613{ 643{
614 struct drm_info_node *node = (struct drm_info_node *) m->private; 644 struct drm_info_node *node = (struct drm_info_node *) m->private;
@@ -658,30 +688,15 @@ static int i915_error_state(struct seq_file *m, void *unused)
658 seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); 688 seq_printf(m, " INSTPM: 0x%08x\n", error->instpm);
659 seq_printf(m, " seqno: 0x%08x\n", error->seqno); 689 seq_printf(m, " seqno: 0x%08x\n", error->seqno);
660 690
661 if (error->active_bo_count) { 691 if (error->active_bo)
662 seq_printf(m, "Buffers [%d]:\n", error->active_bo_count); 692 print_error_buffers(m, "Active",
663 693 error->active_bo,
664 for (i = 0; i < error->active_bo_count; i++) { 694 error->active_bo_count);
665 seq_printf(m, " %08x %8zd %08x %08x %08x%s%s%s%s %s", 695
666 error->active_bo[i].gtt_offset, 696 if (error->pinned_bo)
667 error->active_bo[i].size, 697 print_error_buffers(m, "Pinned",
668 error->active_bo[i].read_domains, 698 error->pinned_bo,
669 error->active_bo[i].write_domain, 699 error->pinned_bo_count);
670 error->active_bo[i].seqno,
671 pin_flag(error->active_bo[i].pinned),
672 tiling_flag(error->active_bo[i].tiling),
673 dirty_flag(error->active_bo[i].dirty),
674 purgeable_flag(error->active_bo[i].purgeable),
675 ring_str(error->active_bo[i].ring));
676
677 if (error->active_bo[i].name)
678 seq_printf(m, " (name: %d)", error->active_bo[i].name);
679 if (error->active_bo[i].fence_reg != I915_FENCE_REG_NONE)
680 seq_printf(m, " (fence: %d)", error->active_bo[i].fence_reg);
681
682 seq_printf(m, "\n");
683 }
684 }
685 700
686 for (i = 0; i < ARRAY_SIZE(error->batchbuffer); i++) { 701 for (i = 0; i < ARRAY_SIZE(error->batchbuffer); i++) {
687 if (error->batchbuffer[i]) { 702 if (error->batchbuffer[i]) {
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 73a41f7ab8c6..826c7237409b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -184,8 +184,8 @@ struct drm_i915_error_state {
184 u32 dirty:1; 184 u32 dirty:1;
185 u32 purgeable:1; 185 u32 purgeable:1;
186 u32 ring:4; 186 u32 ring:4;
187 } *active_bo; 187 } *active_bo, *pinned_bo;
188 u32 active_bo_count; 188 u32 active_bo_count, pinned_bo_count;
189 struct intel_overlay_error_state *overlay; 189 struct intel_overlay_error_state *overlay;
190}; 190};
191 191
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index ef3503733ebb..bbcd5da89ba5 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -552,6 +552,40 @@ i915_ringbuffer_last_batch(struct drm_device *dev,
552 return bbaddr; 552 return bbaddr;
553} 553}
554 554
555static u32 capture_bo_list(struct drm_i915_error_buffer *err,
556 int count,
557 struct list_head *head)
558{
559 struct drm_i915_gem_object *obj;
560 int i = 0;
561
562 list_for_each_entry(obj, head, mm_list) {
563 err->size = obj->base.size;
564 err->name = obj->base.name;
565 err->seqno = obj->last_rendering_seqno;
566 err->gtt_offset = obj->gtt_offset;
567 err->read_domains = obj->base.read_domains;
568 err->write_domain = obj->base.write_domain;
569 err->fence_reg = obj->fence_reg;
570 err->pinned = 0;
571 if (obj->pin_count > 0)
572 err->pinned = 1;
573 if (obj->user_pin_count > 0)
574 err->pinned = -1;
575 err->tiling = obj->tiling_mode;
576 err->dirty = obj->dirty;
577 err->purgeable = obj->madv != I915_MADV_WILLNEED;
578 err->ring = obj->ring->id;
579
580 if (++i == count)
581 break;
582
583 err++;
584 }
585
586 return i;
587}
588
555/** 589/**
556 * i915_capture_error_state - capture an error record for later analysis 590 * i915_capture_error_state - capture an error record for later analysis
557 * @dev: drm device 591 * @dev: drm device
@@ -700,42 +734,35 @@ static void i915_capture_error_state(struct drm_device *dev)
700 error->ringbuffer = i915_error_object_create(dev, 734 error->ringbuffer = i915_error_object_create(dev,
701 dev_priv->render_ring.gem_object); 735 dev_priv->render_ring.gem_object);
702 736
703 /* Record buffers on the active list. */ 737 /* Record buffers on the active and pinned lists. */
704 error->active_bo = NULL; 738 error->active_bo = NULL;
705 error->active_bo_count = 0; 739 error->pinned_bo = NULL;
706 740
707 if (count) 741 error->active_bo_count = count;
742 list_for_each_entry(obj_priv, &dev_priv->mm.pinned_list, mm_list)
743 count++;
744 error->pinned_bo_count = count - error->active_bo_count;
745
746 if (count) {
708 error->active_bo = kmalloc(sizeof(*error->active_bo)*count, 747 error->active_bo = kmalloc(sizeof(*error->active_bo)*count,
709 GFP_ATOMIC); 748 GFP_ATOMIC);
710 749 if (error->active_bo)
711 if (error->active_bo) { 750 error->pinned_bo =
712 int i = 0; 751 error->active_bo + error->active_bo_count;
713 list_for_each_entry(obj_priv, &dev_priv->mm.active_list, mm_list) {
714 struct drm_gem_object *obj = &obj_priv->base;
715
716 error->active_bo[i].size = obj->size;
717 error->active_bo[i].name = obj->name;
718 error->active_bo[i].seqno = obj_priv->last_rendering_seqno;
719 error->active_bo[i].gtt_offset = obj_priv->gtt_offset;
720 error->active_bo[i].read_domains = obj->read_domains;
721 error->active_bo[i].write_domain = obj->write_domain;
722 error->active_bo[i].fence_reg = obj_priv->fence_reg;
723 error->active_bo[i].pinned = 0;
724 if (obj_priv->pin_count > 0)
725 error->active_bo[i].pinned = 1;
726 if (obj_priv->user_pin_count > 0)
727 error->active_bo[i].pinned = -1;
728 error->active_bo[i].tiling = obj_priv->tiling_mode;
729 error->active_bo[i].dirty = obj_priv->dirty;
730 error->active_bo[i].purgeable = obj_priv->madv != I915_MADV_WILLNEED;
731 error->active_bo[i].ring = obj_priv->ring->id;
732
733 if (++i == count)
734 break;
735 }
736 error->active_bo_count = i;
737 } 752 }
738 753
754 if (error->active_bo)
755 error->active_bo_count =
756 capture_bo_list(error->active_bo,
757 error->active_bo_count,
758 &dev_priv->mm.active_list);
759
760 if (error->pinned_bo)
761 error->pinned_bo_count =
762 capture_bo_list(error->pinned_bo,
763 error->pinned_bo_count,
764 &dev_priv->mm.pinned_list);
765
739 do_gettimeofday(&error->time); 766 do_gettimeofday(&error->time);
740 767
741 error->overlay = intel_overlay_capture_error_state(dev); 768 error->overlay = intel_overlay_capture_error_state(dev);