Skip to content

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

Merged
copybara-service[bot] merged 1 commit intogoogle:masterfrom
tanyifeng:poll-revents-writeback
Apr 9, 2026
Merged

poll: Write back only revents to userspace, matching Linux behavior#12851
copybara-service[bot] merged 1 commit intogoogle:masterfrom
tanyifeng:poll-revents-writeback

Conversation

@tanyifeng
Copy link
Copy Markdown
Contributor

@tanyifeng tanyifeng commented Apr 2, 2026

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: write back only the 2-byte revents field per fd in doPoll().

@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

@tanyifeng tanyifeng force-pushed the poll-revents-writeback branch from 7cc0267 to 6529fb0 Compare April 7, 2026 06:41
@tanyifeng tanyifeng force-pushed the poll-revents-writeback branch from 6529fb0 to 23ed484 Compare April 8, 2026 11:30
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: write back only the 2-byte revents field per fd in doPoll().

Signed-off-by: Tan Yifeng <yiftan@tencent.com>
@tanyifeng tanyifeng force-pushed the poll-revents-writeback branch from 23ed484 to 3169ea6 Compare April 8, 2026 11:31
copybara-service bot pushed a commit that referenced this pull request Apr 8, 2026
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: write back only the 2-byte revents field per fd in doPoll().
FUTURE_COPYBARA_INTEGRATE_REVIEW=#12851 from tanyifeng:poll-revents-writeback 3169ea6
PiperOrigin-RevId: 896548818
copybara-service bot pushed a commit that referenced this pull request Apr 8, 2026
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: write back only the 2-byte revents field per fd in doPoll().
FUTURE_COPYBARA_INTEGRATE_REVIEW=#12851 from tanyifeng:poll-revents-writeback 3169ea6
PiperOrigin-RevId: 896548818
copybara-service bot pushed a commit that referenced this pull request Apr 8, 2026
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: write back only the 2-byte revents field per fd in doPoll().
FUTURE_COPYBARA_INTEGRATE_REVIEW=#12851 from tanyifeng:poll-revents-writeback 3169ea6
PiperOrigin-RevId: 896548818
copybara-service bot pushed a commit that referenced this pull request Apr 8, 2026
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: write back only the 2-byte revents field per fd in doPoll().
FUTURE_COPYBARA_INTEGRATE_REVIEW=#12851 from tanyifeng:poll-revents-writeback 3169ea6
PiperOrigin-RevId: 896548818
copybara-service bot pushed a commit that referenced this pull request Apr 8, 2026
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: write back only the 2-byte revents field per fd in doPoll().
FUTURE_COPYBARA_INTEGRATE_REVIEW=#12851 from tanyifeng:poll-revents-writeback 3169ea6
PiperOrigin-RevId: 896650914
copybara-service bot pushed a commit that referenced this pull request Apr 8, 2026
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: write back only the 2-byte revents field per fd in doPoll().
FUTURE_COPYBARA_INTEGRATE_REVIEW=#12851 from tanyifeng:poll-revents-writeback 3169ea6
PiperOrigin-RevId: 896650914
copybara-service bot pushed a commit that referenced this pull request Apr 8, 2026
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: write back only the 2-byte revents field per fd in doPoll().
FUTURE_COPYBARA_INTEGRATE_REVIEW=#12851 from tanyifeng:poll-revents-writeback 3169ea6
PiperOrigin-RevId: 896650914
copybara-service bot pushed a commit that referenced this pull request Apr 8, 2026
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: write back only the 2-byte revents field per fd in doPoll().
FUTURE_COPYBARA_INTEGRATE_REVIEW=#12851 from tanyifeng:poll-revents-writeback 3169ea6
PiperOrigin-RevId: 896650914
copybara-service bot pushed a commit that referenced this pull request Apr 9, 2026
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: write back only the 2-byte revents field per fd in doPoll().
FUTURE_COPYBARA_INTEGRATE_REVIEW=#12851 from tanyifeng:poll-revents-writeback 3169ea6
PiperOrigin-RevId: 896650914
copybara-service bot pushed a commit that referenced this pull request Apr 9, 2026
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: write back only the 2-byte revents field per fd in doPoll().
FUTURE_COPYBARA_INTEGRATE_REVIEW=#12851 from tanyifeng:poll-revents-writeback 3169ea6
PiperOrigin-RevId: 896650914
@copybara-service copybara-service bot merged commit 217f4bf into google:master Apr 9, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants