Don't update the file state in socket.c#3277
Merged
stevenengler merged 2 commits intoshadow:mainfrom Jan 12, 2024
Merged
Conversation
84f77e5 to
b53e917
Compare
In the old code when adding or removing data from a socket buffer, a socket.c function would update the file state (called the "status" in the C code), then a tcp.c function might also update the file state. For example `tcp_receiveUserData` would call `legacysocket_removeFromInputBuffer` which would update the state, and then `tcp_receiveUserData` would later also update the state. This would lead to situations where socket.c would remove the READABLE flag, and then tcp.c would immediately add it back. While the end result is that the flag would effectively appear unchanged, this would cause edge-triggered epoll to think that the file's state changed twice even though it effectively didn't, leading to issue 3274. Since the TCP code is the only C socket code left, now the socket.c code no longer updates the file state (with an exception of `legacysocket_pullOutPacket`) and the tcp.c code is responsible for updating the file state.
This test was authored by @ppopth in issue 3274 and added here with minor changes.
b53e917 to
974f62f
Compare
Contributor
Author
|
Hopefully this PR is correct. I looked it over and I think it's okay. The simulation runtime performance is the same, but the results change slightly. I think this is expected. |
robgjansen
approved these changes
Jan 12, 2024
Member
robgjansen
left a comment
There was a problem hiding this comment.
Looks good! I agree that the epoll events should be processed in a different order than they previously were, which would cause the sim results to be nondeterministic.
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.




In the old code when adding or removing data from a socket buffer, a socket.c function would update the file state (called the "status" in the C code), then a tcp.c function might also update the file state. For example
tcp_receiveUserDatawould calllegacysocket_removeFromInputBufferwhich would update the state, and thentcp_receiveUserDatawould later also update the state. This would lead to situations where socket.c would remove the READABLE flag, and then tcp.c would immediately add it back. While the end result is that the flag would effectively appear unchanged, this would cause edge-triggered epoll to think that the file's state changed twice even though it effectively didn't, leading to #3274.Since the TCP code is the only C socket code left, now the socket.c code no longer updates the file state (with an exception of
legacysocket_pullOutPacket) and the tcp.c code is responsible for updating the file state.The added test was authored by @ppoth in #3274.
We should also be testing other socket/file types, but I think this will be easier once the new
test_epoll_edge.rstests in #3243 are merged. I did test udp and unix sockets manually and the new test passes for them as well.Closes #3274.
Edit: The runtime performance is equivalent, but the simulation results change, so I want to take another look at this. https://github.com/shadow/benchmark-results/blob/master/tor/2024-01-07-T22-11-55/README.md
Edit 2: I think it's expected that the simulation results would change. Before we would remove the
READABLEflag and then add it back again, which would reset the epoll entry's priority each time a packet was pushed to a TCP socket. Now the priority is reset only when the event is collected. This means that epoll events will be processed in a different order than they previously were.