diff options
Diffstat (limited to 'drivers/gpu/drm/drm_crtc.c')
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 826a5ca3595f..3bdf2a650d9c 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -68,9 +68,23 @@ void drm_modeset_unlock_all(struct drm_device *dev) mutex_unlock(&dev->mode_config.mutex); } - EXPORT_SYMBOL(drm_modeset_unlock_all); +/** + * drm_warn_on_modeset_not_all_locked - check that all modeset locks are locked + * @dev: device + */ +void drm_warn_on_modeset_not_all_locked(struct drm_device *dev) +{ + struct drm_crtc *crtc; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + WARN_ON(!mutex_is_locked(&crtc->mutex)); + + WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); +} +EXPORT_SYMBOL(drm_warn_on_modeset_not_all_locked); + /* Avoid boilerplate. I'm tired of typing. */ #define DRM_ENUM_NAME_FN(fnname, list) \ char *fnname(int val) \ @@ -1982,9 +1996,9 @@ int drm_mode_setplane(struct drm_device *dev, void *data, plane_req->src_w, plane_req->src_h); if (!ret) { old_fb = plane->fb; - fb = NULL; plane->crtc = crtc; plane->fb = fb; + fb = NULL; } drm_modeset_unlock_all(dev); @@ -3778,6 +3792,13 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, /* Keep the old fb, don't unref it. */ old_fb = NULL; } else { + /* + * Warn if the driver hasn't properly updated the crtc->fb + * field to reflect that the new framebuffer is now used. + * Failing to do so will screw with the reference counting + * on framebuffers. + */ + WARN_ON(crtc->fb != fb); /* Unref only the old framebuffer. */ fb = NULL; } |