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

Commit 3954e733 authored by Ramalingam C's avatar Ramalingam C Committed by Daniel Vetter
Browse files

drm/i915: Fixing mutex deadlock window at eDP DRRS



In invalidate and flush functions of eDP DRRS, if deferred downclock
work starts execution at a time window between acquiring the drrs
mutex and cancellation of the deferred work
(intel_edp_drrs_downclock_work), then deferred work will find
drrs mutex locked and wait for the same.

Meanwhile the function that acquired mutex drrs invalidate/flush will
wait for the completion of the deferred work before releasing the mutex.
Thats a deadlock.

To avoid such deadlock scenario, this change cancels the deferred work
before acquiring the mutex at invalidate and flush functions.

Signed-off-by: default avatarRamalingam C <ramalingam.c@intel.com>
Reviewed-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent a54746e3
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -4966,12 +4966,13 @@ void intel_edp_drrs_invalidate(struct drm_device *dev,
	if (!dev_priv->drrs.dp)
		return;

	cancel_delayed_work_sync(&dev_priv->drrs.work);

	mutex_lock(&dev_priv->drrs.mutex);
	crtc = dp_to_dig_port(dev_priv->drrs.dp)->base.base.crtc;
	pipe = to_intel_crtc(crtc)->pipe;

	if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) {
		cancel_delayed_work_sync(&dev_priv->drrs.work);
		intel_dp_set_drrs_state(dev_priv->dev,
				dev_priv->drrs.dp->attached_connector->panel.
				fixed_mode->vrefresh);
@@ -5004,13 +5005,13 @@ void intel_edp_drrs_flush(struct drm_device *dev,
	if (!dev_priv->drrs.dp)
		return;

	cancel_delayed_work_sync(&dev_priv->drrs.work);

	mutex_lock(&dev_priv->drrs.mutex);
	crtc = dp_to_dig_port(dev_priv->drrs.dp)->base.base.crtc;
	pipe = to_intel_crtc(crtc)->pipe;
	dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;

	cancel_delayed_work_sync(&dev_priv->drrs.work);

	if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR &&
			!dev_priv->drrs.busy_frontbuffer_bits)
		schedule_delayed_work(&dev_priv->drrs.work,