[PATCH 03/14] drm/i915: Do not allow a pending forcewake put to unbalance across reset

Rodrigo Vivi
2014-04-18T21:04:36Z

From: Chris Wilson <chris@chris-wilson.co.uk>

Across a device reset, we try to restore and user forcewake reference
counts. This is complicated by our deferred forcewake put adding an
extra reference, that may or may not be flushed when we call
del_timer_sync. So we have to take that pending reference into account
when restoring the forcewake.

Reported-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@gmail.com>
---
drivers/gpu/drm/i915/intel_uncore.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 2a72bab..c8969e3 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -317,8 +317,9 @@ static void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
{
struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long irqflags;
+ int pending;

- del_timer_sync(&dev_priv->uncore.force_wake_timer);
+ pending = del_timer_sync(&dev_priv->uncore.force_wake_timer);

/* Hold uncore.lock across reset to prevent any register access
* with forcewake not set correctly
@@ -336,6 +337,8 @@ static void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
if (restore) { /* If reset with a user forcewake, try to restore */
unsigned fw = 0;

+ dev_priv->uncore.forcewake_count -= pending;
+
if (IS_VALLEYVIEW(dev)) {
if (dev_priv->uncore.fw_rendercount)
fw |= FORCEWAKE_RENDER;
--
1.8.3.1