drm: Fix drm_crtc_commit leak if signaled when PAGE_FLIP_EVENT is used

Commit 1c6ceeee6e ("drm/atomic: Fix memleak on ERESTARTSYS during
non-blocking commits") fixed a very similar issue when the event was
allocated by drm_atomic_helper_setup_commit() itself.

However, if the event is allocated in prepare_signaling(), it will also be
set to NULL in complete_signaling(), which prevents drm_crtc_commit from
being put in __drm_atomic_helper_crtc_destroy_state().

Dropping the reference when the event is set to NULL at
complete_signaling() fixes the leak.

The leak can be reproduced by sending a signal to the thread using
DRM_MODE_PAGE_FLIP_EVENT and using a sw_sync fence to cause the atomic
ioctl to block at drm_atomic_helper_wait_for_fences(). It happened both
with amdgpu and vkms.

Fixes: 24835e442f ("drm: reference count event->completion")
Cc: stable@vger.kernel.org
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
Reviewed-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
Link: https://patch.msgid.link/20260727-drm_crtc_atomic_commit_leak-v1-1-23d9948a9d7c@igalia.com
This commit is contained in:
Thadeu Lima de Souza Cascardo 2026-07-27 17:45:49 -03:00 committed by Melissa Wen
parent d32b08284f
commit 4d4be20216

View File

@ -1560,6 +1560,8 @@ static void complete_signaling(struct drm_device *dev,
* to prevent a double free in drm_atomic_commit_clear.
*/
if (event && (event->base.fence || event->base.file_priv)) {
if (crtc_state->commit && crtc_state->commit->abort_completion)
drm_crtc_commit_put(crtc_state->commit);
drm_event_cancel_free(dev, &event->base);
crtc_state->event = NULL;
}