diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-12-11 00:09:12 +0100 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-01-20 22:17:04 +0100 |
commit | 468174f748603497e73dba9b5c6d1d9f71121486 (patch) | |
tree | 4044c56d57bd6f47ae5c1bbd31d9b36ca77ed417 /drivers/gpu/drm/drm_crtc.c | |
parent | 7d331595b05d6f3c38567ad7031b75075557ce2a (diff) | |
download | blackbird-op-linux-468174f748603497e73dba9b5c6d1d9f71121486.tar.gz blackbird-op-linux-468174f748603497e73dba9b5c6d1d9f71121486.zip |
drm: push modeset_lock_all into ->fb_create driver callbacks
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.
Reviewed-by: Rob Clark <rob@ti.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/drm_crtc.c')
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 9 |
1 files changed, 0 insertions, 9 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 09e02a7023f9..2e6103c5d632 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2271,18 +2271,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; @@ -2457,15 +2451,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; |