drm/armada: fix page_flip refcounting leak
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>
This commit is contained in:
parent
0544e38d5a
commit
c5488307dd
@ -945,18 +945,15 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
|
|||||||
armada_reg_queue_end(work->regs, i);
|
armada_reg_queue_end(work->regs, i);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hold the old framebuffer for the work - DRM appears to drop our
|
* Ensure that we hold a reference on the new framebuffer.
|
||||||
* reference to the old framebuffer in drm_mode_page_flip_ioctl().
|
* 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);
|
ret = armada_drm_crtc_queue_frame_work(dcrtc, work);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
/*
|
/* Undo our reference above */
|
||||||
* Undo our reference above; DRM does not drop the reference
|
drm_framebuffer_unreference(fb);
|
||||||
* to this object on error, so that's okay.
|
|
||||||
*/
|
|
||||||
drm_framebuffer_unreference(work->old_fb);
|
|
||||||
kfree(work);
|
kfree(work);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user