nvidia-drm: propagate errno from semaphore surface fence wait ioctl - #1318
Open
VaggelisGian wants to merge 1 commit into
Open
nvidia-drm: propagate errno from semaphore surface fence wait ioctl#1318VaggelisGian wants to merge 1 commit into
VaggelisGian wants to merge 1 commit into
Conversation
nv_drm_semsurf_fence_wait_ioctl() initializes ret to -EINVAL and sets it to 0 on the success paths, but ends in a bare return 0. Every validation failure (non-monotonic wait values, unknown fence context handle, wrong context type, allocation failure, invalid sync FD) logs an error and then reports success to userspace even though no wait was registered with RM. A caller that trusts the return value believes its wait is armed; the semaphore it waits on is never signaled and the caller hangs (NVIDIA#1297). Return ret instead. The success paths still return 0, including the deliberate proceed-as-signaled path where dma_fence_add_callback() failed after the wait was registered with RM, and the early -EOPNOTSUPP check is unchanged. Sibling ioctls in this file already propagate their errno the same way. Test Plan: No build or runtime test possible in the preparation environment (no Linux kernel toolchain, no NVIDIA GPU). Verified statically: git diff --stat : 1 file changed, 1 insertion(+), 1 deletion(-) Traced all eight paths through the function: error paths reach done: with ret == -EINVAL while wait_data is NULL or unshared, success paths set ret = 0 before the label, and the callback- registration-failure path resets ret to 0 after running the work callback inline, so no double free and no success-path change.
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Found while investigating #1297.
Problem
nv_drm_semsurf_fence_wait_ioctl()initializesret = -EINVAL, sets it to 0 on success paths, but then ends in a barereturn 0. Every validation failure logs an error and reports success to userspace even though no wait was registered with RM:pre_wait_value >= post_wait_valuenv_drm_sync_file_get_fence()returned NULL)A caller that trusts the return value believes its wait is armed. The semaphore it waits on is never signaled, and the caller hangs. This is exactly the sequence in #1297's log:
Attempt to wait on invalid sync FD: 1511followed by a hung render thread.Every sibling ioctl in the file (
SEMSURF_FENCE_CREATE,SEMSURF_FENCE_ATTACH, the prime fence ioctls) propagates its errno the same way this one already computes but discards it, and the first check in this very function (pDevice == NULL) already returns-EOPNOTSUPP.Change
One line:
done:now doesreturn ret;.dma_fence_add_callback()fails after the wait was registered with RM (there the wait IS registered, so reporting success is correct).-EINVAL; no path changes from nonzero to zero.wait_datais NULL or freshly allocated and unshared when it is freed; the inline work-callback path resetsret = 0before the label.Test Plan
Prepared on Windows without Linux kernel toolchain or NVIDIA GPU, so no build and no runtime test were possible; verification was static:
Traced all eight paths through the function for
ret/wait_datastate at the label, confirmed the sole caller is the DRM ioctl dispatch table, and searched open-source userspace (Mesa, libdrm, Proton ecosystem) for callers ofDRM_IOCTL_NVIDIA_SEMSURF_FENCE_WAIT: none found outside header vendoring, so the only caller affected is NVIDIA's own userspace, which already handles nonzero returns from this same function. A repro of #1297 with the patched module should show the game receiving an error at wait time instead of hanging.