Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 79249636 authored by Ben Widawsky's avatar Ben Widawsky Committed by Daniel Vetter
Browse files

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: default avatarBen Widawsky <ben@bwidawsk.net>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent d5570a72
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -382,7 +382,13 @@ static void gen6_pm_rps_work(struct work_struct *work)
	else
		new_delay = dev_priv->rps.cur_delay - 1;

	/* 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);
}
+2 −0
Original line number Diff line number Diff line
@@ -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;