Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c5488307 authored by Russell King's avatar Russell King
Browse files

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: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 0544e38d
Loading
Loading
Loading
Loading
+5 −8
Original line number Original line Diff line number Diff line
@@ -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;
	}
	}