Skip to content

Commit 72fe90b

Browse files
committed
drm/modes: move reference taking into object lookup.
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. "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." Reviewed-by: Daniel Vetter <[email protected]> Signed-off-by: Dave Airlie <[email protected]>
1 parent c7e1c59 commit 72fe90b

File tree

1 file changed

+20
-17
lines changed

1 file changed

+20
-17
lines changed

drivers/gpu/drm/drm_crtc.c

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,11 @@ static struct drm_mode_object *_object_find(struct drm_device *dev,
364364
if (obj &&
365365
obj->type == DRM_MODE_OBJECT_BLOB)
366366
obj = NULL;
367+
368+
if (obj && obj->free_cb) {
369+
if (!kref_get_unless_zero(&obj->refcount))
370+
obj = NULL;
371+
}
367372
mutex_unlock(&dev->mode_config.idr_mutex);
368373

369374
return obj;
@@ -495,11 +500,8 @@ struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
495500

496501
mutex_lock(&dev->mode_config.fb_lock);
497502
obj = _object_find(dev, id, DRM_MODE_OBJECT_FB);
498-
if (obj) {
503+
if (obj)
499504
fb = obj_to_fb(obj);
500-
if (!kref_get_unless_zero(&fb->base.refcount))
501-
fb = NULL;
502-
}
503505
mutex_unlock(&dev->mode_config.fb_lock);
504506

505507
return fb;
@@ -3474,37 +3476,38 @@ int drm_mode_rmfb(struct drm_device *dev,
34743476
{
34753477
struct drm_framebuffer *fb = NULL;
34763478
struct drm_framebuffer *fbl = NULL;
3477-
struct drm_mode_object *obj;
34783479
uint32_t *id = data;
34793480
int found = 0;
34803481

34813482
if (!drm_core_check_feature(dev, DRIVER_MODESET))
34823483
return -EINVAL;
34833484

3485+
fb = drm_framebuffer_lookup(dev, *id);
3486+
if (!fb)
3487+
return -ENOENT;
3488+
34843489
mutex_lock(&file_priv->fbs_lock);
3485-
mutex_lock(&dev->mode_config.fb_lock);
3486-
obj = _object_find(dev, *id, DRM_MODE_OBJECT_FB);
3487-
if (!obj)
3488-
goto fail_lookup;
3489-
fb = obj_to_fb(obj);
34903490
list_for_each_entry(fbl, &file_priv->fbs, filp_head)
34913491
if (fb == fbl)
34923492
found = 1;
3493-
if (!found)
3494-
goto fail_lookup;
3493+
if (!found) {
3494+
mutex_unlock(&file_priv->fbs_lock);
3495+
goto fail_unref;
3496+
}
34953497

34963498
list_del_init(&fb->filp_head);
3497-
mutex_unlock(&dev->mode_config.fb_lock);
34983499
mutex_unlock(&file_priv->fbs_lock);
34993500

3501+
/* we now own the reference that was stored in the fbs list */
35003502
drm_framebuffer_unreference(fb);
35013503

3502-
return 0;
3504+
/* drop the reference we picked up in framebuffer lookup */
3505+
drm_framebuffer_unreference(fb);
35033506

3504-
fail_lookup:
3505-
mutex_unlock(&dev->mode_config.fb_lock);
3506-
mutex_unlock(&file_priv->fbs_lock);
3507+
return 0;
35073508

3509+
fail_unref:
3510+
drm_framebuffer_unreference(fb);
35083511
return -ENOENT;
35093512
}
35103513

0 commit comments

Comments
 (0)