aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-07-23 18:18:51 -0400
committerEric Anholt <eric@anholt.net>2010-08-01 22:56:29 -0400
commit8dc1775dce10d5e47d2805665804fddf39ea3a90 (patch)
treec8929cedb667faacd988eb22312dbe7c72728c0a
parentbe72615bcf4d5b7b314d836c5e1b4baa4b65dad1 (diff)
drm/i915: Attempt to uncouple object after catastrophic failure in unbind
If we fail to flush outstanding GPU writes but return the memory to the system, we risk corrupting memory should the GPU recovery and complete those writes. On the other hand, if we bail early and free the object then we have a definite use-after-free and real memory corruption. Choose the lesser of two evils, since in order to recover from the hung GPU we need to completely reset it, those pending writes should never happen. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Eric Anholt <eric@anholt.net>
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index f45f385c84cd..eeb768818136 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1967,11 +1967,12 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
1967 * before we unbind. 1967 * before we unbind.
1968 */ 1968 */
1969 ret = i915_gem_object_set_to_cpu_domain(obj, 1); 1969 ret = i915_gem_object_set_to_cpu_domain(obj, 1);
1970 if (ret) { 1970 if (ret == -ERESTARTSYS)
1971 if (ret != -ERESTARTSYS)
1972 DRM_ERROR("set_domain failed: %d\n", ret);
1973 return ret; 1971 return ret;
1974 } 1972 /* Continue on if we fail due to EIO, the GPU is hung so we
1973 * should be safe and we need to cleanup or else we might
1974 * cause memory corruption through use-after-free.
1975 */
1975 1976
1976 BUG_ON(obj_priv->active); 1977 BUG_ON(obj_priv->active);
1977 1978
@@ -2007,7 +2008,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
2007 2008
2008 trace_i915_gem_object_unbind(obj); 2009 trace_i915_gem_object_unbind(obj);
2009 2010
2010 return 0; 2011 return ret;
2011} 2012}
2012 2013
2013static struct drm_gem_object * 2014static struct drm_gem_object *