Skip to content

poll: Write back only revents to userspace, matching Linux behavior#12851

Open
tanyifeng wants to merge 1 commit intogoogle:masterfrom
tanyifeng:poll-revents-writeback
Open

poll: Write back only revents to userspace, matching Linux behavior#12851
tanyifeng wants to merge 1 commit intogoogle:masterfrom
tanyifeng:poll-revents-writeback

Conversation

@tanyifeng
Copy link
Copy Markdown
Contributor

doPoll() was modifying pfd.Events (adding POLLHUP|POLLERR) and writing back the entire pollfd struct. Linux only writes back revents via unsafe_put_user() in do_sys_poll(). The polluted events field broke libevent's poll_del(), causing a busy-loop in tmux (CPU 96.6%).

Fix: use an internal mask for POLLHUP|POLLERR in initReadiness() and pollBlock(); write back only the 2-byte revents field per fd in doPoll().

Test: PollTest.EventsFieldNotModified, PollTest.EventsFieldNotModifiedOnError

doPoll() was modifying pfd.Events (adding POLLHUP|POLLERR) and writing
back the entire pollfd struct. Linux only writes back revents via
unsafe_put_user() in do_sys_poll(). The polluted events field broke
libevent's poll_del(), causing a busy-loop in tmux (CPU 96.6%).

Fix: use an internal mask for POLLHUP|POLLERR in initReadiness() and
pollBlock(); write back only the 2-byte revents field per fd in doPoll().

Test: PollTest.EventsFieldNotModified, PollTest.EventsFieldNotModifiedOnError
Signed-off-by: Tan Yifeng <yiftan@tencent.com>
@tanyifeng
Copy link
Copy Markdown
Contributor Author

Reproduction

# In gVisor (runsc) — CPU spikes to ~95%
docker run -d --name tmux-test --runtime=runsc ubuntu:22.04 sleep 3600
docker exec tmux-test bash -c "apt-get update -qq && apt-get install -y -qq tmux procps >/dev/null 2>&1"
docker exec tmux-test bash -c "tmux new-session -d -s test && sleep 30 && ps aux | grep tmux"
# tmux: 94.7% CPU

# In Linux (runc) — CPU stays at 0%
docker run -d --name tmux-ctrl --runtime=runc ubuntu:22.04 sleep 3600
docker exec tmux-ctrl bash -c "apt-get update -qq && apt-get install -y -qq tmux procps >/dev/null 2>&1"
docker exec tmux-ctrl bash -c "tmux new-session -d -s test && sleep 30 && ps aux | grep tmux"
# tmux: 0.0% CPU

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant