diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-07-23 23:18:50 +0100 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2010-08-01 19:53:24 -0700 |
commit | be72615bcf4d5b7b314d836c5e1b4baa4b65dad1 (patch) | |
tree | 1a16cfaf29843b54a4577120c3c2df9cfd548f60 /drivers/gpu/drm/i915/i915_drv.h | |
parent | b09a1feca65764311f8a3e14befb52b98d705f0a (diff) |
drm/i915: Repeat unbinding during free if interrupted (v6)
If during the freeing of an object the unbind is interrupted by a system
call, which is quite possible if we have outstanding GPU writes that
must be flushed, the unbind is silently aborted. This still leaves the
AGP region and backing pages allocated, and perhaps more importantly,
the object remains upon the various lists exposing us to memory
corruption.
I think this is the cause behind the use-after-free, such as
Bug 15664 - Graphics hang and kernel backtrace when starting Azureus
with Compiz enabled
https://bugzilla.kernel.org/show_bug.cgi?id=15664
v2: Daniel Vetter reminded me that kernel space programming is never easy.
We cannot simply spin to clear the pending signal and so must deferred
the freeing of the object until later.
v3: Run from the top level retire requests.
v4: Tested with P(return -ERESTARTSYS)=.5 from i915_gem_do_wait_request()
v5: Rebase against Eric's for-linus tree.
v6: Refactor, split and add a comment about avoiding unbounded recursion.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_drv.h')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a27780b7aef..906663b9929 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -552,6 +552,14 @@ typedef struct drm_i915_private { struct list_head fence_list; /** + * List of objects currently pending being freed. + * + * These objects are no longer in use, but due to a signal + * we were prevented from freeing them at the appointed time. + */ + struct list_head deferred_free_list; + + /** * We leave the user IRQ off as much as possible, * but this means that requests will finish and never * be retired once the system goes idle. Set a timer to |