Skip to content

Commit

Permalink
drm: nest modeset locks within fpriv->fbs_lock
Browse files Browse the repository at this point in the history
Atm we still need to unconditionally take the modeset locks in the
rmfb paths. But eventually we only want to take them if there are
other users around as a slow-path. This way sane userspace avoids
blocking on edid reads and other stuff in rmfb if it ensures that the
fb isn't used anywhere by a crtc/plane.

We can do a quick check for such other users once framebuffers are
properly refcounting by locking at the refcount - if it's more than 1,
there are other users left. Again, rmfb racing against other ioctls
isn't a real problem, userspace is allowed to shoot its foot.

This patch just prepares this by moving the modeset locks to nest
within fpriv->fbs_lock. Now the distinction between the fbs_lock and
the device-global fb_lock is clear, since we need to hold the fbs_lock
outside of any modeset_locks in fb_release.

Reviewed-by: Rob Clark <rob@ti.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
  • Loading branch information
Daniel Vetter committed Jan 20, 2013
1 parent 2b677e8 commit 7d33159
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions drivers/gpu/drm/drm_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2282,13 +2282,13 @@ int drm_mode_addfb(struct drm_device *dev,
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;
list_add(&fb->filp_head, &file_priv->fbs);
DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
mutex_unlock(&file_priv->fbs_lock);
drm_modeset_unlock_all(dev);

return ret;
}
Expand Down Expand Up @@ -2465,14 +2465,14 @@ int drm_mode_addfb2(struct drm_device *dev,
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;
list_add(&fb->filp_head, &file_priv->fbs);
DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
mutex_unlock(&file_priv->fbs_lock);

drm_modeset_unlock_all(dev);

return ret;
}
Expand Down Expand Up @@ -2670,7 +2670,6 @@ void drm_fb_release(struct drm_file *priv)
struct drm_device *dev = priv->minor->dev;
struct drm_framebuffer *fb, *tfb;

drm_modeset_lock_all(dev);
mutex_lock(&priv->fbs_lock);
list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {

Expand All @@ -2682,10 +2681,11 @@ void drm_fb_release(struct drm_file *priv)
list_del_init(&fb->filp_head);

/* This will also drop the fpriv->fbs reference. */
drm_modeset_lock_all(dev);
drm_framebuffer_remove(fb);
drm_modeset_unlock_all(dev);
}
mutex_unlock(&priv->fbs_lock);
drm_modeset_unlock_all(dev);
}

/**
Expand Down

0 comments on commit 7d33159

Please sign in to comment.