[PATCH 09/15] drm/modes: move reference taking into object lookup.

Daniel Vetter daniel at ffwll.ch
Thu Apr 21 09:05:20 UTC 2016


On Fri, Apr 15, 2016 at 03:10:40PM +1000, Dave Airlie wrote:
> From: Dave Airlie <airlied at redhat.com>
> 
> When we lookup an ref counted object we now take a proper reference
> using kref_get_unless_zero.
> 
> Framebuffer lookup no longer needs do this itself.
> 
> Convert rmfb to using framebuffer lookup and deal with the fact
> it now gets an extra reference that we have to cleanup. This should
> mean we can avoid holding fb_lock across rmfb. (if I'm wrong let me
> know).
> 
> We also now only hold the fbs_lock around the list manipulation.
> 
> Signed-off-by: Dave Airlie <airlied at redhat.com>

Needs the same comment as patch 7 added to the commit message:

"Previously fb refcounting, and especially the weak reference
(kref_get_unless_zero) used in fb lookups have been protected by fb_lock.
But with the refactoring to share refcounting in the drm_mode_object base
class that switched to being protected by idr_mutex, which means fb_lock
critical sections can be reduced."

With that: Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>

> ---
>  drivers/gpu/drm/drm_crtc.c | 37 ++++++++++++++++++++-----------------
>  1 file changed, 20 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index 21cb998..e47c4a2 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -364,6 +364,11 @@ static struct drm_mode_object *_object_find(struct drm_device *dev,
>  	if (obj &&
>  	    obj->type == DRM_MODE_OBJECT_BLOB)
>  		obj = NULL;
> +
> +	if (obj && obj->free_cb) {
> +		if (!kref_get_unless_zero(&obj->refcount))
> +			obj = NULL;
> +	}
>  	mutex_unlock(&dev->mode_config.idr_mutex);
>  
>  	return obj;
> @@ -495,11 +500,8 @@ struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
>  
>  	mutex_lock(&dev->mode_config.fb_lock);
>  	obj = _object_find(dev, id, DRM_MODE_OBJECT_FB);
> -	if (obj) {
> +	if (obj)
>  		fb = obj_to_fb(obj);
> -		if (!kref_get_unless_zero(&fb->base.refcount))
> -			fb = NULL;
> -	}
>  	mutex_unlock(&dev->mode_config.fb_lock);
>  
>  	return fb;
> @@ -3434,37 +3436,38 @@ int drm_mode_rmfb(struct drm_device *dev,
>  {
>  	struct drm_framebuffer *fb = NULL;
>  	struct drm_framebuffer *fbl = NULL;
> -	struct drm_mode_object *obj;
>  	uint32_t *id = data;
>  	int found = 0;
>  
>  	if (!drm_core_check_feature(dev, DRIVER_MODESET))
>  		return -EINVAL;
>  
> +	fb = drm_framebuffer_lookup(dev, *id);
> +	if (!fb)
> +		return -ENOENT;
> +
>  	mutex_lock(&file_priv->fbs_lock);
> -	mutex_lock(&dev->mode_config.fb_lock);
> -	obj = _object_find(dev, *id, DRM_MODE_OBJECT_FB);
> -	if (!obj)
> -		goto fail_lookup;
> -	fb = obj_to_fb(obj);
>  	list_for_each_entry(fbl, &file_priv->fbs, filp_head)
>  		if (fb == fbl)
>  			found = 1;
> -	if (!found)
> -		goto fail_lookup;
> +	if (!found) {
> +		mutex_unlock(&file_priv->fbs_lock);
> +		goto fail_unref;
> +	}
>  
>  	list_del_init(&fb->filp_head);
> -	mutex_unlock(&dev->mode_config.fb_lock);
>  	mutex_unlock(&file_priv->fbs_lock);
>  
> +	/* we now own the reference that was stored in the fbs list */
>  	drm_framebuffer_unreference(fb);
>  
> -	return 0;
> +	/* drop the reference we picked up in framebuffer lookup */
> +	drm_framebuffer_unreference(fb);
>  
> -fail_lookup:
> -	mutex_unlock(&dev->mode_config.fb_lock);
> -	mutex_unlock(&file_priv->fbs_lock);
> +	return 0;
>  
> +fail_unref:
> +	drm_framebuffer_unreference(fb);
>  	return -ENOENT;
>  }
>  
> -- 
> 2.5.5
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


More information about the dri-devel mailing list