aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-12-10 18:09:12 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-01-20 16:17:04 -0500
commit468174f748603497e73dba9b5c6d1d9f71121486 (patch)
tree4044c56d57bd6f47ae5c1bbd31d9b36ca77ed417
parent7d331595b05d6f3c38567ad7031b75075557ce2a (diff)
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>
-rw-r--r--drivers/gpu/drm/drm_crtc.c9
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,
2271 if ((config->min_height > r.height) || (r.height > config->max_height)) 2271 if ((config->min_height > r.height) || (r.height > config->max_height))
2272 return -EINVAL; 2272 return -EINVAL;
2273 2273
2274 drm_modeset_lock_all(dev);
2275
2276 /* TODO check buffer is sufficiently large */
2277 /* TODO setup destructor callback */
2278
2279 fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r); 2274 fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r);
2280 if (IS_ERR(fb)) { 2275 if (IS_ERR(fb)) {
2281 DRM_DEBUG_KMS("could not create framebuffer\n"); 2276 DRM_DEBUG_KMS("could not create framebuffer\n");
2282 drm_modeset_unlock_all(dev); 2277 drm_modeset_unlock_all(dev);
2283 return PTR_ERR(fb); 2278 return PTR_ERR(fb);
2284 } 2279 }
2285 drm_modeset_unlock_all(dev);
2286 2280
2287 mutex_lock(&file_priv->fbs_lock); 2281 mutex_lock(&file_priv->fbs_lock);
2288 or->fb_id = fb->base.id; 2282 or->fb_id = fb->base.id;
@@ -2457,15 +2451,12 @@ int drm_mode_addfb2(struct drm_device *dev,
2457 if (ret) 2451 if (ret)
2458 return ret; 2452 return ret;
2459 2453
2460 drm_modeset_lock_all(dev);
2461
2462 fb = dev->mode_config.funcs->fb_create(dev, file_priv, r); 2454 fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
2463 if (IS_ERR(fb)) { 2455 if (IS_ERR(fb)) {
2464 DRM_DEBUG_KMS("could not create framebuffer\n"); 2456 DRM_DEBUG_KMS("could not create framebuffer\n");
2465 drm_modeset_unlock_all(dev); 2457 drm_modeset_unlock_all(dev);
2466 return PTR_ERR(fb); 2458 return PTR_ERR(fb);
2467 } 2459 }
2468 drm_modeset_unlock_all(dev);
2469 2460
2470 mutex_lock(&file_priv->fbs_lock); 2461 mutex_lock(&file_priv->fbs_lock);
2471 r->fb_id = fb->base.id; 2462 r->fb_id = fb->base.id;