During page flip atomic_check and atomic_commit can return -ERESTARTSYS to restart the ioctl. When this happens we fail to put the commit object leading to a memory leak. Signed-off-by: Jerry Zuo <Jerry.Zuo at amd.com> --- drivers/gpu/drm/drm_atomic.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index f32506a7c1d6..f2f623dacf90 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1642,14 +1642,35 @@ int drm_atomic_nonblocking_commit(struct drm_atomic_state *state) { struct drm_mode_config *config = &state->dev->mode_config; int ret; + int i; + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; ret = drm_atomic_check_only(state); - if (ret) + if (ret) { + if (ret == -ERESTARTSYS) + goto fail; + return ret; + } DRM_DEBUG_ATOMIC("commiting %p nonblocking\n", state); - return config->funcs->atomic_commit(state->dev, state, true); + ret = config->funcs->atomic_commit(state->dev, state, true); + if (ret == -ERESTARTSYS) + goto fail; + + return ret; + + /* cleanup commit object if commit fails with ERESTARTSYS */ +fail: + for_each_crtc_in_state(state, crtc, crtc_state, i) { + if (state->crtcs[i].commit) { + drm_crtc_commit_put(state->crtcs[i].commit); + } + } + + return ret; } EXPORT_SYMBOL(drm_atomic_nonblocking_commit); -- 2.11.0