summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorDaniel Vetter2010-08-20 22:26:30 +0200
committerChris Wilson2010-09-08 11:13:27 +0200
commit67e77c5ae8bff6f805d207541f1315051248a87b (patch)
tree56a845d734e9a8ed8027683ba0897fd95d280652 /drivers/gpu/drm/i915/intel_display.c
parentdrm/i915: unload: fix idle_timer/idle_work races (diff)
downloadkernel-qcow2-linux-67e77c5ae8bff6f805d207541f1315051248a87b.tar.gz
kernel-qcow2-linux-67e77c5ae8bff6f805d207541f1315051248a87b.tar.xz
kernel-qcow2-linux-67e77c5ae8bff6f805d207541f1315051248a87b.zip
drm/i915: unload: fix unpin_work related races
Kill any outstanding unpin_work when destroying the corresponding crtc. Then flush the workqueue before the gem teardown, in case any unpin work is still outstanding. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ccfc10559c17..794d4ac0c40f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4850,8 +4850,22 @@ void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj)
static void intel_crtc_destroy(struct drm_crtc *crtc)
{
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+ struct intel_unpin_work *work;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ work = intel_crtc->unpin_work;
+ intel_crtc->unpin_work = NULL;
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+
+ if (work) {
+ cancel_work_sync(&work->work);
+ kfree(work);
+ }
drm_crtc_cleanup(crtc);
+
kfree(intel_crtc);
}