aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/vmwgfx
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-12-10 15:19:18 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-01-20 16:16:58 -0500
commit4b096ac10da0b63f09bd123b86fed8deb80646ce (patch)
tree3d252a1b2ed182beb769796fb99eb68693176bfa /drivers/gpu/drm/vmwgfx
parentdac35663cef4ca7f572d430bb54b14be8f03cb10 (diff)
drm: revamp locking around fb creation/destruction
Well, at least step 1. The goal here is that framebuffer objects can survive outside of the mode_config lock, with just a reference held as protection. The first step to get there is to introduce a special fb_lock which protects fb lookup, creation and destruction, to make them appear atomic. This new fb_lock can nest within the mode_config lock. But the idea is (once the reference counting part is completed) that we only quickly take that fb_lock to lookup a framebuffer and grab a reference, without any other locks involved. vmwgfx is the only driver which does framebuffer lookups itself, also wrap those calls to drm_mode_object_find with the new lock. Also protect the fb_list walking in i915 and omapdrm with the new lock. As a slight complication there's also the list of user-created fbs attached to the file private. The problem now is that at fclose() time we need to walk that list, eventually do a modeset call to remove the fb from active usage (and are required to be able to take the mode_config lock), but in the end we need to grab the new fb_lock to remove the fb from the list. The easiest solution is to add another mutex to protect this per-file list. Currently that new fbs_lock nests within the modeset locks and so appears redudant. But later patches will switch around this sequence so that taking the modeset locks in the fb destruction path is optional in the fastpath. Ultimately the goal is that addfb and rmfb do not require the mode_config lock, since otherwise they have the potential to introduce stalls in the pageflip sequence of a compositor (if the compositor e.g. switches to a fullscreen client or if it enables a plane). But that requires a few more steps and hoops to jump through. Note that framebuffer creation/destruction is now double-protected - once by the fb_lock and in parts by the idr_lock. The later would be unnecessariy if framebuffers would have their own idr allocator. But that's material for another patch (series). v2: Properly initialize the fb->filp_head list in _init, otherwise the newly added WARN to check whether the fb isn't on a fpriv list any more will fail for driver-private objects. v3: Fixup two error-case unlock bugs spotted by Richard Wilbur. Reviewed-by: Rob Clark <rob@ti.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/vmwgfx')
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
index a135498a1298..0d6a161b204b 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
@@ -165,7 +165,9 @@ int vmw_present_ioctl(struct drm_device *dev, void *data,
165 165
166 drm_modeset_lock_all(dev); 166 drm_modeset_lock_all(dev);
167 167
168 mutex_lock(&dev->mode_config.fb_lock);
168 obj = drm_mode_object_find(dev, arg->fb_id, DRM_MODE_OBJECT_FB); 169 obj = drm_mode_object_find(dev, arg->fb_id, DRM_MODE_OBJECT_FB);
170 mutex_unlock(&dev->mode_config.fb_lock);
169 if (!obj) { 171 if (!obj) {
170 DRM_ERROR("Invalid framebuffer id.\n"); 172 DRM_ERROR("Invalid framebuffer id.\n");
171 ret = -EINVAL; 173 ret = -EINVAL;
@@ -248,7 +250,9 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data,
248 250
249 drm_modeset_lock_all(dev); 251 drm_modeset_lock_all(dev);
250 252
253 mutex_lock(&dev->mode_config.fb_lock);
251 obj = drm_mode_object_find(dev, arg->fb_id, DRM_MODE_OBJECT_FB); 254 obj = drm_mode_object_find(dev, arg->fb_id, DRM_MODE_OBJECT_FB);
255 mutex_unlock(&dev->mode_config.fb_lock);
252 if (!obj) { 256 if (!obj) {
253 DRM_ERROR("Invalid framebuffer id.\n"); 257 DRM_ERROR("Invalid framebuffer id.\n");
254 ret = -EINVAL; 258 ret = -EINVAL;