diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 8535dc17db7e9502d14c9ea40b65b0e3e7830118..62e833ffeffdfcd57af7621bfc34690afaeec20a 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -803,6 +803,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, struct drm_framebuffer *fb = NULL; struct drm_pending_vblank_event *e = NULL; u32 target_vblank = page_flip->sequence; + struct drm_modeset_acquire_ctx ctx; int ret = -EINVAL; if (!drm_core_check_feature(dev, DRIVER_MODESET)) @@ -866,7 +867,16 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, return -EINVAL; } - drm_modeset_lock_crtc(crtc, crtc->primary); + drm_modeset_acquire_init(&ctx, 0); +retry: + ret = drm_modeset_lock(&crtc->mutex, &ctx); + if (ret) + goto out; + ret = drm_modeset_lock(&crtc->cursor->mutex, &ctx); + if (ret) + goto out; + crtc->acquire_ctx = &ctx; + if (crtc->primary->fb == NULL) { /* The framebuffer is currently unbound, presumably * due to a hotplug event, that userspace has not @@ -944,7 +954,14 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, if (crtc->primary->old_fb) drm_framebuffer_put(crtc->primary->old_fb); crtc->primary->old_fb = NULL; - drm_modeset_unlock_crtc(crtc); + + if (ret == -EDEADLK) { + drm_modeset_backoff(&ctx); + goto retry; + } + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); return ret; }