From: David Gibson <david@gibson.dropbear.id.au>
To: passt-dev@passt.top, Stefano Brivio <sbrivio@redhat.com>
Cc: David Gibson <david@gibson.dropbear.id.au>
Subject: [PATCH 3/8] tcp_splice: Improve EOF exit condition for the loop
Date: Thu, 28 May 2026 15:02:08 +1000 [thread overview]
Message-ID: <20260528050213.679685-4-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <20260528050213.679685-1-david@gibson.dropbear.id.au>
In tcp_splice_forward() we exit the forwarding loop if we have an EOF on
the read side. However, this potentially leaves data in the pipe, even if
the write side hasn't yet blocked. It's not clear to me whether this could
leave data indefinitely in the pipe with no events to keep it moving,
but it's not clear to me that it couldn't either.
Stay in the loop until either the write side blocks or we've emptied
the pipe.
Secondly, this test is after several tests on how much we wrote which
might also cause a retry. However, if we've reached EOF and the pipe is
empty, there's nothing more to do, regardless of how much we wrote, so
we should exit, regardless of those conditions. So move this exit test
above the retry conditions.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
tcp_splice.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/tcp_splice.c b/tcp_splice.c
index 25e5d097..943dc214 100644
--- a/tcp_splice.c
+++ b/tcp_splice.c
@@ -543,15 +543,16 @@ retry:
break;
}
+ if (conn->events & FIN_RCVD(fromsidei) &&
+ !conn->pending[fromsidei])
+ break;
+
if (never_read && written == (long)(c->tcp.pipe_size))
goto retry;
if (!never_read && written > 0 &&
written < conn->pending[fromsidei])
goto retry;
-
- if (conn->events & FIN_RCVD(fromsidei))
- break;
}
if (!conn->pending[fromsidei] &&
--
2.54.0
next prev parent reply other threads:[~2026-05-28 5:02 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-28 5:02 [PATCH 0/8] splice() forwarding cleanups David Gibson
2026-05-28 5:02 ` [PATCH 1/8] tcp_splice: Remove never-invoked SO_RCVLOWAT logic David Gibson
2026-05-28 5:02 ` [PATCH 2/8] tcp_splice: Simplify EPOLLRDHUP / eof / FIN handling David Gibson
2026-05-28 5:02 ` David Gibson [this message]
2026-05-28 5:02 ` [PATCH 4/8] tcp_splice: Remove goto from forwarding loop David Gibson
2026-05-28 5:02 ` [PATCH 5/8] tcp_splice: Simplify shutdown(2) handling David Gibson
2026-05-28 5:02 ` [PATCH 6/8] tcp_splice: Simplify / correct OUT_WAIT flag handling David Gibson
2026-05-28 5:02 ` [PATCH 7/8] tcp_splice: Remove questionable "optimisation" of pending bytes tracking David Gibson
2026-05-28 5:02 ` [PATCH 8/8] tcp_splice: Exit forwarding earlier when stalled read side David Gibson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260528050213.679685-4-david@gibson.dropbear.id.au \
--to=david@gibson.dropbear.id.au \
--cc=passt-dev@passt.top \
--cc=sbrivio@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://passt.top/passt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).