diff options
Diffstat (limited to 'drivers/gpu/drm/drm_atomic_helper.c')
-rw-r--r-- | drivers/gpu/drm/drm_atomic_helper.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index ab4032167094..ae3cbfe9e01c 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c | |||
@@ -1878,6 +1878,8 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, | |||
1878 | new_crtc_state->event->base.completion = &commit->flip_done; | 1878 | new_crtc_state->event->base.completion = &commit->flip_done; |
1879 | new_crtc_state->event->base.completion_release = release_crtc_commit; | 1879 | new_crtc_state->event->base.completion_release = release_crtc_commit; |
1880 | drm_crtc_commit_get(commit); | 1880 | drm_crtc_commit_get(commit); |
1881 | |||
1882 | commit->abort_completion = true; | ||
1881 | } | 1883 | } |
1882 | 1884 | ||
1883 | for_each_oldnew_connector_in_state(state, conn, old_conn_state, new_conn_state, i) { | 1885 | for_each_oldnew_connector_in_state(state, conn, old_conn_state, new_conn_state, i) { |
@@ -3421,8 +3423,21 @@ EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state); | |||
3421 | void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state) | 3423 | void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state) |
3422 | { | 3424 | { |
3423 | if (state->commit) { | 3425 | if (state->commit) { |
3426 | /* | ||
3427 | * In the event that a non-blocking commit returns | ||
3428 | * -ERESTARTSYS before the commit_tail work is queued, we will | ||
3429 | * have an extra reference to the commit object. Release it, if | ||
3430 | * the event has not been consumed by the worker. | ||
3431 | * | ||
3432 | * state->event may be freed, so we can't directly look at | ||
3433 | * state->event->base.completion. | ||
3434 | */ | ||
3435 | if (state->event && state->commit->abort_completion) | ||
3436 | drm_crtc_commit_put(state->commit); | ||
3437 | |||
3424 | kfree(state->commit->event); | 3438 | kfree(state->commit->event); |
3425 | state->commit->event = NULL; | 3439 | state->commit->event = NULL; |
3440 | |||
3426 | drm_crtc_commit_put(state->commit); | 3441 | drm_crtc_commit_put(state->commit); |
3427 | } | 3442 | } |
3428 | 3443 | ||