diff options
author | Ben Widawsky <ben@bwidawsk.net> | 2011-03-19 21:14:26 -0400 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2011-05-10 16:56:40 -0400 |
commit | 2c34b850ee1e9f86b41706149d0954eee58757a3 (patch) | |
tree | e2c62976d4efd5b88f5914fdb91ff5f110328823 /drivers/gpu | |
parent | 273e27ca8081095a1bdf65276d4b645215ad1c57 (diff) |
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>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index bcef1c1e83fc..b6f593a6d970 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -6713,13 +6713,14 @@ intel_alloc_context_page(struct drm_device *dev) | |||
6713 | struct drm_i915_gem_object *ctx; | 6713 | struct drm_i915_gem_object *ctx; |
6714 | int ret; | 6714 | int ret; |
6715 | 6715 | ||
6716 | WARN_ON(!mutex_is_locked(&dev->struct_mutex)); | ||
6717 | |||
6716 | ctx = i915_gem_alloc_object(dev, 4096); | 6718 | ctx = i915_gem_alloc_object(dev, 4096); |
6717 | if (!ctx) { | 6719 | if (!ctx) { |
6718 | DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); | 6720 | DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); |
6719 | return NULL; | 6721 | return NULL; |
6720 | } | 6722 | } |
6721 | 6723 | ||
6722 | mutex_lock(&dev->struct_mutex); | ||
6723 | ret = i915_gem_object_pin(ctx, 4096, true); | 6724 | ret = i915_gem_object_pin(ctx, 4096, true); |
6724 | if (ret) { | 6725 | if (ret) { |
6725 | DRM_ERROR("failed to pin power context: %d\n", ret); | 6726 | DRM_ERROR("failed to pin power context: %d\n", ret); |
@@ -6731,7 +6732,6 @@ intel_alloc_context_page(struct drm_device *dev) | |||
6731 | DRM_ERROR("failed to set-domain on power context: %d\n", ret); | 6732 | DRM_ERROR("failed to set-domain on power context: %d\n", ret); |
6732 | goto err_unpin; | 6733 | goto err_unpin; |
6733 | } | 6734 | } |
6734 | mutex_unlock(&dev->struct_mutex); | ||
6735 | 6735 | ||
6736 | return ctx; | 6736 | return ctx; |
6737 | 6737 | ||
@@ -7295,9 +7295,12 @@ void ironlake_enable_rc6(struct drm_device *dev) | |||
7295 | if (!i915_enable_rc6) | 7295 | if (!i915_enable_rc6) |
7296 | return; | 7296 | return; |
7297 | 7297 | ||
7298 | mutex_lock(&dev->struct_mutex); | ||
7298 | ret = ironlake_setup_rc6(dev); | 7299 | ret = ironlake_setup_rc6(dev); |
7299 | if (ret) | 7300 | if (ret) { |
7301 | mutex_unlock(&dev->struct_mutex); | ||
7300 | return; | 7302 | return; |
7303 | } | ||
7301 | 7304 | ||
7302 | /* | 7305 | /* |
7303 | * GPU can automatically power down the render unit if given a page | 7306 | * 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 | ret = BEGIN_LP_RING(6); | 7309 | ret = BEGIN_LP_RING(6); |
7307 | if (ret) { | 7310 | if (ret) { |
7308 | ironlake_teardown_rc6(dev); | 7311 | ironlake_teardown_rc6(dev); |
7312 | mutex_unlock(&dev->struct_mutex); | ||
7309 | return; | 7313 | return; |
7310 | } | 7314 | } |
7311 | 7315 | ||
@@ -7323,6 +7327,7 @@ void ironlake_enable_rc6(struct drm_device *dev) | |||
7323 | 7327 | ||
7324 | I915_WRITE(PWRCTXA, dev_priv->pwrctx->gtt_offset | PWRCTX_EN); | 7328 | I915_WRITE(PWRCTXA, dev_priv->pwrctx->gtt_offset | PWRCTX_EN); |
7325 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); | 7329 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); |
7330 | mutex_unlock(&dev->struct_mutex); | ||
7326 | } | 7331 | } |
7327 | 7332 | ||
7328 | 7333 | ||