aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2025-02-16 08:16:33 +0100
committerStefano Brivio <sbrivio@redhat.com>2025-02-17 08:27:30 +0100
commit667caa09c6d46d937b3076254176eded262b3eca (patch)
treefc8cfbf3de22a02a7055a1d6ec742d62721e78cf
parent7c33b1208632a9581d0ee7aabd1e0584a5d1fb20 (diff)
downloadpasst-667caa09c6d46d937b3076254176eded262b3eca.tar
passt-667caa09c6d46d937b3076254176eded262b3eca.tar.gz
passt-667caa09c6d46d937b3076254176eded262b3eca.tar.bz2
passt-667caa09c6d46d937b3076254176eded262b3eca.tar.lz
passt-667caa09c6d46d937b3076254176eded262b3eca.tar.xz
passt-667caa09c6d46d937b3076254176eded262b3eca.tar.zst
passt-667caa09c6d46d937b3076254176eded262b3eca.zip
tcp_splice: Don't wake up on input data if we can't write it anywhere
If we set the OUT_WAIT_* flag (waiting on EPOLLOUT) for a side of a given flow, it means that we're blocked, waiting for the receiver to actually receive data, with a full pipe. In that case, if we keep EPOLLIN set for the socket on the other side (our receiving side), we'll get into a loop such as: 41.0230: pasta: epoll event on connected spliced TCP socket 108 (events: 0x00000001) 41.0230: Flow 1 (TCP connection (spliced)): -1 from read-side call 41.0230: Flow 1 (TCP connection (spliced)): -1 from write-side call (passed 8192) 41.0230: Flow 1 (TCP connection (spliced)): event at tcp_splice_sock_handler:577 41.0230: pasta: epoll event on connected spliced TCP socket 108 (events: 0x00000001) 41.0230: Flow 1 (TCP connection (spliced)): -1 from read-side call 41.0230: Flow 1 (TCP connection (spliced)): -1 from write-side call (passed 8192) 41.0230: Flow 1 (TCP connection (spliced)): event at tcp_splice_sock_handler:577 leading to 100% CPU usage, of course. Drop EPOLLIN on our receiving side as long when we're waiting for output readiness on the other side. Link: https://github.com/containers/podman/issues/23686#issuecomment-2661036584 Link: https://www.reddit.com/r/podman/comments/1iph50j/pasta_high_cpu_on_podman_rootless_container/ Reviewed-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--tcp_splice.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/tcp_splice.c b/tcp_splice.c
index f1a9223..8a39a6f 100644
--- a/tcp_splice.c
+++ b/tcp_splice.c
@@ -131,8 +131,12 @@ static void tcp_splice_conn_epoll_events(uint16_t events,
ev[1].events = EPOLLOUT;
}
- flow_foreach_sidei(sidei)
- ev[sidei].events |= (events & OUT_WAIT(sidei)) ? EPOLLOUT : 0;
+ flow_foreach_sidei(sidei) {
+ if (events & OUT_WAIT(sidei)) {
+ ev[sidei].events |= EPOLLOUT;
+ ev[!sidei].events &= ~EPOLLIN;
+ }
+ }
}
/**