Commit a4a69da0 authored by Thierry Reding's avatar Thierry Reding

drm: Introduce drm_framebuffer_{get,put}()

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: default avatarSean Paul <seanpaul@chromium.org>
Acked-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170228144643.5668-5-thierry.reding@gmail.com
parent ad093607
...@@ -737,7 +737,7 @@ int drm_atomic_plane_set_property(struct drm_plane *plane, ...@@ -737,7 +737,7 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, val); struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, val);
drm_atomic_set_fb_for_plane(state, fb); drm_atomic_set_fb_for_plane(state, fb);
if (fb) if (fb)
drm_framebuffer_unreference(fb); drm_framebuffer_put(fb);
} else if (property == config->prop_in_fence_fd) { } else if (property == config->prop_in_fence_fd) {
if (state->fence) if (state->fence)
return -EINVAL; return -EINVAL;
...@@ -1865,12 +1865,12 @@ void drm_atomic_clean_old_fb(struct drm_device *dev, ...@@ -1865,12 +1865,12 @@ void drm_atomic_clean_old_fb(struct drm_device *dev,
if (ret == 0) { if (ret == 0) {
struct drm_framebuffer *new_fb = plane->state->fb; struct drm_framebuffer *new_fb = plane->state->fb;
if (new_fb) if (new_fb)
drm_framebuffer_reference(new_fb); drm_framebuffer_get(new_fb);
plane->fb = new_fb; plane->fb = new_fb;
plane->crtc = plane->state->crtc; plane->crtc = plane->state->crtc;
if (plane->old_fb) if (plane->old_fb)
drm_framebuffer_unreference(plane->old_fb); drm_framebuffer_put(plane->old_fb);
} }
plane->old_fb = NULL; plane->old_fb = NULL;
} }
......
...@@ -3230,7 +3230,7 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, ...@@ -3230,7 +3230,7 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
memcpy(state, plane->state, sizeof(*state)); memcpy(state, plane->state, sizeof(*state));
if (state->fb) if (state->fb)
drm_framebuffer_reference(state->fb); drm_framebuffer_get(state->fb);
state->fence = NULL; state->fence = NULL;
} }
...@@ -3270,7 +3270,7 @@ EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state); ...@@ -3270,7 +3270,7 @@ EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state);
void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state) void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
{ {
if (state->fb) if (state->fb)
drm_framebuffer_unreference(state->fb); drm_framebuffer_put(state->fb);
if (state->fence) if (state->fence)
dma_fence_put(state->fence); dma_fence_put(state->fence);
......
...@@ -471,9 +471,9 @@ int drm_mode_set_config_internal(struct drm_mode_set *set) ...@@ -471,9 +471,9 @@ int drm_mode_set_config_internal(struct drm_mode_set *set)
drm_for_each_crtc(tmp, crtc->dev) { drm_for_each_crtc(tmp, crtc->dev) {
if (tmp->primary->fb) if (tmp->primary->fb)
drm_framebuffer_reference(tmp->primary->fb); drm_framebuffer_get(tmp->primary->fb);
if (tmp->primary->old_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; tmp->primary->old_fb = NULL;
} }
...@@ -567,7 +567,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, ...@@ -567,7 +567,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
} }
fb = crtc->primary->fb; fb = crtc->primary->fb;
/* Make refcounting symmetric with the lookup path. */ /* Make refcounting symmetric with the lookup path. */
drm_framebuffer_reference(fb); drm_framebuffer_get(fb);
} else { } else {
fb = drm_framebuffer_lookup(dev, crtc_req->fb_id); fb = drm_framebuffer_lookup(dev, crtc_req->fb_id);
if (!fb) { if (!fb) {
...@@ -680,7 +680,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, ...@@ -680,7 +680,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
out: out:
if (fb) if (fb)
drm_framebuffer_unreference(fb); drm_framebuffer_put(fb);
if (connector_set) { if (connector_set) {
for (i = 0; i < crtc_req->count_connectors; i++) { for (i = 0; i < crtc_req->count_connectors; i++) {
......
...@@ -52,13 +52,13 @@ ...@@ -52,13 +52,13 @@
* metadata fields. * metadata fields.
* *
* The lifetime of a drm framebuffer is controlled with a reference count, * The lifetime of a drm framebuffer is controlled with a reference count,
* drivers can grab additional references with drm_framebuffer_reference() and * drivers can grab additional references with drm_framebuffer_get() and drop
* drop them again with drm_framebuffer_unreference(). For driver-private * them again with drm_framebuffer_put(). For driver-private framebuffers for
* framebuffers for which the last reference is never dropped (e.g. for the * which the last reference is never dropped (e.g. for the fbdev framebuffer
* fbdev framebuffer when the struct &struct drm_framebuffer is embedded into * when the struct &struct drm_framebuffer is embedded into the fbdev helper
* the fbdev helper struct) drivers can manually clean up a framebuffer at * struct) drivers can manually clean up a framebuffer at module unload time
* module unload time with drm_framebuffer_unregister_private(). But doing this * with drm_framebuffer_unregister_private(). But doing this is not
* is not recommended, and it's better to have a normal free-standing &struct * recommended, and it's better to have a normal free-standing &struct
* drm_framebuffer. * drm_framebuffer.
*/ */
...@@ -374,7 +374,7 @@ int drm_mode_rmfb(struct drm_device *dev, ...@@ -374,7 +374,7 @@ int drm_mode_rmfb(struct drm_device *dev,
mutex_unlock(&file_priv->fbs_lock); mutex_unlock(&file_priv->fbs_lock);
/* drop the reference we picked up in framebuffer lookup */ /* 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 * we now own the reference that was stored in the fbs list
...@@ -394,12 +394,12 @@ int drm_mode_rmfb(struct drm_device *dev, ...@@ -394,12 +394,12 @@ int drm_mode_rmfb(struct drm_device *dev,
flush_work(&arg.work); flush_work(&arg.work);
destroy_work_on_stack(&arg.work); destroy_work_on_stack(&arg.work);
} else } else
drm_framebuffer_unreference(fb); drm_framebuffer_put(fb);
return 0; return 0;
fail_unref: fail_unref:
drm_framebuffer_unreference(fb); drm_framebuffer_put(fb);
return -ENOENT; return -ENOENT;
} }
...@@ -453,7 +453,7 @@ int drm_mode_getfb(struct drm_device *dev, ...@@ -453,7 +453,7 @@ int drm_mode_getfb(struct drm_device *dev,
ret = -ENODEV; ret = -ENODEV;
} }
drm_framebuffer_unreference(fb); drm_framebuffer_put(fb);
return ret; return ret;
} }
...@@ -540,7 +540,7 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev, ...@@ -540,7 +540,7 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
out_err2: out_err2:
kfree(clips); kfree(clips);
out_err1: out_err1:
drm_framebuffer_unreference(fb); drm_framebuffer_put(fb);
return ret; return ret;
} }
...@@ -580,7 +580,7 @@ void drm_fb_release(struct drm_file *priv) ...@@ -580,7 +580,7 @@ void drm_fb_release(struct drm_file *priv)
list_del_init(&fb->filp_head); list_del_init(&fb->filp_head);
/* This drops the fpriv->fbs reference. */ /* This drops the fpriv->fbs reference. */
drm_framebuffer_unreference(fb); drm_framebuffer_put(fb);
} }
} }
...@@ -661,7 +661,7 @@ EXPORT_SYMBOL(drm_framebuffer_init); ...@@ -661,7 +661,7 @@ EXPORT_SYMBOL(drm_framebuffer_init);
* *
* If successful, this grabs an additional reference to the framebuffer - * If successful, this grabs an additional reference to the framebuffer -
* callers need to make sure to eventually unreference the returned 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, struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
uint32_t id) uint32_t id)
...@@ -687,8 +687,8 @@ EXPORT_SYMBOL(drm_framebuffer_lookup); ...@@ -687,8 +687,8 @@ EXPORT_SYMBOL(drm_framebuffer_lookup);
* *
* NOTE: This function is deprecated. For driver-private framebuffers it is not * NOTE: This function is deprecated. For driver-private framebuffers it is not
* recommended to embed a framebuffer struct info fbdev struct, instead, a * recommended to embed a framebuffer struct info fbdev struct, instead, a
* framebuffer pointer is preferred and drm_framebuffer_unreference() should be * framebuffer pointer is preferred and drm_framebuffer_put() should be called
* called when the framebuffer is to be cleaned up. * when the framebuffer is to be cleaned up.
*/ */
void drm_framebuffer_unregister_private(struct drm_framebuffer *fb) void drm_framebuffer_unregister_private(struct drm_framebuffer *fb)
{ {
...@@ -797,7 +797,7 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb) ...@@ -797,7 +797,7 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb)
} }
out: out:
drm_framebuffer_unreference(fb); drm_framebuffer_put(fb);
} }
EXPORT_SYMBOL(drm_framebuffer_remove); EXPORT_SYMBOL(drm_framebuffer_remove);
......
...@@ -293,7 +293,7 @@ void drm_plane_force_disable(struct drm_plane *plane) ...@@ -293,7 +293,7 @@ void drm_plane_force_disable(struct drm_plane *plane)
return; return;
} }
/* disconnect the plane from the fb and crtc: */ /* 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->old_fb = NULL;
plane->fb = NULL; plane->fb = NULL;
plane->crtc = NULL; plane->crtc = NULL;
...@@ -520,9 +520,9 @@ static int __setplane_internal(struct drm_plane *plane, ...@@ -520,9 +520,9 @@ static int __setplane_internal(struct drm_plane *plane,
out: out:
if (fb) if (fb)
drm_framebuffer_unreference(fb); drm_framebuffer_put(fb);
if (plane->old_fb) if (plane->old_fb)
drm_framebuffer_unreference(plane->old_fb); drm_framebuffer_put(plane->old_fb);
plane->old_fb = NULL; plane->old_fb = NULL;
return ret; return ret;
...@@ -638,7 +638,7 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc, ...@@ -638,7 +638,7 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc,
} else { } else {
fb = crtc->cursor->fb; fb = crtc->cursor->fb;
if (fb) if (fb)
drm_framebuffer_reference(fb); drm_framebuffer_get(fb);
} }
if (req->flags & DRM_MODE_CURSOR_MOVE) { if (req->flags & DRM_MODE_CURSOR_MOVE) {
...@@ -902,9 +902,9 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, ...@@ -902,9 +902,9 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
if (ret && crtc->funcs->page_flip_target) if (ret && crtc->funcs->page_flip_target)
drm_crtc_vblank_put(crtc); drm_crtc_vblank_put(crtc);
if (fb) if (fb)
drm_framebuffer_unreference(fb); drm_framebuffer_put(fb);
if (crtc->primary->old_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; crtc->primary->old_fb = NULL;
drm_modeset_unlock_crtc(crtc); drm_modeset_unlock_crtc(crtc);
......
...@@ -101,8 +101,8 @@ struct drm_framebuffer_funcs { ...@@ -101,8 +101,8 @@ struct drm_framebuffer_funcs {
* cleanup (like releasing the reference(s) on the backing GEM bo(s)) * cleanup (like releasing the reference(s) on the backing GEM bo(s))
* should be deferred. In cases like this, the driver would like to * 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 * hold a ref to the fb even though it has already been removed from
* userspace perspective. See drm_framebuffer_reference() and * userspace perspective. See drm_framebuffer_get() and
* drm_framebuffer_unreference(). * drm_framebuffer_put().
* *
* The refcount is stored inside the mode object @base. * The refcount is stored inside the mode object @base.
*/ */
...@@ -204,25 +204,50 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb); ...@@ -204,25 +204,50 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb);
void drm_framebuffer_unregister_private(struct drm_framebuffer *fb); void drm_framebuffer_unregister_private(struct drm_framebuffer *fb);
/** /**
* drm_framebuffer_reference - incr the fb refcnt * drm_framebuffer_get - acquire a framebuffer reference
* @fb: framebuffer * @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) 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 * drm_framebuffer_unreference - release a framebuffer reference
* @fb: framebuffer to unref * @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) 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, ...@@ -248,9 +273,9 @@ static inline void drm_framebuffer_assign(struct drm_framebuffer **p,
struct drm_framebuffer *fb) struct drm_framebuffer *fb)
{ {
if (fb) if (fb)
drm_framebuffer_reference(fb); drm_framebuffer_get(fb);
if (*p) if (*p)
drm_framebuffer_unreference(*p); drm_framebuffer_put(*p);
*p = fb; *p = fb;
} }
......
...@@ -26,6 +26,12 @@ expression object; ...@@ -26,6 +26,12 @@ expression object;
| |
- drm_connector_unreference(object) - drm_connector_unreference(object)
+ drm_connector_put(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@ @r depends on report@
...@@ -41,6 +47,10 @@ drm_mode_object_reference@p(object) ...@@ -41,6 +47,10 @@ drm_mode_object_reference@p(object)
drm_connector_unreference@p(object) drm_connector_unreference@p(object)
| |
drm_connector_reference@p(object) drm_connector_reference@p(object)
|
drm_framebuffer_unreference@p(object)
|
drm_framebuffer_reference@p(object)
) )
@script:python depends on report@ @script:python depends on report@
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment