Commit 2c34b850 authored by Ben Widawsky's avatar Ben Widawsky Committed by Keith Packard

drm/i915: fix ilk rc6 teardown locking

In the failure cases during rc6 initialization, both the power context
and render context may get !refcount without holding struct_mutex.
However, on rc6 disabling, the lock is held by the caller.

Rearranged the locking so that it's safe in both cases.
Signed-off-by: default avatarBen Widawsky <ben@bwidawsk.net>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarKeith Packard <keithp@keithp.com>
Signed-off-by: default avatarKeith Packard <keithp@keithp.com>
parent 273e27ca
...@@ -6713,13 +6713,14 @@ intel_alloc_context_page(struct drm_device *dev) ...@@ -6713,13 +6713,14 @@ intel_alloc_context_page(struct drm_device *dev)
struct drm_i915_gem_object *ctx; struct drm_i915_gem_object *ctx;
int ret; int ret;
WARN_ON(!mutex_is_locked(&dev->struct_mutex));
ctx = i915_gem_alloc_object(dev, 4096); ctx = i915_gem_alloc_object(dev, 4096);
if (!ctx) { if (!ctx) {
DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); DRM_DEBUG("failed to alloc power context, RC6 disabled\n");
return NULL; return NULL;
} }
mutex_lock(&dev->struct_mutex);
ret = i915_gem_object_pin(ctx, 4096, true); ret = i915_gem_object_pin(ctx, 4096, true);
if (ret) { if (ret) {
DRM_ERROR("failed to pin power context: %d\n", ret); DRM_ERROR("failed to pin power context: %d\n", ret);
...@@ -6731,7 +6732,6 @@ intel_alloc_context_page(struct drm_device *dev) ...@@ -6731,7 +6732,6 @@ intel_alloc_context_page(struct drm_device *dev)
DRM_ERROR("failed to set-domain on power context: %d\n", ret); DRM_ERROR("failed to set-domain on power context: %d\n", ret);
goto err_unpin; goto err_unpin;
} }
mutex_unlock(&dev->struct_mutex);
return ctx; return ctx;
...@@ -7295,9 +7295,12 @@ void ironlake_enable_rc6(struct drm_device *dev) ...@@ -7295,9 +7295,12 @@ void ironlake_enable_rc6(struct drm_device *dev)
if (!i915_enable_rc6) if (!i915_enable_rc6)
return; return;
mutex_lock(&dev->struct_mutex);
ret = ironlake_setup_rc6(dev); ret = ironlake_setup_rc6(dev);
if (ret) if (ret) {
mutex_unlock(&dev->struct_mutex);
return; return;
}
/* /*
* GPU can automatically power down the render unit if given a page * GPU can automatically power down the render unit if given a page
...@@ -7306,6 +7309,7 @@ void ironlake_enable_rc6(struct drm_device *dev) ...@@ -7306,6 +7309,7 @@ void ironlake_enable_rc6(struct drm_device *dev)
ret = BEGIN_LP_RING(6); ret = BEGIN_LP_RING(6);
if (ret) { if (ret) {
ironlake_teardown_rc6(dev); ironlake_teardown_rc6(dev);
mutex_unlock(&dev->struct_mutex);
return; return;
} }
...@@ -7323,6 +7327,7 @@ void ironlake_enable_rc6(struct drm_device *dev) ...@@ -7323,6 +7327,7 @@ void ironlake_enable_rc6(struct drm_device *dev)
I915_WRITE(PWRCTXA, dev_priv->pwrctx->gtt_offset | PWRCTX_EN); I915_WRITE(PWRCTXA, dev_priv->pwrctx->gtt_offset | PWRCTX_EN);
I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT);
mutex_unlock(&dev->struct_mutex);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment