aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_crtc.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-12-11 00:38:18 +0100
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-01-20 22:17:06 +0100
commit4ccf097f1935321f03ad36218588a9e446006b6a (patch)
treed6238772eb276ac0c7d56faf16fb920990773e9f /drivers/gpu/drm/drm_crtc.c
parentdrm: don't take modeset locks in getfb ioctl (diff)
downloadlinux-dev-4ccf097f1935321f03ad36218588a9e446006b6a.tar.xz
linux-dev-4ccf097f1935321f03ad36218588a9e446006b6a.zip
drm: fb refcounting for dirtyfb_ioctl
We only need to ensure that the fb stays around for long enough. While at it, only grab the modeset locks when we need them (since most drivers don't implement the dirty callback, this should help jitter and stalls when using the generic modeset driver). 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.c15
1 files changed, 6 insertions, 9 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index cba8c8bb789c..d4f8fa5b3c18 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2580,14 +2580,9 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- drm_modeset_lock_all(dev);
fb = drm_framebuffer_lookup(dev, r->fb_id);
- if (!fb) {
- ret = -EINVAL;
- goto out_err1;
- }
- /* fb is protect by the mode_config lock, so drop the ref immediately */
- drm_framebuffer_unreference(fb);
+ if (!fb)
+ return -EINVAL;
num_clips = r->num_clips;
clips_ptr = (struct drm_clip_rect __user *)(unsigned long)r->clips_ptr;
@@ -2625,17 +2620,19 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
}
if (fb->funcs->dirty) {
+ drm_modeset_lock_all(dev);
ret = fb->funcs->dirty(fb, file_priv, flags, r->color,
clips, num_clips);
+ drm_modeset_unlock_all(dev);
} else {
ret = -ENOSYS;
- goto out_err2;
}
out_err2:
kfree(clips);
out_err1:
- drm_modeset_unlock_all(dev);
+ drm_framebuffer_unreference(fb);
+
return ret;
}