Skip to content

Commit d0f37cf

Browse files
committed
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 <[email protected]> Signed-off-by: Dave Airlie <[email protected]>
1 parent 747a598 commit d0f37cf

File tree

2 files changed

+66
-38
lines changed

2 files changed

+66
-38
lines changed

drivers/gpu/drm/drm_crtc.c

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,8 @@ EXPORT_SYMBOL(drm_get_format_name);
275275
static int drm_mode_object_get_reg(struct drm_device *dev,
276276
struct drm_mode_object *obj,
277277
uint32_t obj_type,
278-
bool register_obj)
278+
bool register_obj,
279+
void (*obj_free_cb)(struct kref *kref))
279280
{
280281
int ret;
281282

@@ -288,6 +289,10 @@ static int drm_mode_object_get_reg(struct drm_device *dev,
288289
*/
289290
obj->id = ret;
290291
obj->type = obj_type;
292+
if (obj_free_cb) {
293+
obj->free_cb = obj_free_cb;
294+
kref_init(&obj->refcount);
295+
}
291296
}
292297
mutex_unlock(&dev->mode_config.idr_mutex);
293298

@@ -311,7 +316,7 @@ static int drm_mode_object_get_reg(struct drm_device *dev,
311316
int drm_mode_object_get(struct drm_device *dev,
312317
struct drm_mode_object *obj, uint32_t obj_type)
313318
{
314-
return drm_mode_object_get_reg(dev, obj, obj_type, true);
319+
return drm_mode_object_get_reg(dev, obj, obj_type, true, NULL);
315320
}
316321

317322
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,
389394
}
390395
EXPORT_SYMBOL(drm_mode_object_find);
391396

397+
void drm_mode_object_unreference(struct drm_mode_object *obj)
398+
{
399+
if (obj->free_cb) {
400+
DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, atomic_read(&obj->refcount.refcount));
401+
kref_put(&obj->refcount, obj->free_cb);
402+
}
403+
}
404+
EXPORT_SYMBOL(drm_mode_object_unreference);
405+
406+
/**
407+
* drm_mode_object_reference - incr the fb refcnt
408+
* @obj: mode_object
409+
*
410+
* This function operates only on refcounted objects.
411+
* This functions increments the object's refcount.
412+
*/
413+
void drm_mode_object_reference(struct drm_mode_object *obj)
414+
{
415+
if (obj->free_cb) {
416+
DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, atomic_read(&obj->refcount.refcount));
417+
kref_get(&obj->refcount);
418+
}
419+
}
420+
EXPORT_SYMBOL(drm_mode_object_reference);
421+
392422
static void drm_framebuffer_free(struct kref *kref)
393423
{
394424
struct drm_framebuffer *fb =
395-
container_of(kref, struct drm_framebuffer, refcount);
425+
container_of(kref, struct drm_framebuffer, base.refcount);
396426
struct drm_device *dev = fb->dev;
397427

398428
/*
@@ -430,12 +460,12 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
430460
int ret;
431461

432462
mutex_lock(&dev->mode_config.fb_lock);
433-
kref_init(&fb->refcount);
434463
INIT_LIST_HEAD(&fb->filp_head);
435464
fb->dev = dev;
436465
fb->funcs = funcs;
437466

438-
ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB);
467+
ret = drm_mode_object_get_reg(dev, &fb->base, DRM_MODE_OBJECT_FB,
468+
true, drm_framebuffer_free);
439469
if (ret)
440470
goto out;
441471

@@ -482,7 +512,7 @@ struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
482512
mutex_lock(&dev->mode_config.fb_lock);
483513
fb = __drm_framebuffer_lookup(dev, id);
484514
if (fb) {
485-
if (!kref_get_unless_zero(&fb->refcount))
515+
if (!kref_get_unless_zero(&fb->base.refcount))
486516
fb = NULL;
487517
}
488518
mutex_unlock(&dev->mode_config.fb_lock);
@@ -491,32 +521,6 @@ struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
491521
}
492522
EXPORT_SYMBOL(drm_framebuffer_lookup);
493523

494-
/**
495-
* drm_framebuffer_unreference - unref a framebuffer
496-
* @fb: framebuffer to unref
497-
*
498-
* This functions decrements the fb's refcount and frees it if it drops to zero.
499-
*/
500-
void drm_framebuffer_unreference(struct drm_framebuffer *fb)
501-
{
502-
DRM_DEBUG("%p: FB ID: %d (%d)\n", fb, fb->base.id, atomic_read(&fb->refcount.refcount));
503-
kref_put(&fb->refcount, drm_framebuffer_free);
504-
}
505-
EXPORT_SYMBOL(drm_framebuffer_unreference);
506-
507-
/**
508-
* drm_framebuffer_reference - incr the fb refcnt
509-
* @fb: framebuffer
510-
*
511-
* This functions increments the fb's refcount.
512-
*/
513-
void drm_framebuffer_reference(struct drm_framebuffer *fb)
514-
{
515-
DRM_DEBUG("%p: FB ID: %d (%d)\n", fb, fb->base.id, atomic_read(&fb->refcount.refcount));
516-
kref_get(&fb->refcount);
517-
}
518-
EXPORT_SYMBOL(drm_framebuffer_reference);
519-
520524
/**
521525
* drm_framebuffer_unregister_private - unregister a private fb from the lookup idr
522526
* @fb: fb to unregister
@@ -902,7 +906,7 @@ int drm_connector_init(struct drm_device *dev,
902906

903907
drm_modeset_lock_all(dev);
904908

905-
ret = drm_mode_object_get_reg(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR, false);
909+
ret = drm_mode_object_get_reg(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR, false, NULL);
906910
if (ret)
907911
goto out_unlock;
908912

@@ -5971,7 +5975,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
59715975
*/
59725976
WARN_ON(!list_empty(&dev->mode_config.fb_list));
59735977
list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
5974-
drm_framebuffer_free(&fb->refcount);
5978+
drm_framebuffer_free(&fb->base.refcount);
59755979
}
59765980

59775981
ida_destroy(&dev->mode_config.connector_ida);

include/drm/drm_crtc.h

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ struct drm_mode_object {
4949
uint32_t id;
5050
uint32_t type;
5151
struct drm_object_properties *properties;
52+
struct kref refcount;
53+
void (*free_cb)(struct kref *kref);
5254
};
5355

5456
#define DRM_OBJECT_MAX_PROPERTY 24
@@ -223,8 +225,8 @@ struct drm_framebuffer {
223225
* should be deferred. In cases like this, the driver would like to
224226
* hold a ref to the fb even though it has already been removed from
225227
* userspace perspective.
228+
* The refcount is stored inside the mode object.
226229
*/
227-
struct kref refcount;
228230
/*
229231
* Place on the dev->mode_config.fb_list, access protected by
230232
* dev->mode_config.fb_lock.
@@ -2377,8 +2379,6 @@ extern int drm_framebuffer_init(struct drm_device *dev,
23772379
const struct drm_framebuffer_funcs *funcs);
23782380
extern struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
23792381
uint32_t id);
2380-
extern void drm_framebuffer_unreference(struct drm_framebuffer *fb);
2381-
extern void drm_framebuffer_reference(struct drm_framebuffer *fb);
23822382
extern void drm_framebuffer_remove(struct drm_framebuffer *fb);
23832383
extern void drm_framebuffer_cleanup(struct drm_framebuffer *fb);
23842384
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,
24362436
int gamma_size);
24372437
extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
24382438
uint32_t id, uint32_t type);
2439+
void drm_mode_object_reference(struct drm_mode_object *obj);
2440+
void drm_mode_object_unreference(struct drm_mode_object *obj);
24392441

24402442
/* IOCTLs */
24412443
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,
26052607
return clamp_val(val, 0, max);
26062608
}
26072609

2610+
/*
2611+
* drm_framebuffer_reference - incr the fb refcnt
2612+
* @fb: framebuffer
2613+
*
2614+
* This functions increments the fb's refcount.
2615+
*/
2616+
static inline void drm_framebuffer_reference(struct drm_framebuffer *fb)
2617+
{
2618+
drm_mode_object_reference(&fb->base);
2619+
}
2620+
2621+
/**
2622+
* drm_framebuffer_unreference - unref a framebuffer
2623+
* @fb: framebuffer to unref
2624+
*
2625+
* This functions decrements the fb's refcount and frees it if it drops to zero.
2626+
*/
2627+
static inline void drm_framebuffer_unreference(struct drm_framebuffer *fb)
2628+
{
2629+
drm_mode_object_unreference(&fb->base);
2630+
}
2631+
26082632
/**
26092633
* drm_framebuffer_read_refcount - read the framebuffer reference count.
26102634
* @fb: framebuffer
@@ -2613,7 +2637,7 @@ static inline uint32_t drm_color_lut_extract(uint32_t user_input,
26132637
*/
26142638
static inline uint32_t drm_framebuffer_read_refcount(struct drm_framebuffer *fb)
26152639
{
2616-
return atomic_read(&fb->refcount.refcount);
2640+
return atomic_read(&fb->base.refcount.refcount);
26172641
}
26182642

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

0 commit comments

Comments
 (0)