Skip to content

Commit

Permalink
drm/i915: Error checks in gen6_set_rps
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Ben Widawsky authored and Daniel Vetter committed Sep 20, 2012
1 parent d5570a7 commit 7924963
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 1 deletion.
8 changes: 7 additions & 1 deletion drivers/gpu/drm/i915/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/intel_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 7924963

Please sign in to comment.