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 >