From: Paulo Zanoni <paulo.r.zanoni@xxxxxxxxx> The problem with calling intel_fbc_update() at flush is that it fully rechecks and recomputes the FBC state, and that includes reallocating the CFB, which requires a struct_mutex lock that we don't always have. The lack of struct_mutex lock can be considered a regression from: commit dbef0f15b5c83231dacb214dbf9a6dba063ca21c Author: Paulo Zanoni <paulo.r.zanoni@xxxxxxxxx> Date: Fri Feb 13 17:23:46 2015 -0200 drm/i915: add frontbuffer tracking to FBC So introduce intel_fbc_stop() that doesn't unset fbc.crtc, then call stop/enable at invalidate/flush. Notice that invalidate/flush is only called by the frontbuffer tracking infrastrucutre, so it's safe to not do a full intel_fbc_update() here. Signed-off-by: Paulo Zanoni <paulo.r.zanoni@xxxxxxxxx> --- drivers/gpu/drm/i915/intel_fbc.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 316feb1..0a66814 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -422,7 +422,7 @@ static void intel_fbc_enable(struct drm_crtc *crtc) schedule_delayed_work(&work->work, msecs_to_jiffies(50)); } -static void __intel_fbc_disable(struct drm_device *dev) +static void intel_fbc_stop(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -434,6 +434,13 @@ static void __intel_fbc_disable(struct drm_device *dev) return; dev_priv->display.disable_fbc(dev); +} + +static void __intel_fbc_disable(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + intel_fbc_stop(dev); dev_priv->fbc.crtc = NULL; } @@ -753,7 +760,7 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv, dev_priv->fbc.busy_bits |= (fbc_bits & frontbuffer_bits); if (dev_priv->fbc.busy_bits) - __intel_fbc_disable(dev); + intel_fbc_stop(dev); mutex_unlock(&dev_priv->fbc.lock); } @@ -770,8 +777,11 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv, dev_priv->fbc.busy_bits &= ~frontbuffer_bits; - if (!dev_priv->fbc.busy_bits) - __intel_fbc_update(dev); + if (!dev_priv->fbc.busy_bits && dev_priv->fbc.crtc) { + if (dev_priv->fbc.enabled) + intel_fbc_stop(dev); + intel_fbc_enable(&dev_priv->fbc.crtc->base); + } out: mutex_unlock(&dev_priv->fbc.lock); -- 2.1.4 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx