mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	drm/mode: move framebuffer reference into object.
This is the initial code to add references to some mode objects. In the future we need to start reference counting connectors so firstly I want to reorganise the code so the framebuffer ref counting uses the same paths. This patch shouldn't change any functionality, just moves the kref. [airlied: move kerneldoc as well] Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
		
							parent
							
								
									747a598ffa
								
							
						
					
					
						commit
						d0f37cf629
					
				
					 2 changed files with 66 additions and 38 deletions
				
			
		| 
						 | 
					@ -275,7 +275,8 @@ EXPORT_SYMBOL(drm_get_format_name);
 | 
				
			||||||
static int drm_mode_object_get_reg(struct drm_device *dev,
 | 
					static int drm_mode_object_get_reg(struct drm_device *dev,
 | 
				
			||||||
				   struct drm_mode_object *obj,
 | 
									   struct drm_mode_object *obj,
 | 
				
			||||||
				   uint32_t obj_type,
 | 
									   uint32_t obj_type,
 | 
				
			||||||
				   bool register_obj)
 | 
									   bool register_obj,
 | 
				
			||||||
 | 
									   void (*obj_free_cb)(struct kref *kref))
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -288,6 +289,10 @@ static int drm_mode_object_get_reg(struct drm_device *dev,
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		obj->id = ret;
 | 
							obj->id = ret;
 | 
				
			||||||
		obj->type = obj_type;
 | 
							obj->type = obj_type;
 | 
				
			||||||
 | 
							if (obj_free_cb) {
 | 
				
			||||||
 | 
								obj->free_cb = obj_free_cb;
 | 
				
			||||||
 | 
								kref_init(&obj->refcount);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	mutex_unlock(&dev->mode_config.idr_mutex);
 | 
						mutex_unlock(&dev->mode_config.idr_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -311,7 +316,7 @@ static int drm_mode_object_get_reg(struct drm_device *dev,
 | 
				
			||||||
int drm_mode_object_get(struct drm_device *dev,
 | 
					int drm_mode_object_get(struct drm_device *dev,
 | 
				
			||||||
			struct drm_mode_object *obj, uint32_t obj_type)
 | 
								struct drm_mode_object *obj, uint32_t obj_type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return drm_mode_object_get_reg(dev, obj, obj_type, true);
 | 
						return drm_mode_object_get_reg(dev, obj, obj_type, true, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void drm_mode_object_register(struct drm_device *dev,
 | 
					static void drm_mode_object_register(struct drm_device *dev,
 | 
				
			||||||
| 
						 | 
					@ -389,10 +394,35 @@ struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(drm_mode_object_find);
 | 
					EXPORT_SYMBOL(drm_mode_object_find);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void drm_mode_object_unreference(struct drm_mode_object *obj)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (obj->free_cb) {
 | 
				
			||||||
 | 
							DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, atomic_read(&obj->refcount.refcount));
 | 
				
			||||||
 | 
							kref_put(&obj->refcount, obj->free_cb);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(drm_mode_object_unreference);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * drm_mode_object_reference - incr the fb refcnt
 | 
				
			||||||
 | 
					 * @obj: mode_object
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function operates only on refcounted objects.
 | 
				
			||||||
 | 
					 * This functions increments the object's refcount.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void drm_mode_object_reference(struct drm_mode_object *obj)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (obj->free_cb) {
 | 
				
			||||||
 | 
							DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, atomic_read(&obj->refcount.refcount));
 | 
				
			||||||
 | 
							kref_get(&obj->refcount);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(drm_mode_object_reference);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void drm_framebuffer_free(struct kref *kref)
 | 
					static void drm_framebuffer_free(struct kref *kref)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct drm_framebuffer *fb =
 | 
						struct drm_framebuffer *fb =
 | 
				
			||||||
			container_of(kref, struct drm_framebuffer, refcount);
 | 
								container_of(kref, struct drm_framebuffer, base.refcount);
 | 
				
			||||||
	struct drm_device *dev = fb->dev;
 | 
						struct drm_device *dev = fb->dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -430,12 +460,12 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mutex_lock(&dev->mode_config.fb_lock);
 | 
						mutex_lock(&dev->mode_config.fb_lock);
 | 
				
			||||||
	kref_init(&fb->refcount);
 | 
					 | 
				
			||||||
	INIT_LIST_HEAD(&fb->filp_head);
 | 
						INIT_LIST_HEAD(&fb->filp_head);
 | 
				
			||||||
	fb->dev = dev;
 | 
						fb->dev = dev;
 | 
				
			||||||
	fb->funcs = funcs;
 | 
						fb->funcs = funcs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB);
 | 
						ret = drm_mode_object_get_reg(dev, &fb->base, DRM_MODE_OBJECT_FB,
 | 
				
			||||||
 | 
									      true, drm_framebuffer_free);
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -482,7 +512,7 @@ struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
 | 
				
			||||||
	mutex_lock(&dev->mode_config.fb_lock);
 | 
						mutex_lock(&dev->mode_config.fb_lock);
 | 
				
			||||||
	fb = __drm_framebuffer_lookup(dev, id);
 | 
						fb = __drm_framebuffer_lookup(dev, id);
 | 
				
			||||||
	if (fb) {
 | 
						if (fb) {
 | 
				
			||||||
		if (!kref_get_unless_zero(&fb->refcount))
 | 
							if (!kref_get_unless_zero(&fb->base.refcount))
 | 
				
			||||||
			fb = NULL;
 | 
								fb = NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	mutex_unlock(&dev->mode_config.fb_lock);
 | 
						mutex_unlock(&dev->mode_config.fb_lock);
 | 
				
			||||||
| 
						 | 
					@ -491,32 +521,6 @@ struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(drm_framebuffer_lookup);
 | 
					EXPORT_SYMBOL(drm_framebuffer_lookup);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * drm_framebuffer_unreference - unref a framebuffer
 | 
					 | 
				
			||||||
 * @fb: framebuffer to unref
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This functions decrements the fb's refcount and frees it if it drops to zero.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void drm_framebuffer_unreference(struct drm_framebuffer *fb)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	DRM_DEBUG("%p: FB ID: %d (%d)\n", fb, fb->base.id, atomic_read(&fb->refcount.refcount));
 | 
					 | 
				
			||||||
	kref_put(&fb->refcount, drm_framebuffer_free);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
EXPORT_SYMBOL(drm_framebuffer_unreference);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * drm_framebuffer_reference - incr the fb refcnt
 | 
					 | 
				
			||||||
 * @fb: framebuffer
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This functions increments the fb's refcount.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void drm_framebuffer_reference(struct drm_framebuffer *fb)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	DRM_DEBUG("%p: FB ID: %d (%d)\n", fb, fb->base.id, atomic_read(&fb->refcount.refcount));
 | 
					 | 
				
			||||||
	kref_get(&fb->refcount);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
EXPORT_SYMBOL(drm_framebuffer_reference);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * drm_framebuffer_unregister_private - unregister a private fb from the lookup idr
 | 
					 * drm_framebuffer_unregister_private - unregister a private fb from the lookup idr
 | 
				
			||||||
 * @fb: fb to unregister
 | 
					 * @fb: fb to unregister
 | 
				
			||||||
| 
						 | 
					@ -902,7 +906,7 @@ int drm_connector_init(struct drm_device *dev,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	drm_modeset_lock_all(dev);
 | 
						drm_modeset_lock_all(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = drm_mode_object_get_reg(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR, false);
 | 
						ret = drm_mode_object_get_reg(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR, false, NULL);
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		goto out_unlock;
 | 
							goto out_unlock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5971,7 +5975,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	WARN_ON(!list_empty(&dev->mode_config.fb_list));
 | 
						WARN_ON(!list_empty(&dev->mode_config.fb_list));
 | 
				
			||||||
	list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
 | 
						list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
 | 
				
			||||||
		drm_framebuffer_free(&fb->refcount);
 | 
							drm_framebuffer_free(&fb->base.refcount);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ida_destroy(&dev->mode_config.connector_ida);
 | 
						ida_destroy(&dev->mode_config.connector_ida);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,6 +49,8 @@ struct drm_mode_object {
 | 
				
			||||||
	uint32_t id;
 | 
						uint32_t id;
 | 
				
			||||||
	uint32_t type;
 | 
						uint32_t type;
 | 
				
			||||||
	struct drm_object_properties *properties;
 | 
						struct drm_object_properties *properties;
 | 
				
			||||||
 | 
						struct kref refcount;
 | 
				
			||||||
 | 
						void (*free_cb)(struct kref *kref);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DRM_OBJECT_MAX_PROPERTY 24
 | 
					#define DRM_OBJECT_MAX_PROPERTY 24
 | 
				
			||||||
| 
						 | 
					@ -223,8 +225,8 @@ struct drm_framebuffer {
 | 
				
			||||||
	 * 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.
 | 
						 * userspace perspective.
 | 
				
			||||||
 | 
						 * The refcount is stored inside the mode object.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	struct kref refcount;
 | 
					 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Place on the dev->mode_config.fb_list, access protected by
 | 
						 * Place on the dev->mode_config.fb_list, access protected by
 | 
				
			||||||
	 * dev->mode_config.fb_lock.
 | 
						 * dev->mode_config.fb_lock.
 | 
				
			||||||
| 
						 | 
					@ -2377,8 +2379,6 @@ extern int drm_framebuffer_init(struct drm_device *dev,
 | 
				
			||||||
				const struct drm_framebuffer_funcs *funcs);
 | 
									const struct drm_framebuffer_funcs *funcs);
 | 
				
			||||||
extern struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
 | 
					extern struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
 | 
				
			||||||
						      uint32_t id);
 | 
											      uint32_t id);
 | 
				
			||||||
extern void drm_framebuffer_unreference(struct drm_framebuffer *fb);
 | 
					 | 
				
			||||||
extern void drm_framebuffer_reference(struct drm_framebuffer *fb);
 | 
					 | 
				
			||||||
extern void drm_framebuffer_remove(struct drm_framebuffer *fb);
 | 
					extern void drm_framebuffer_remove(struct drm_framebuffer *fb);
 | 
				
			||||||
extern void drm_framebuffer_cleanup(struct drm_framebuffer *fb);
 | 
					extern void drm_framebuffer_cleanup(struct drm_framebuffer *fb);
 | 
				
			||||||
extern void drm_framebuffer_unregister_private(struct drm_framebuffer *fb);
 | 
					extern void drm_framebuffer_unregister_private(struct drm_framebuffer *fb);
 | 
				
			||||||
| 
						 | 
					@ -2436,6 +2436,8 @@ extern int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
 | 
				
			||||||
					 int gamma_size);
 | 
										 int gamma_size);
 | 
				
			||||||
extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
 | 
					extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
 | 
				
			||||||
		uint32_t id, uint32_t type);
 | 
							uint32_t id, uint32_t type);
 | 
				
			||||||
 | 
					void drm_mode_object_reference(struct drm_mode_object *obj);
 | 
				
			||||||
 | 
					void drm_mode_object_unreference(struct drm_mode_object *obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* IOCTLs */
 | 
					/* IOCTLs */
 | 
				
			||||||
extern int drm_mode_getresources(struct drm_device *dev,
 | 
					extern int drm_mode_getresources(struct drm_device *dev,
 | 
				
			||||||
| 
						 | 
					@ -2605,6 +2607,28 @@ static inline uint32_t drm_color_lut_extract(uint32_t user_input,
 | 
				
			||||||
	return clamp_val(val, 0, max);
 | 
						return clamp_val(val, 0, max);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * drm_framebuffer_reference - incr the fb refcnt
 | 
				
			||||||
 | 
					 * @fb: framebuffer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This functions increments the fb's refcount.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline void drm_framebuffer_reference(struct drm_framebuffer *fb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						drm_mode_object_reference(&fb->base);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * drm_framebuffer_unreference - unref a framebuffer
 | 
				
			||||||
 | 
					 * @fb: framebuffer to unref
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This functions decrements the fb's refcount and frees it if it drops to zero.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline void drm_framebuffer_unreference(struct drm_framebuffer *fb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						drm_mode_object_unreference(&fb->base);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * drm_framebuffer_read_refcount - read the framebuffer reference count.
 | 
					 * drm_framebuffer_read_refcount - read the framebuffer reference count.
 | 
				
			||||||
 * @fb: framebuffer
 | 
					 * @fb: framebuffer
 | 
				
			||||||
| 
						 | 
					@ -2613,7 +2637,7 @@ static inline uint32_t drm_color_lut_extract(uint32_t user_input,
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static inline uint32_t drm_framebuffer_read_refcount(struct drm_framebuffer *fb)
 | 
					static inline uint32_t drm_framebuffer_read_refcount(struct drm_framebuffer *fb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return atomic_read(&fb->refcount.refcount);
 | 
						return atomic_read(&fb->base.refcount.refcount);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Plane list iterator for legacy (overlay only) planes. */
 | 
					/* Plane list iterator for legacy (overlay only) planes. */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue