On Sun, May 29, 2011 at 5:16 AM, Dave Airlie <airlied at gmail.com> wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> We need to take a reference to this object, pinning doesn't take a reference
> so if userspace deletes the object it can disappear even if pinned.
>
> v2: fix error paths to unreference properly also.
>
> should fix:
> https://bugzilla.kernel.org/show_bug.cgi?id=32402
> and
> https://bugzilla.redhat.com/show_bug.cgi?id=680651
>

Thanks for tracking this down.

Acked-By: Alex Deucher <alexdeucher at gmail.com>

> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
> ?drivers/gpu/drm/radeon/radeon_display.c | ? 13 ++++++++-----
> ?1 files changed, 8 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_display.c 
> b/drivers/gpu/drm/radeon/radeon_display.c
> index ae247ee..292f73f 100644
> --- a/drivers/gpu/drm/radeon/radeon_display.c
> +++ b/drivers/gpu/drm/radeon/radeon_display.c
> @@ -264,6 +264,8 @@ static void radeon_unpin_work_func(struct work_struct 
> *__work)
> ? ? ? ? ? ? ? ?radeon_bo_unreserve(work->old_rbo);
> ? ? ? ?} else
> ? ? ? ? ? ? ? ?DRM_ERROR("failed to reserve buffer after flip\n");
> +
> + ? ? ? drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
> ? ? ? ?kfree(work);
> ?}
>
> @@ -371,6 +373,8 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
> ? ? ? ?new_radeon_fb = to_radeon_framebuffer(fb);
> ? ? ? ?/* schedule unpin of the old buffer */
> ? ? ? ?obj = old_radeon_fb->obj;
> + ? ? ? /* take a reference to the old object */
> + ? ? ? drm_gem_object_reference(obj);
> ? ? ? ?rbo = gem_to_radeon_bo(obj);
> ? ? ? ?work->old_rbo = rbo;
> ? ? ? ?INIT_WORK(&work->work, radeon_unpin_work_func);
> @@ -378,12 +382,9 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
> ? ? ? ?/* We borrow the event spin lock for protecting unpin_work */
> ? ? ? ?spin_lock_irqsave(&dev->event_lock, flags);
> ? ? ? ?if (radeon_crtc->unpin_work) {
> - ? ? ? ? ? ? ? spin_unlock_irqrestore(&dev->event_lock, flags);
> - ? ? ? ? ? ? ? kfree(work);
> - ? ? ? ? ? ? ? radeon_fence_unref(&fence);
> -
> ? ? ? ? ? ? ? ?DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
> - ? ? ? ? ? ? ? return -EBUSY;
> + ? ? ? ? ? ? ? r = -EBUSY;
> + ? ? ? ? ? ? ? goto unlock_free;
> ? ? ? ?}
> ? ? ? ?radeon_crtc->unpin_work = work;
> ? ? ? ?radeon_crtc->deferred_flip_completion = 0;
> @@ -497,6 +498,8 @@ pflip_cleanup1:
> ?pflip_cleanup:
> ? ? ? ?spin_lock_irqsave(&dev->event_lock, flags);
> ? ? ? ?radeon_crtc->unpin_work = NULL;
> +unlock_free:
> + ? ? ? drm_gem_object_unreference_unlocked(old_radeon_fb->obj);
> ? ? ? ?spin_unlock_irqrestore(&dev->event_lock, flags);
> ? ? ? ?radeon_fence_unref(&fence);
> ? ? ? ?kfree(work);
> --
> 1.7.4.4
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>

Reply via email to