diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-05-27 08:18:13 -0400 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2010-05-28 13:40:27 -0400 |
commit | 468f0b44ce4b002ca7d9260f802a341854752c02 (patch) | |
tree | 43ab02a3949035fca6d169aa3b10cf6e836455ab /drivers/gpu/drm/i915/intel_display.c | |
parent | 35aed2e6be2feaa227fe5c7a0b7c286c4fe71592 (diff) |
drm/i915: Hold the spinlock whilst resetting unpin_work along error path
Delay taking the mutex until we need to and ensure that we hold the
spinlock when resetting unpin_work on the error path. Also defer the
debugging print messages until after we have released the spinlock.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Jesse Barnes <jbarnes@virtuousgeek.org>
Cc: Kristian Høgsberg <krh@bitplanet.net>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cfac4dd1d483..1845a068cca5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -4667,8 +4667,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
4667 | if (work == NULL) | 4667 | if (work == NULL) |
4668 | return -ENOMEM; | 4668 | return -ENOMEM; |
4669 | 4669 | ||
4670 | mutex_lock(&dev->struct_mutex); | ||
4671 | |||
4672 | work->event = event; | 4670 | work->event = event; |
4673 | work->dev = crtc->dev; | 4671 | work->dev = crtc->dev; |
4674 | intel_fb = to_intel_framebuffer(crtc->fb); | 4672 | intel_fb = to_intel_framebuffer(crtc->fb); |
@@ -4678,10 +4676,10 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
4678 | /* We borrow the event spin lock for protecting unpin_work */ | 4676 | /* We borrow the event spin lock for protecting unpin_work */ |
4679 | spin_lock_irqsave(&dev->event_lock, flags); | 4677 | spin_lock_irqsave(&dev->event_lock, flags); |
4680 | if (intel_crtc->unpin_work) { | 4678 | if (intel_crtc->unpin_work) { |
4681 | DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); | ||
4682 | spin_unlock_irqrestore(&dev->event_lock, flags); | 4679 | spin_unlock_irqrestore(&dev->event_lock, flags); |
4683 | kfree(work); | 4680 | kfree(work); |
4684 | mutex_unlock(&dev->struct_mutex); | 4681 | |
4682 | DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); | ||
4685 | return -EBUSY; | 4683 | return -EBUSY; |
4686 | } | 4684 | } |
4687 | intel_crtc->unpin_work = work; | 4685 | intel_crtc->unpin_work = work; |
@@ -4690,13 +4688,19 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
4690 | intel_fb = to_intel_framebuffer(fb); | 4688 | intel_fb = to_intel_framebuffer(fb); |
4691 | obj = intel_fb->obj; | 4689 | obj = intel_fb->obj; |
4692 | 4690 | ||
4691 | mutex_lock(&dev->struct_mutex); | ||
4693 | ret = intel_pin_and_fence_fb_obj(dev, obj); | 4692 | ret = intel_pin_and_fence_fb_obj(dev, obj); |
4694 | if (ret != 0) { | 4693 | if (ret != 0) { |
4695 | DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n", | ||
4696 | to_intel_bo(obj)); | ||
4697 | kfree(work); | ||
4698 | intel_crtc->unpin_work = NULL; | ||
4699 | mutex_unlock(&dev->struct_mutex); | 4694 | mutex_unlock(&dev->struct_mutex); |
4695 | |||
4696 | spin_lock_irqsave(&dev->event_lock, flags); | ||
4697 | intel_crtc->unpin_work = NULL; | ||
4698 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
4699 | |||
4700 | kfree(work); | ||
4701 | |||
4702 | DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n", | ||
4703 | to_intel_bo(obj)); | ||
4700 | return ret; | 4704 | return ret; |
4701 | } | 4705 | } |
4702 | 4706 | ||