Skip to content

Commit

Permalink
drm/i915: unload: fix unpin_work related races
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Daniel Vetter authored and Chris Wilson committed Sep 8, 2010
1 parent 3dec009 commit 67e77c5
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 0 deletions.
3 changes: 3 additions & 0 deletions drivers/gpu/drm/i915/i915_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -2292,6 +2292,9 @@ int i915_driver_unload(struct drm_device *dev)
intel_opregion_free(dev, 0);

if (drm_core_check_feature(dev, DRIVER_MODESET)) {
/* Flush any outstanding unpin_work. */
flush_workqueue(dev_priv->wq);

i915_gem_free_all_phys_object(dev);

mutex_lock(&dev->struct_mutex);
Expand Down
14 changes: 14 additions & 0 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down

0 comments on commit 67e77c5

Please sign in to comment.