aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-12-14 07:57:25 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-01-31 15:02:54 -0500
commit172975aa746e155533cb386c7159c2d6510e2bc8 (patch)
tree9e511dfba94c1d1ed6919d141610296507e3b6de /drivers/gpu
parent8461d2267726dddcb9b5d6ae6b32769b38a326cc (diff)
drm/i915: Handle unmappable buffers during error state capture
As the buffer is not necessarily accessible through the GTT at the time of a GPU hang, and capturing some of its contents is far more valuable than skipping it, provide a clflushed fallback read path. We still prefer to read through the GTT as that is more consistent with the GPU access of the same buffer. So example it will demonstrate any errorneous tiling or swizzling of the command buffer as seen by the GPU. This becomes necessary with use of CPU relocations and lazy GTT binding, but could potentially happen anyway as a result of a pathological error. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Eugeni Dodonov <eugeni.dodonov@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 64bb2127911e..8ea1ca4158a0 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -720,7 +720,6 @@ i915_error_object_create(struct drm_i915_private *dev_priv,
720 reloc_offset = src->gtt_offset; 720 reloc_offset = src->gtt_offset;
721 for (page = 0; page < page_count; page++) { 721 for (page = 0; page < page_count; page++) {
722 unsigned long flags; 722 unsigned long flags;
723 void __iomem *s;
724 void *d; 723 void *d;
725 724
726 d = kmalloc(PAGE_SIZE, GFP_ATOMIC); 725 d = kmalloc(PAGE_SIZE, GFP_ATOMIC);
@@ -728,10 +727,29 @@ i915_error_object_create(struct drm_i915_private *dev_priv,
728 goto unwind; 727 goto unwind;
729 728
730 local_irq_save(flags); 729 local_irq_save(flags);
731 s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, 730 if (reloc_offset < dev_priv->mm.gtt_mappable_end) {
732 reloc_offset); 731 void __iomem *s;
733 memcpy_fromio(d, s, PAGE_SIZE); 732
734 io_mapping_unmap_atomic(s); 733 /* Simply ignore tiling or any overlapping fence.
734 * It's part of the error state, and this hopefully
735 * captures what the GPU read.
736 */
737
738 s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
739 reloc_offset);
740 memcpy_fromio(d, s, PAGE_SIZE);
741 io_mapping_unmap_atomic(s);
742 } else {
743 void *s;
744
745 drm_clflush_pages(&src->pages[page], 1);
746
747 s = kmap_atomic(src->pages[page]);
748 memcpy(d, s, PAGE_SIZE);
749 kunmap_atomic(s);
750
751 drm_clflush_pages(&src->pages[page], 1);
752 }
735 local_irq_restore(flags); 753 local_irq_restore(flags);
736 754
737 dst->pages[page] = d; 755 dst->pages[page] = d;