aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArchit Taneja <archit@ti.com>2013-04-09 08:26:00 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2013-04-11 06:25:57 -0400
commitb03e14fd4b9f91d0c6be864bf62c75933fa26cac (patch)
treeea5e01fc30a6470eeab374bf310d8ea824813f19
parentbddabbe174cfb6f944baaf13ed5b93c6ee89ec3d (diff)
drm/omap: Take a fb reference in omap_plane_update()
When userspace calls SET_PLANE ioctl, drm core takes a reference of the fb and passes control to the update_plane op defined by the drm driver. In omapdrm, we have a worker thread which queues framebuffers objects received from update_plane and displays them at the appropriate time. It is possible that the framebuffer is destoryed by userspace between the time of calling the ioctl and apply-worker being scheduled. If this happens, the apply-worker holds a pointer to a framebuffer which is already destroyed. Take an extra refernece/unreference of the fb in omap_plane_update() to prevent this from happening. A reference is taken of the fb passed to update_plane(), the previous framebuffer (held by plane->fb) is unreferenced. This will prevent drm from destroying the framebuffer till the time it's unreferenced by the apply-worker. This is in addition to the exisitng reference/unreference in update_pin(), which is taken for the scanout of the plane's current framebuffer, and an unreference the previous framebuffer. Signed-off-by: Archit Taneja <archit@ti.com> Reviewed-by: Rob Clark <robdclark@gmail.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
-rw-r--r--drivers/gpu/drm/omapdrm/omap_plane.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 2882cda6ea19..8d225d7ff4e3 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -247,6 +247,12 @@ static int omap_plane_update(struct drm_plane *plane,
247{ 247{
248 struct omap_plane *omap_plane = to_omap_plane(plane); 248 struct omap_plane *omap_plane = to_omap_plane(plane);
249 omap_plane->enabled = true; 249 omap_plane->enabled = true;
250
251 if (plane->fb)
252 drm_framebuffer_unreference(plane->fb);
253
254 drm_framebuffer_reference(fb);
255
250 return omap_plane_mode_set(plane, crtc, fb, 256 return omap_plane_mode_set(plane, crtc, fb,
251 crtc_x, crtc_y, crtc_w, crtc_h, 257 crtc_x, crtc_y, crtc_w, crtc_h,
252 src_x, src_y, src_w, src_h, 258 src_x, src_y, src_w, src_h,