And drop it where it's not needed. Most driver just lookup the gem
object, allocate an fb struct, fill in all the useful fields and then
register it with drm_framebuffer_init.
All of these operations are already separately locked, and since we
only put the fb into the fpriv->fbs list _after_ having called
->fb_create, we can't also race with rmfb. We can otoh race with other
ioctls that put the framebuffer to use, but all drivers have been
reorganized already to call drm_framebuffer_init last in the fb
creation sequence.
So essentially, we can completely remove any modeset locks from the
addfb ioctl paths. Yeah!
Also, reference-counting is solid - we get a reference from fb_create
which we transfer to the fpriv->fbs list. And after unlocking the
fpriv->fbs_lock we don't touch the framebuffer any longer. Furthermore
drm_framebuffer_init has added a 2nd reference for the idr lookup, and
any access through that table will do it's own refcounting.
Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
---
drivers/gpu/drm/drm_crtc.c | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 33e95bb..9ad807d 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2255,18 +2255,12 @@ int drm_mode_addfb(struct drm_device *dev,
if ((config->min_height > r.height) || (r.height > config->max_height))
return -EINVAL;
- drm_modeset_lock_all(dev);
-
- /* TODO check buffer is sufficiently large */
- /* TODO setup destructor callback */
-
fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r);
if (IS_ERR(fb)) {
DRM_DEBUG_KMS("could not create framebuffer\n");
drm_modeset_unlock_all(dev);
return PTR_ERR(fb);
}
- drm_modeset_unlock_all(dev);
mutex_lock(&file_priv->fbs_lock);
or->fb_id = fb->base.id;
@@ -2441,15 +2435,12 @@ int drm_mode_addfb2(struct drm_device *dev,
if (ret)
return ret;
- drm_modeset_lock_all(dev);
-
fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
if (IS_ERR(fb)) {
DRM_DEBUG_KMS("could not create framebuffer\n");
drm_modeset_unlock_all(dev);
return PTR_ERR(fb);
}
- drm_modeset_unlock_all(dev);
mutex_lock(&file_priv->fbs_lock);
r->fb_id = fb->base.id;
--
1.7.10.4