提交 468f0b44 编写于 作者: C Chris Wilson 提交者: Eric Anholt

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: NChris Wilson <chris@chris-wilson.co.uk>
Cc: Jesse Barnes <jbarnes@virtuousgeek.org>
Cc: Kristian Høgsberg <krh@bitplanet.net>
Reviewed-by: NJesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: NEric Anholt <eric@anholt.net>
上级 35aed2e6
...@@ -4667,8 +4667,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, ...@@ -4667,8 +4667,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
if (work == NULL) if (work == NULL)
return -ENOMEM; return -ENOMEM;
mutex_lock(&dev->struct_mutex);
work->event = event; work->event = event;
work->dev = crtc->dev; work->dev = crtc->dev;
intel_fb = to_intel_framebuffer(crtc->fb); intel_fb = to_intel_framebuffer(crtc->fb);
...@@ -4678,10 +4676,10 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, ...@@ -4678,10 +4676,10 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
/* We borrow the event spin lock for protecting unpin_work */ /* We borrow the event spin lock for protecting unpin_work */
spin_lock_irqsave(&dev->event_lock, flags); spin_lock_irqsave(&dev->event_lock, flags);
if (intel_crtc->unpin_work) { if (intel_crtc->unpin_work) {
DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
spin_unlock_irqrestore(&dev->event_lock, flags); spin_unlock_irqrestore(&dev->event_lock, flags);
kfree(work); kfree(work);
mutex_unlock(&dev->struct_mutex);
DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
return -EBUSY; return -EBUSY;
} }
intel_crtc->unpin_work = work; intel_crtc->unpin_work = work;
...@@ -4690,13 +4688,19 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, ...@@ -4690,13 +4688,19 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
intel_fb = to_intel_framebuffer(fb); intel_fb = to_intel_framebuffer(fb);
obj = intel_fb->obj; obj = intel_fb->obj;
mutex_lock(&dev->struct_mutex);
ret = intel_pin_and_fence_fb_obj(dev, obj); ret = intel_pin_and_fence_fb_obj(dev, obj);
if (ret != 0) { if (ret != 0) {
DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n",
to_intel_bo(obj));
kfree(work);
intel_crtc->unpin_work = NULL;
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
spin_lock_irqsave(&dev->event_lock, flags);
intel_crtc->unpin_work = NULL;
spin_unlock_irqrestore(&dev->event_lock, flags);
kfree(work);
DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n",
to_intel_bo(obj));
return ret; return ret;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册