[PATCH 4/6] drm: Introduce drm_framebuffer_{get,put}()
Sean Paul
seanpaul at chromium.org
Wed Feb 8 19:36:37 UTC 2017
On Wed, Feb 08, 2017 at 07:24:06PM +0100, Thierry Reding wrote:
> From: Thierry Reding <treding at nvidia.com>
>
> For consistency with other reference counting APIs in the kernel, add
> drm_framebuffer_get() and drm_framebuffer_put() to reference count DRM
> framebuffers.
>
> Compatibility aliases are added to keep existing code working. To help
> speed up the transition, all the instances of the old functions in the
> DRM core are already replaced in this commit.
>
> The existing semantic patch for the DRM subsystem-wide conversion is
> extended to account for these new helpers.
>
Reviewed-by: Sean Paul <seanpaul at chromium.org>
> Signed-off-by: Thierry Reding <treding at nvidia.com>
> ---
> drivers/gpu/drm/drm_atomic.c | 6 ++--
> drivers/gpu/drm/drm_atomic_helper.c | 4 +--
> drivers/gpu/drm/drm_crtc.c | 8 +++---
> drivers/gpu/drm/drm_framebuffer.c | 34 +++++++++++-----------
> drivers/gpu/drm/drm_plane.c | 12 ++++----
> include/drm/drm_framebuffer.h | 49 ++++++++++++++++++++++++--------
> scripts/coccinelle/api/drm-get-put.cocci | 10 +++++++
> 7 files changed, 79 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 82bad40b2f3e..740650b450c5 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -733,7 +733,7 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
> struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, val);
> drm_atomic_set_fb_for_plane(state, fb);
> if (fb)
> - drm_framebuffer_unreference(fb);
> + drm_framebuffer_put(fb);
> } else if (property == config->prop_in_fence_fd) {
> if (state->fence)
> return -EINVAL;
> @@ -1837,12 +1837,12 @@ void drm_atomic_clean_old_fb(struct drm_device *dev,
> if (ret == 0) {
> struct drm_framebuffer *new_fb = plane->state->fb;
> if (new_fb)
> - drm_framebuffer_reference(new_fb);
> + drm_framebuffer_get(new_fb);
> plane->fb = new_fb;
> plane->crtc = plane->state->crtc;
>
> if (plane->old_fb)
> - drm_framebuffer_unreference(plane->old_fb);
> + drm_framebuffer_put(plane->old_fb);
> }
> plane->old_fb = NULL;
> }
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 9f2c28ddf948..4dcd64ca34c8 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -3151,7 +3151,7 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
> memcpy(state, plane->state, sizeof(*state));
>
> if (state->fb)
> - drm_framebuffer_reference(state->fb);
> + drm_framebuffer_get(state->fb);
>
> state->fence = NULL;
> }
> @@ -3191,7 +3191,7 @@ EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state);
> void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
> {
> if (state->fb)
> - drm_framebuffer_unreference(state->fb);
> + drm_framebuffer_put(state->fb);
>
> if (state->fence)
> dma_fence_put(state->fence);
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index 9594c623799b..e2974d3c92e7 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -471,9 +471,9 @@ int drm_mode_set_config_internal(struct drm_mode_set *set)
>
> drm_for_each_crtc(tmp, crtc->dev) {
> if (tmp->primary->fb)
> - drm_framebuffer_reference(tmp->primary->fb);
> + drm_framebuffer_get(tmp->primary->fb);
> if (tmp->primary->old_fb)
> - drm_framebuffer_unreference(tmp->primary->old_fb);
> + drm_framebuffer_put(tmp->primary->old_fb);
> tmp->primary->old_fb = NULL;
> }
>
> @@ -567,7 +567,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
> }
> fb = crtc->primary->fb;
> /* Make refcounting symmetric with the lookup path. */
> - drm_framebuffer_reference(fb);
> + drm_framebuffer_get(fb);
> } else {
> fb = drm_framebuffer_lookup(dev, crtc_req->fb_id);
> if (!fb) {
> @@ -680,7 +680,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
>
> out:
> if (fb)
> - drm_framebuffer_unreference(fb);
> + drm_framebuffer_put(fb);
>
> if (connector_set) {
> for (i = 0; i < crtc_req->count_connectors; i++) {
> diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
> index 11daa24692aa..5e8e1d06866a 100644
> --- a/drivers/gpu/drm/drm_framebuffer.c
> +++ b/drivers/gpu/drm/drm_framebuffer.c
> @@ -52,13 +52,13 @@
> * metadata fields.
> *
> * The lifetime of a drm framebuffer is controlled with a reference count,
> - * drivers can grab additional references with drm_framebuffer_reference() and
> - * drop them again with drm_framebuffer_unreference(). For driver-private
> - * framebuffers for which the last reference is never dropped (e.g. for the
> - * fbdev framebuffer when the struct &struct drm_framebuffer is embedded into
> - * the fbdev helper struct) drivers can manually clean up a framebuffer at
> - * module unload time with drm_framebuffer_unregister_private(). But doing this
> - * is not recommended, and it's better to have a normal free-standing &struct
> + * drivers can grab additional references with drm_framebuffer_get() and drop
> + * them again with drm_framebuffer_put(). For driver-private framebuffers for
> + * which the last reference is never dropped (e.g. for the fbdev framebuffer
> + * when the struct &struct drm_framebuffer is embedded into the fbdev helper
> + * struct) drivers can manually clean up a framebuffer at module unload time
> + * with drm_framebuffer_unregister_private(). But doing this is not
> + * recommended, and it's better to have a normal free-standing &struct
> * drm_framebuffer.
> */
>
> @@ -374,7 +374,7 @@ int drm_mode_rmfb(struct drm_device *dev,
> mutex_unlock(&file_priv->fbs_lock);
>
> /* drop the reference we picked up in framebuffer lookup */
> - drm_framebuffer_unreference(fb);
> + drm_framebuffer_put(fb);
>
> /*
> * we now own the reference that was stored in the fbs list
> @@ -394,12 +394,12 @@ int drm_mode_rmfb(struct drm_device *dev,
> flush_work(&arg.work);
> destroy_work_on_stack(&arg.work);
> } else
> - drm_framebuffer_unreference(fb);
> + drm_framebuffer_put(fb);
>
> return 0;
>
> fail_unref:
> - drm_framebuffer_unreference(fb);
> + drm_framebuffer_put(fb);
> return -ENOENT;
> }
>
> @@ -453,7 +453,7 @@ int drm_mode_getfb(struct drm_device *dev,
> ret = -ENODEV;
> }
>
> - drm_framebuffer_unreference(fb);
> + drm_framebuffer_put(fb);
>
> return ret;
> }
> @@ -540,7 +540,7 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
> out_err2:
> kfree(clips);
> out_err1:
> - drm_framebuffer_unreference(fb);
> + drm_framebuffer_put(fb);
>
> return ret;
> }
> @@ -580,7 +580,7 @@ void drm_fb_release(struct drm_file *priv)
> list_del_init(&fb->filp_head);
>
> /* This drops the fpriv->fbs reference. */
> - drm_framebuffer_unreference(fb);
> + drm_framebuffer_put(fb);
> }
> }
>
> @@ -661,7 +661,7 @@ EXPORT_SYMBOL(drm_framebuffer_init);
> *
> * If successful, this grabs an additional reference to the framebuffer -
> * callers need to make sure to eventually unreference the returned framebuffer
> - * again, using @drm_framebuffer_unreference.
> + * again, using drm_framebuffer_put().
> */
> struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
> uint32_t id)
> @@ -687,8 +687,8 @@ EXPORT_SYMBOL(drm_framebuffer_lookup);
> *
> * NOTE: This function is deprecated. For driver-private framebuffers it is not
> * recommended to embed a framebuffer struct info fbdev struct, instead, a
> - * framebuffer pointer is preferred and drm_framebuffer_unreference() should be
> - * called when the framebuffer is to be cleaned up.
> + * framebuffer pointer is preferred and drm_framebuffer_put() should be called
> + * when the framebuffer is to be cleaned up.
> */
> void drm_framebuffer_unregister_private(struct drm_framebuffer *fb)
> {
> @@ -790,7 +790,7 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb)
> drm_modeset_unlock_all(dev);
> }
>
> - drm_framebuffer_unreference(fb);
> + drm_framebuffer_put(fb);
> }
> EXPORT_SYMBOL(drm_framebuffer_remove);
>
> diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
> index f42590049a3a..a22e76837065 100644
> --- a/drivers/gpu/drm/drm_plane.c
> +++ b/drivers/gpu/drm/drm_plane.c
> @@ -293,7 +293,7 @@ void drm_plane_force_disable(struct drm_plane *plane)
> return;
> }
> /* disconnect the plane from the fb and crtc: */
> - drm_framebuffer_unreference(plane->old_fb);
> + drm_framebuffer_put(plane->old_fb);
> plane->old_fb = NULL;
> plane->fb = NULL;
> plane->crtc = NULL;
> @@ -520,9 +520,9 @@ static int __setplane_internal(struct drm_plane *plane,
>
> out:
> if (fb)
> - drm_framebuffer_unreference(fb);
> + drm_framebuffer_put(fb);
> if (plane->old_fb)
> - drm_framebuffer_unreference(plane->old_fb);
> + drm_framebuffer_put(plane->old_fb);
> plane->old_fb = NULL;
>
> return ret;
> @@ -638,7 +638,7 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc,
> } else {
> fb = crtc->cursor->fb;
> if (fb)
> - drm_framebuffer_reference(fb);
> + drm_framebuffer_get(fb);
> }
>
> if (req->flags & DRM_MODE_CURSOR_MOVE) {
> @@ -902,9 +902,9 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
> if (ret && crtc->funcs->page_flip_target)
> drm_crtc_vblank_put(crtc);
> if (fb)
> - drm_framebuffer_unreference(fb);
> + drm_framebuffer_put(fb);
> if (crtc->primary->old_fb)
> - drm_framebuffer_unreference(crtc->primary->old_fb);
> + drm_framebuffer_put(crtc->primary->old_fb);
> crtc->primary->old_fb = NULL;
> drm_modeset_unlock_crtc(crtc);
>
> diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h
> index dd1e3e99dcff..5244f059d23a 100644
> --- a/include/drm/drm_framebuffer.h
> +++ b/include/drm/drm_framebuffer.h
> @@ -101,8 +101,8 @@ struct drm_framebuffer_funcs {
> * cleanup (like releasing the reference(s) on the backing GEM bo(s))
> * should be deferred. In cases like this, the driver would like to
> * hold a ref to the fb even though it has already been removed from
> - * userspace perspective. See drm_framebuffer_reference() and
> - * drm_framebuffer_unreference().
> + * userspace perspective. See drm_framebuffer_get() and
> + * drm_framebuffer_put().
> *
> * The refcount is stored inside the mode object @base.
> */
> @@ -204,25 +204,50 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb);
> void drm_framebuffer_unregister_private(struct drm_framebuffer *fb);
>
> /**
> - * drm_framebuffer_reference - incr the fb refcnt
> - * @fb: framebuffer
> + * drm_framebuffer_get - acquire a framebuffer reference
> + * @fb: DRM framebuffer
> + *
> + * This function increments the framebuffer's reference count.
> + */
> +static inline void drm_framebuffer_get(struct drm_framebuffer *fb)
> +{
> + drm_mode_object_get(&fb->base);
> +}
> +
> +/**
> + * drm_framebuffer_put - release a framebuffer reference
> + * @fb: DRM framebuffer
> + *
> + * This function decrements the framebuffer's reference count and frees the
> + * framebuffer if the reference count drops to zero.
> + */
> +static inline void drm_framebuffer_put(struct drm_framebuffer *fb)
> +{
> + drm_mode_object_put(&fb->base);
> +}
> +
> +/**
> + * drm_framebuffer_reference - acquire a framebuffer reference
> + * @fb: DRM framebuffer
> *
> - * This functions increments the fb's refcount.
> + * This is a compatibility alias for drm_framebuffer_get() and should not be
> + * used by new code.
> */
> static inline void drm_framebuffer_reference(struct drm_framebuffer *fb)
> {
> - drm_mode_object_reference(&fb->base);
> + drm_framebuffer_get(fb);
> }
>
> /**
> - * drm_framebuffer_unreference - unref a framebuffer
> - * @fb: framebuffer to unref
> + * drm_framebuffer_unreference - release a framebuffer reference
> + * @fb: DRM framebuffer
> *
> - * This functions decrements the fb's refcount and frees it if it drops to zero.
> + * This is a compatibility alias for drm_framebuffer_put() and should not be
> + * used by new code.
> */
> static inline void drm_framebuffer_unreference(struct drm_framebuffer *fb)
> {
> - drm_mode_object_unreference(&fb->base);
> + drm_framebuffer_put(fb);
> }
>
> /**
> @@ -248,9 +273,9 @@ static inline void drm_framebuffer_assign(struct drm_framebuffer **p,
> struct drm_framebuffer *fb)
> {
> if (fb)
> - drm_framebuffer_reference(fb);
> + drm_framebuffer_get(fb);
> if (*p)
> - drm_framebuffer_unreference(*p);
> + drm_framebuffer_put(*p);
> *p = fb;
> }
>
> diff --git a/scripts/coccinelle/api/drm-get-put.cocci b/scripts/coccinelle/api/drm-get-put.cocci
> index 8a4c2cb7889e..fd298c24a465 100644
> --- a/scripts/coccinelle/api/drm-get-put.cocci
> +++ b/scripts/coccinelle/api/drm-get-put.cocci
> @@ -26,6 +26,12 @@ expression object;
> |
> - drm_connector_unreference(object)
> + drm_connector_put(object)
> +|
> +- drm_framebuffer_reference(object)
> ++ drm_framebuffer_get(object)
> +|
> +- drm_framebuffer_unreference(object)
> ++ drm_framebuffer_put(object)
> )
>
> @r depends on report@
> @@ -41,6 +47,10 @@ drm_mode_object_reference at p(object)
> drm_connector_unreference at p(object)
> |
> drm_connector_reference at p(object)
> +|
> +drm_framebuffer_unreference at p(object)
> +|
> +drm_framebuffer_reference at p(object)
> )
>
> @script:python depends on report@
> --
> 2.11.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
--
Sean Paul, Software Engineer, Google / Chromium OS
More information about the dri-devel
mailing list