From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: passt.top; dkim=pass (2048-bit key; secure) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.a=rsa-sha256 header.s=202602 header.b=g5zjUppy; dkim-atps=neutral Received: from mail.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id 430C05A0265 for ; Thu, 28 May 2026 07:02:18 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202602; t=1779944535; bh=r7q+/n8AATNAQRzHjjvBS8APt18woh2QdTzFcyEDESM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=g5zjUppyjlqIAEVgYDdDxKGy+n6vFTi0wGE02x7PfhafSIefybIwrV92cUT52mee1 CG2olGHmH5HFOxP4vCnh0Fwn/dYQZVE07NUh/nIDp3ZYEMjWVGs7i8VaEOqBtavVIT gPqGwlqXYt8okxEsyPey3Ez5rG5CDD8QeztJEqFS751OkLfFcbNwmNNdrtPG0apGyU HDcMBfgcQH7gb24o0lrX9TQ069TXC5R3ThiKHB987c1QRsAuUgFuOpQWizmx8dJOaw O+KsGn0iV3njCn0ysTi056UpLH/q57HOl8Y4rlPN1GKKl9tHYjf7miUIfv4+yUGVNv GfGixaZP736Rg== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4gQvVb0Dzfz4wLr; Thu, 28 May 2026 15:02:15 +1000 (AEST) From: David Gibson To: passt-dev@passt.top, Stefano Brivio Subject: [PATCH 4/8] tcp_splice: Remove goto from forwarding loop Date: Thu, 28 May 2026 15:02:09 +1000 Message-ID: <20260528050213.679685-5-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260528050213.679685-1-david@gibson.dropbear.id.au> References: <20260528050213.679685-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: ROP4H3TRSJNEU4GXAVYFPYQ3S7GRHI4N X-Message-ID-Hash: ROP4H3TRSJNEU4GXAVYFPYQ3S7GRHI4N X-MailFrom: dgibson@gandalf.ozlabs.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: David Gibson X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: The forwarding look in tcp_splice_forward() has a retry label that we goto in some cases. However, the only difference between a 'goto retry' and a 'continue' is that the 'continue' will reset the 'more' variable to 0. The fist goto retry only occurs if never_read is set, which can only be the case if we never changed 'more' in the first place, so is strictly equivalent to a continue. In the second case, 'more' can be set though. 'more' is set by a heuristic that if we're able to read most of a pipe's worth of data at once, there's probably more coming, so we should prepare the write-side for that. However, on a goto retry we have a new read side splice. If this time we *don't* get most of a pipe's worth of data, that suggests that contrary to expectations from the previous loop we have now temporarily run out of input data and so SPLICE_F_MORE is no longer a good guess for the next write side splice(). In other words, the second read-splice() gives us better data for the heuristic than keeping our guess from the first one, so resetting 'more' is valuable. So, we could replace both gotos with continues. But they're already at the end the loop body, so a continue is a no-op. Just remove them. That, in turn removes the need for the never_read variable. Signed-off-by: David Gibson --- tcp_splice.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tcp_splice.c b/tcp_splice.c index 943dc214..8c8e3bbb 100644 --- a/tcp_splice.c +++ b/tcp_splice.c @@ -476,13 +476,11 @@ static int tcp_splice_forward(struct ctx *c, { uint8_t lowat_set_flag = RCVLOWAT_SET(fromsidei); uint8_t lowat_act_flag = RCVLOWAT_ACT(fromsidei); - int never_read = 1; while (1) { ssize_t readlen, written; int more = 0; -retry: do readlen = splice(conn->s[fromsidei], NULL, conn->pipe[fromsidei][1], NULL, @@ -502,8 +500,6 @@ retry: if (!readlen) { conn_event(conn, FIN_RCVD(fromsidei)); } else if (readlen > 0) { - never_read = 0; - if (readlen >= (long)c->tcp.pipe_size * 90 / 100) more = SPLICE_F_MORE; @@ -546,13 +542,6 @@ retry: 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->pending[fromsidei] && -- 2.54.0