Skip to content

Commit

Permalink
drm/mode: move framebuffer reference into object.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Dave Airlie committed Apr 22, 2016
1 parent 747a598 commit d0f37cf
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 38 deletions.
72 changes: 38 additions & 34 deletions drivers/gpu/drm/drm_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,8 @@ EXPORT_SYMBOL(drm_get_format_name);
static int drm_mode_object_get_reg(struct drm_device *dev,
struct drm_mode_object *obj,
uint32_t obj_type,
bool register_obj)
bool register_obj,
void (*obj_free_cb)(struct kref *kref))
{
int ret;

Expand All @@ -288,6 +289,10 @@ static int drm_mode_object_get_reg(struct drm_device *dev,
*/
obj->id = ret;
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);

Expand All @@ -311,7 +316,7 @@ static int drm_mode_object_get_reg(struct drm_device *dev,
int drm_mode_object_get(struct drm_device *dev,
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,
Expand Down Expand Up @@ -389,10 +394,35 @@ struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
}
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)
{
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;

/*
Expand Down Expand Up @@ -430,12 +460,12 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
int ret;

mutex_lock(&dev->mode_config.fb_lock);
kref_init(&fb->refcount);
INIT_LIST_HEAD(&fb->filp_head);
fb->dev = dev;
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)
goto out;

Expand Down Expand Up @@ -482,7 +512,7 @@ struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
mutex_lock(&dev->mode_config.fb_lock);
fb = __drm_framebuffer_lookup(dev, id);
if (fb) {
if (!kref_get_unless_zero(&fb->refcount))
if (!kref_get_unless_zero(&fb->base.refcount))
fb = NULL;
}
mutex_unlock(&dev->mode_config.fb_lock);
Expand All @@ -491,32 +521,6 @@ struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
}
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
* @fb: fb to unregister
Expand Down Expand Up @@ -902,7 +906,7 @@ int drm_connector_init(struct drm_device *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)
goto out_unlock;

Expand Down Expand Up @@ -5971,7 +5975,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
*/
WARN_ON(!list_empty(&dev->mode_config.fb_list));
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);
Expand Down
32 changes: 28 additions & 4 deletions include/drm/drm_crtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ struct drm_mode_object {
uint32_t id;
uint32_t type;
struct drm_object_properties *properties;
struct kref refcount;
void (*free_cb)(struct kref *kref);
};

#define DRM_OBJECT_MAX_PROPERTY 24
Expand Down Expand Up @@ -223,8 +225,8 @@ struct drm_framebuffer {
* 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.
* The refcount is stored inside the mode object.
*/
struct kref refcount;
/*
* Place on the dev->mode_config.fb_list, access protected by
* dev->mode_config.fb_lock.
Expand Down Expand Up @@ -2377,8 +2379,6 @@ extern int drm_framebuffer_init(struct drm_device *dev,
const struct drm_framebuffer_funcs *funcs);
extern struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
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_cleanup(struct drm_framebuffer *fb);
extern void drm_framebuffer_unregister_private(struct drm_framebuffer *fb);
Expand Down Expand Up @@ -2436,6 +2436,8 @@ extern int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
int gamma_size);
extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
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 */
extern int drm_mode_getresources(struct drm_device *dev,
Expand Down Expand Up @@ -2605,6 +2607,28 @@ static inline uint32_t drm_color_lut_extract(uint32_t user_input,
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.
* @fb: framebuffer
Expand All @@ -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)
{
return atomic_read(&fb->refcount.refcount);
return atomic_read(&fb->base.refcount.refcount);
}

/* Plane list iterator for legacy (overlay only) planes. */
Expand Down

0 comments on commit d0f37cf

Please sign in to comment.