diff options
author | Eric Anholt <eric@anholt.net> | 2008-11-13 18:00:55 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2008-11-24 18:27:52 -0500 |
commit | 28dfe52a6e8a1495067c4331358700a170d0ee86 (patch) | |
tree | 5b81b6c092fe0d212d3b198293ddadaf3e2d2738 /drivers/gpu | |
parent | cdfbc41f6d602fc0105fb2b4e0645cc1aa274c12 (diff) |
drm/i915: Avoid BUG_ONs on VT switch with a wedged chipset.
Instead, just warn that bad things are happening and do our best to clean up
the mess without the GPU's help.
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 53 |
1 files changed, 39 insertions, 14 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6b4a2bd20640..edc805afde05 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include "i915_drv.h" | 31 | #include "i915_drv.h" |
32 | #include <linux/swap.h> | 32 | #include <linux/swap.h> |
33 | 33 | ||
34 | #define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) | ||
35 | |||
34 | static int | 36 | static int |
35 | i915_gem_object_set_domain(struct drm_gem_object *obj, | 37 | i915_gem_object_set_domain(struct drm_gem_object *obj, |
36 | uint32_t read_domains, | 38 | uint32_t read_domains, |
@@ -2299,29 +2301,52 @@ i915_gem_idle(struct drm_device *dev) | |||
2299 | 2301 | ||
2300 | i915_gem_retire_requests(dev); | 2302 | i915_gem_retire_requests(dev); |
2301 | 2303 | ||
2302 | /* Active and flushing should now be empty as we've | 2304 | if (!dev_priv->mm.wedged) { |
2303 | * waited for a sequence higher than any pending execbuffer | 2305 | /* Active and flushing should now be empty as we've |
2304 | */ | 2306 | * waited for a sequence higher than any pending execbuffer |
2305 | BUG_ON(!list_empty(&dev_priv->mm.active_list)); | 2307 | */ |
2306 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | 2308 | WARN_ON(!list_empty(&dev_priv->mm.active_list)); |
2309 | WARN_ON(!list_empty(&dev_priv->mm.flushing_list)); | ||
2310 | /* Request should now be empty as we've also waited | ||
2311 | * for the last request in the list | ||
2312 | */ | ||
2313 | WARN_ON(!list_empty(&dev_priv->mm.request_list)); | ||
2314 | } | ||
2307 | 2315 | ||
2308 | /* Request should now be empty as we've also waited | 2316 | /* Empty the active and flushing lists to inactive. If there's |
2309 | * for the last request in the list | 2317 | * anything left at this point, it means that we're wedged and |
2318 | * nothing good's going to happen by leaving them there. So strip | ||
2319 | * the GPU domains and just stuff them onto inactive. | ||
2310 | */ | 2320 | */ |
2311 | BUG_ON(!list_empty(&dev_priv->mm.request_list)); | 2321 | while (!list_empty(&dev_priv->mm.active_list)) { |
2322 | struct drm_i915_gem_object *obj_priv; | ||
2323 | |||
2324 | obj_priv = list_first_entry(&dev_priv->mm.active_list, | ||
2325 | struct drm_i915_gem_object, | ||
2326 | list); | ||
2327 | obj_priv->obj->write_domain &= ~I915_GEM_GPU_DOMAINS; | ||
2328 | i915_gem_object_move_to_inactive(obj_priv->obj); | ||
2329 | } | ||
2330 | |||
2331 | while (!list_empty(&dev_priv->mm.flushing_list)) { | ||
2332 | struct drm_i915_gem_object *obj_priv; | ||
2333 | |||
2334 | obj_priv = list_first_entry(&dev_priv->mm.active_list, | ||
2335 | struct drm_i915_gem_object, | ||
2336 | list); | ||
2337 | obj_priv->obj->write_domain &= ~I915_GEM_GPU_DOMAINS; | ||
2338 | i915_gem_object_move_to_inactive(obj_priv->obj); | ||
2339 | } | ||
2340 | |||
2312 | 2341 | ||
2313 | /* Move all buffers out of the GTT. */ | 2342 | /* Move all inactive buffers out of the GTT. */ |
2314 | ret = i915_gem_evict_from_list(dev, &dev_priv->mm.inactive_list); | 2343 | ret = i915_gem_evict_from_list(dev, &dev_priv->mm.inactive_list); |
2344 | WARN_ON(!list_empty(&dev_priv->mm.inactive_list)); | ||
2315 | if (ret) { | 2345 | if (ret) { |
2316 | mutex_unlock(&dev->struct_mutex); | 2346 | mutex_unlock(&dev->struct_mutex); |
2317 | return ret; | 2347 | return ret; |
2318 | } | 2348 | } |
2319 | 2349 | ||
2320 | BUG_ON(!list_empty(&dev_priv->mm.active_list)); | ||
2321 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | ||
2322 | BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); | ||
2323 | BUG_ON(!list_empty(&dev_priv->mm.request_list)); | ||
2324 | |||
2325 | i915_gem_cleanup_ringbuffer(dev); | 2350 | i915_gem_cleanup_ringbuffer(dev); |
2326 | mutex_unlock(&dev->struct_mutex); | 2351 | mutex_unlock(&dev->struct_mutex); |
2327 | 2352 | ||