Uh oh!
There was an error while loading. Please reload this page.
Conversation
The gate classifies a function when it names EINTR, calls syscall_restart_forbid, or calls a name in its wait-helper list. That list held one name. Everything reaching a wait through io_xfer, io_retry_backoff or net_wait_or_interrupted therefore decided the restart question outside the gate's view: the receive half of the socket layer, the read and write path, flock, semop and splice among them. Deriving the list from a naming convention was tried first and does not hold. The tree disagrees with any suffix rule in both directions. connect_or_interrupted carries the suffix, while net_recv_zero_payload_gate and io_xfer do not and report EINTR upward all the same. Derivation also means deleting an inventory entry shrinks the regex, which is the gate going quiet at the moment it should complain. The list is spelled out instead, under two assertions: it may not be empty, since the empty alternation matches every call in the tree and buries the answer under a thousand unclassified functions, and every name in it has to carry a classification of its own. sys_recvmmsg forbade the restart only when its own poll returned EINTR, which is the single case where the timeout had not been spent. The case that matters is the other one: a poll that reports readable after most of the interval, a sibling that takes the datagram, and an interrupted wait inside the first sys_recvmsg reaching the guest as EINTR with nothing received. The restart re-runs the call with the full timeout. The forbid is unconditional now, so every exit past the poll inherits it. proc_wait_autoreap_children forbids as well, because its loop can reap an exited child before the backoff reports EINTR. Whether that is a consumption the restart cannot recover is arguable in the other direction: the rescan skips entries it has already marked inactive and reaches the same ECHILD, which is what POSIX gives a waiter under SA_NOCLDWAIT once the children are gone. Recorded here as the conservative reading.
Uh oh!
There was an error while loading. Please reload this page.
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 freeto 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.
The gate classifies a function when it names EINTR, calls syscall_restart_forbid, or calls a name in its wait-helper list. That list held one name. Everything reaching a wait through io_xfer, io_retry_backoff or net_wait_or_interrupted therefore decided the restart question outside the gate's view: the receive half of the socket layer, the read and write path, flock, semop and splice among them.
Deriving the list from a naming convention was tried first and does not hold. The tree disagrees with any suffix rule in both directions. connect_or_interrupted carries the suffix, while
net_recv_zero_payload_gate and io_xfer do not and report EINTR upward all the same. Derivation also means deleting an inventory entry shrinks the regex, which is the gate going quiet at the moment it should complain. The list is spelled out instead, under two assertions: it may not be empty, since the empty alternation matches every call in the tree and buries the answer under a thousand unclassified functions, and every name in it has to carry a classification of its own.
sys_recvmmsg forbade the restart only when its own poll returned EINTR, which is the single case where the timeout had not been spent. The case that matters is the other one: a poll that reports readable after most of the interval, a sibling that takes the datagram, and an interrupted wait inside the first sys_recvmsg reaching the guest as EINTR with nothing received. The restart re-runs the call with the full timeout. The forbid is unconditional now, so every exit past the poll inherits it.
proc_wait_autoreap_children forbids as well, because its loop can reap an exited child before the backoff reports EINTR. Whether that is a consumption the restart cannot recover is arguable in the other direction: the rescan skips entries it has already marked inactive and reaches the same ECHILD, which is what POSIX gives a waiter under SA_NOCLDWAIT once the children are gone. Recorded here as the conservative reading.
Summary by cubic
Widened the EINTR gate to cover waits reached via common helpers and tightened restart semantics where timeouts or state can be consumed. Previously the gate only saw direct EINTR mentions or a single wait helper; now it enumerates helpers explicitly and asserts coverage. Behavior changes: sys_recvmmsg used to forbid restart only when its poll returned EINTR; it now forbids restart for every exit after the poll to avoid resetting a relative timeout. proc_wait_autoreap_children now forbids restart on interrupted waits to avoid observing different process state.
Reviewer notes
Written for commit 74c4402. Summary will update on new commits.