Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 67e77c5a authored by Daniel Vetter's avatar Daniel Vetter Committed by Chris Wilson
Browse files

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: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent 3dec0095
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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);
+14 −0
Original line number Diff line number Diff line
@@ -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);
}