@@ -1085,6 +1085,26 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
goto put_vblank;
}
+ if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
+ e = kzalloc(sizeof *e, GFP_KERNEL);
+ if (!e) {
+ ret = -ENOMEM;
+ goto put_fb;
+ }
+
+ e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
+ e->event.base.length = sizeof(e->event);
+ e->event.vbl.user_data = page_flip->user_data;
+ e->event.vbl.crtc_id = crtc->base.id;
+
+ ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base);
+ if (ret) {
+ kfree(e);
+ e = NULL;
+ goto put_fb;
+ }
+ }
+
drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
retry:
ret = drm_modeset_lock(&crtc->mutex, &ctx);
@@ -1129,26 +1149,6 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
goto out;
}
- if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
- e = kzalloc(sizeof *e, GFP_KERNEL);
- if (!e) {
- ret = -ENOMEM;
- goto out;
- }
-
- e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
- e->event.base.length = sizeof(e->event);
- e->event.vbl.user_data = page_flip->user_data;
- e->event.vbl.crtc_id = crtc->base.id;
-
- ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base);
- if (ret) {
- kfree(e);
- e = NULL;
- goto out;
- }
- }
-
plane->old_fb = plane->fb;
if (crtc->funcs->page_flip_target)
ret = crtc->funcs->page_flip_target(crtc, fb, e,
@@ -1159,8 +1159,6 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags,
&ctx);
if (ret) {
- if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT)
- drm_event_cancel_free(dev, &e->base);
/* Keep the old fb, don't unref it. */
plane->old_fb = NULL;
} else {
@@ -1184,6 +1182,9 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
+ if (ret && e)
+ drm_event_cancel_free(dev, &e->base);
+put_fb:
drm_framebuffer_put(fb);
put_vblank:
if (ret && crtc->funcs->page_flip_target)