summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Widawsky <ben@bwidawsk.net>2012-09-07 19:43:42 -0700
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-09-20 14:23:01 +0200
commit792496368bcd766926239a5ad105ca9aad797b34 (patch)
tree0d50f6c63f4700507f5a58866cc053b1d7680ed7
parentd5570a72439b2d972c915208266440c2f330d03d (diff)
drm/i915: Error checks in gen6_set_rps
With the new "standardized" sysfs interfaces we need to be a bit more careful about setting the RPS values. Because the sysfs code and the rps workqueue can run at the same time, if the sysfs setter wins the race to the mutex, the workqueue can come in and set a value which is out of range (ie. we're no longer protecting by RPINTLIM). I was not able to actually make this error occur in testing. Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c8
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c2
2 files changed, 9 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index dd49046bccd..d9151264d91 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -382,7 +382,13 @@ static void gen6_pm_rps_work(struct work_struct *work)
else
new_delay = dev_priv->rps.cur_delay - 1;
- gen6_set_rps(dev_priv->dev, new_delay);
+ /* sysfs frequency interfaces may have snuck in while servicing the
+ * interrupt
+ */
+ if (!(new_delay > dev_priv->rps.max_delay ||
+ new_delay < dev_priv->rps.min_delay)) {
+ gen6_set_rps(dev_priv->dev, new_delay);
+ }
mutex_unlock(&dev_priv->dev->struct_mutex);
}
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 4e86037ae6b..82ca172831c 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2324,6 +2324,8 @@ void gen6_set_rps(struct drm_device *dev, u8 val)
u32 limits = gen6_rps_limits(dev_priv, &val);
WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+ WARN_ON(val > dev_priv->rps.max_delay);
+ WARN_ON(val < dev_priv->rps.min_delay);
if (val == dev_priv->rps.cur_delay)
return;