diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-04-13 17:04:09 -0400 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2011-06-09 14:43:47 -0400 |
commit | a8198eea156df47e0e843ac5c7d4c8774e121c42 (patch) | |
tree | e2a1376eadff54842460fa392efcf4a0505f1bd8 | |
parent | 284d952968d60cca156ef0c5efa62592b72264cb (diff) |
drm/i915: Introduce i915_gem_object_finish_gpu()
... reincarnated from i915_gem_object_flush_gpu(). The semantic
difference is that after calling finish_gpu() the object no longer
resides in any GPU domain, and so will cause the GPU caches to be
invalidated if it is ever used again.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 29 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 2 |
3 files changed, 21 insertions, 12 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f63ee162f124..4d1a8ae70a33 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1190,7 +1190,7 @@ void i915_gem_clflush_object(struct drm_i915_gem_object *obj); | |||
1190 | int __must_check i915_gem_object_set_domain(struct drm_i915_gem_object *obj, | 1190 | int __must_check i915_gem_object_set_domain(struct drm_i915_gem_object *obj, |
1191 | uint32_t read_domains, | 1191 | uint32_t read_domains, |
1192 | uint32_t write_domain); | 1192 | uint32_t write_domain); |
1193 | int __must_check i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj); | 1193 | int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj); |
1194 | int __must_check i915_gem_init_ringbuffer(struct drm_device *dev); | 1194 | int __must_check i915_gem_init_ringbuffer(struct drm_device *dev); |
1195 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); | 1195 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); |
1196 | void i915_gem_do_init(struct drm_device *dev, | 1196 | void i915_gem_do_init(struct drm_device *dev, |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 12d32579b951..6291dcdf5d40 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -2165,23 +2165,29 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) | |||
2165 | return -EINVAL; | 2165 | return -EINVAL; |
2166 | } | 2166 | } |
2167 | 2167 | ||
2168 | ret = i915_gem_object_finish_gpu(obj); | ||
2169 | if (ret == -ERESTARTSYS) | ||
2170 | return ret; | ||
2171 | /* Continue on if we fail due to EIO, the GPU is hung so we | ||
2172 | * should be safe and we need to cleanup or else we might | ||
2173 | * cause memory corruption through use-after-free. | ||
2174 | */ | ||
2175 | |||
2168 | /* blow away mappings if mapped through GTT */ | 2176 | /* blow away mappings if mapped through GTT */ |
2169 | i915_gem_release_mmap(obj); | 2177 | i915_gem_release_mmap(obj); |
2170 | 2178 | ||
2171 | /* Move the object to the CPU domain to ensure that | 2179 | /* Move the object to the CPU domain to ensure that |
2172 | * any possible CPU writes while it's not in the GTT | 2180 | * any possible CPU writes while it's not in the GTT |
2173 | * are flushed when we go to remap it. This will | 2181 | * are flushed when we go to remap it. |
2174 | * also ensure that all pending GPU writes are finished | ||
2175 | * before we unbind. | ||
2176 | */ | 2182 | */ |
2177 | ret = i915_gem_object_set_to_cpu_domain(obj, 1); | 2183 | if (ret == 0) |
2184 | ret = i915_gem_object_set_to_cpu_domain(obj, 1); | ||
2178 | if (ret == -ERESTARTSYS) | 2185 | if (ret == -ERESTARTSYS) |
2179 | return ret; | 2186 | return ret; |
2180 | /* Continue on if we fail due to EIO, the GPU is hung so we | ||
2181 | * should be safe and we need to cleanup or else we might | ||
2182 | * cause memory corruption through use-after-free. | ||
2183 | */ | ||
2184 | if (ret) { | 2187 | if (ret) { |
2188 | /* In the event of a disaster, abandon all caches and | ||
2189 | * hope for the best. | ||
2190 | */ | ||
2185 | i915_gem_clflush_object(obj); | 2191 | i915_gem_clflush_object(obj); |
2186 | obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU; | 2192 | obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU; |
2187 | } | 2193 | } |
@@ -3045,11 +3051,11 @@ i915_gem_object_set_to_display_plane(struct drm_i915_gem_object *obj, | |||
3045 | } | 3051 | } |
3046 | 3052 | ||
3047 | int | 3053 | int |
3048 | i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj) | 3054 | i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj) |
3049 | { | 3055 | { |
3050 | int ret; | 3056 | int ret; |
3051 | 3057 | ||
3052 | if (!obj->active) | 3058 | if ((obj->base.read_domains & I915_GEM_GPU_DOMAINS) == 0) |
3053 | return 0; | 3059 | return 0; |
3054 | 3060 | ||
3055 | if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { | 3061 | if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { |
@@ -3058,6 +3064,9 @@ i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj) | |||
3058 | return ret; | 3064 | return ret; |
3059 | } | 3065 | } |
3060 | 3066 | ||
3067 | /* Ensure that we invalidate the GPU's caches and TLBs. */ | ||
3068 | obj->base.read_domains &= ~I915_GEM_GPU_DOMAINS; | ||
3069 | |||
3061 | return i915_gem_object_wait_rendering(obj); | 3070 | return i915_gem_object_wait_rendering(obj); |
3062 | } | 3071 | } |
3063 | 3072 | ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index aa43e7be6053..e32fb89b3165 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1971,7 +1971,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1971 | * This should only fail upon a hung GPU, in which case we | 1971 | * This should only fail upon a hung GPU, in which case we |
1972 | * can safely continue. | 1972 | * can safely continue. |
1973 | */ | 1973 | */ |
1974 | ret = i915_gem_object_flush_gpu(obj); | 1974 | ret = i915_gem_object_finish_gpu(obj); |
1975 | (void) ret; | 1975 | (void) ret; |
1976 | } | 1976 | } |
1977 | 1977 | ||