Skip to content

Commit

Permalink
drm/armada: fix page_flip refcounting leak
Browse files Browse the repository at this point in the history
A refcounting leak was found of the original frame buffer attached to
the CRTC when using the page_flip ioctl, resulting in the frame buffer
never being freed.

This was not obvious initially, as if the page flip subsequently
re-attaches the original frame buffer, the refcounts will be balanced.
However, if the original frame buffer is freed, then it will be leaked.

Fix this by ensuring that we take a reference on the incoming fb, but
rely on the queued work to drop that ref count.

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Russell King committed Oct 17, 2014
1 parent 0544e38 commit c548830
Showing 1 changed file with 5 additions and 8 deletions.
13 changes: 5 additions & 8 deletions drivers/gpu/drm/armada/armada_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -945,18 +945,15 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
armada_reg_queue_end(work->regs, i);

/*
* Hold the old framebuffer for the work - DRM appears to drop our
* reference to the old framebuffer in drm_mode_page_flip_ioctl().
* Ensure that we hold a reference on the new framebuffer.
* This has to match the behaviour in mode_set.
*/
drm_framebuffer_reference(work->old_fb);
drm_framebuffer_reference(fb);

ret = armada_drm_crtc_queue_frame_work(dcrtc, work);
if (ret) {
/*
* Undo our reference above; DRM does not drop the reference
* to this object on error, so that's okay.
*/
drm_framebuffer_unreference(work->old_fb);
/* Undo our reference above */
drm_framebuffer_unreference(fb);
kfree(work);
return ret;
}
Expand Down

0 comments on commit c548830

Please sign in to comment.