Skip to content

Don't update the file state in socket.c#3277

Merged
stevenengler merged 2 commits intoshadow:mainfrom
stevenengler:edge-epoll-fix
Jan 12, 2024
Merged

Don't update the file state in socket.c#3277
stevenengler merged 2 commits intoshadow:mainfrom
stevenengler:edge-epoll-fix

Conversation

@stevenengler
Copy link
Copy Markdown
Contributor

@stevenengler stevenengler commented Jan 7, 2024

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 #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.rs tests 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 READABLE flag 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.

@stevenengler stevenengler self-assigned this Jan 7, 2024
@github-actions github-actions bot added Component: Testing Unit and integration tests and frameworks Component: Main Composing the core Shadow executable labels Jan 7, 2024
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.
@stevenengler
Copy link
Copy Markdown
Contributor Author

stevenengler commented Jan 12, 2024

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.

run_time
ram_simtime
transfer_time_5242880 exit
1705019771_grim

Copy link
Copy Markdown
Member

@robgjansen robgjansen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@stevenengler stevenengler merged commit c0f33f9 into shadow:main Jan 12, 2024
@stevenengler stevenengler deleted the edge-epoll-fix branch January 12, 2024 21:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Component: Main Composing the core Shadow executable Component: Testing Unit and integration tests and frameworks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Partial read triggers an event in Shadow, but not Linux

2 participants