If reset fails, the GPU is declared wedged. This ideally should never happen, but very rarely it does. After the GPU is declared wedged, we must allow userspace to continue to use its mapping of bo in order to recover its data (and in some cases in order for memory management to continue unabated). Obviously after the GPU is wedged, no bo are currently accessed by the GPU and so we can complete any waits or domain transitions away from the GPU. Currently, we fail this essential task and instead report EIO and send a SIGBUS to the affected process - causing major loss of data (by killing X or compiz). References: https://bugs.freedesktop.org/show_bug.cgi?id=63921 References: https://bugs.freedesktop.org/show_bug.cgi?id=64073 Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk> --- drivers/gpu/drm/i915/i915_gem.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e0c3ada..2bd8d7a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1214,7 +1214,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, * to catch cases where we are gazumped. */ ret = i915_gem_object_wait_rendering__nonblocking(obj, !write_domain); - if (ret) + if (ret && ret != -EIO) goto unref; if (read_domains & I915_GEM_DOMAIN_GTT) { @@ -1334,6 +1334,8 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) bool write = !!(vmf->flags & FAULT_FLAG_WRITE); ret = i915_mutex_lock_interruptible(dev); + if (ret == -EIO) + ret = mutex_lock_interruptible(dev); if (ret) goto out; @@ -2732,7 +2734,7 @@ i915_gem_object_wait_fence(struct drm_i915_gem_object *obj) { if (obj->last_fenced_seqno) { int ret = i915_wait_seqno(obj->ring, obj->last_fenced_seqno); - if (ret) + if (ret && ret != -EIO) return ret; obj->last_fenced_seqno = 0; @@ -3141,7 +3143,7 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) return 0; ret = i915_gem_object_wait_rendering(obj, !write); - if (ret) + if (ret && ret != -EIO) return ret; i915_gem_object_flush_cpu_write_domain(obj); @@ -3382,7 +3384,7 @@ i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj) return 0; ret = i915_gem_object_wait_rendering(obj, false); - if (ret) + if (ret && ret != -EIO) return ret; /* Ensure that we invalidate the GPU's caches and TLBs. */ @@ -3406,7 +3408,7 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write) return 0; ret = i915_gem_object_wait_rendering(obj, !write); - if (ret) + if (ret && ret != -EIO) return ret; i915_gem_object_flush_gtt_write_domain(obj); -- 1.7.10.4