From 321ebf04dc7ab5c54d658f93db0ffe35277664ab Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 4 Nov 2014 22:57:27 +0100 Subject: drm/atomic: Refcounting for plane_state->fb So my original plan was that the drm core refcounts framebuffers like with the legacy ioctls. But that doesn't work for a bunch of reasons: - State objects might live longer than until the next fb change happens for a plane. For example delayed cleanup work only happens _after_ the pageflip ioctl has completed. So this definitely doesn't work without the plane state holding its own references. - The other issue is transition from legacy to atomic implementations, where the driver works under a mix of both worlds. Which means legacy paths might not properly update the ->fb pointer under plane->state->fb. Which is a bit a problem when then someone comes around and _does_ try to clean it up when it's long gone. The second issue is just a bit a transition bug, since drivers should update plane->state->fb in all the paths that aren't converted yet. But a bit more robustness for the transition can't hurt - we pull similar tricks with cleaning up the old fb in the transitional helpers already. The pattern for drivers that transition is if (plane->state) drm_atomic_set_fb_for_plane(plane->state, plane->fb); inserted after the fb update has logically completed at the end of ->set_config (or ->set_base/mode_set if using the crtc helpers), ->page_flip, ->update_plane or any other entry point which updates plane->fb. v2: Update kerneldoc - copypasta fail. v3: Fix spelling in the commit message (Sean). Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc_helper.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/drm_crtc_helper.c') diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 33195e9adaab..d552708409de 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -34,11 +34,13 @@ #include #include +#include #include #include #include #include #include +#include #include /** @@ -998,15 +1000,14 @@ int drm_helper_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, if (plane->funcs->atomic_duplicate_state) plane_state = plane->funcs->atomic_duplicate_state(plane); else if (plane->state) - plane_state = kmemdup(plane->state, sizeof(*plane_state), - GFP_KERNEL); + plane_state = drm_atomic_helper_plane_duplicate_state(plane); else plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL); if (!plane_state) return -ENOMEM; plane_state->crtc = crtc; - plane_state->fb = crtc->primary->fb; + drm_atomic_set_fb_for_plane(plane_state, crtc->primary->fb); plane_state->crtc_x = 0; plane_state->crtc_y = 0; plane_state->crtc_h = crtc->mode.vdisplay; -- cgit v1.2.3