forked from Minki/linux
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: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
parent
273e27ca80
commit
2c34b850ee
@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user