提交 3954e733 编写于 作者: R Ramalingam C 提交者: Daniel Vetter

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: NRamalingam C <ramalingam.c@intel.com>
Reviewed-by: NRodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: NDaniel Vetter <daniel.vetter@ffwll.ch>
上级 a54746e3
......@@ -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,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册