From 57606c7aa1155ae9e475e173ce6cb0e316912796 Mon Sep 17 00:00:00 2001 From: Kevin Krakauer Date: Fri, 20 Oct 2023 10:32:43 -0700 Subject: [PATCH] tcp_benchmark: prevent "cheating" with splice tcp_benchmark is trying to measure the performance of using netstack vs Linux networking. However, Go tries (succeeds) to be smart and figures out it can use splice() to copy between sockets, increasing throughput. That, however, just distorts the benchmark: netstack copies those bytes. In regular use this isn't an issue because netstack isn't hooked up to two sockets, it's hooked up to one socket and one userspace process (usually the sentry). PiperOrigin-RevId: 575257650 --- test/benchmarks/tcp/tcp_proxy.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/test/benchmarks/tcp/tcp_proxy.go b/test/benchmarks/tcp/tcp_proxy.go index d6082a0aa..11ff1473f 100644 --- a/test/benchmarks/tcp/tcp_proxy.go +++ b/test/benchmarks/tcp/tcp_proxy.go @@ -509,9 +509,14 @@ func main() { } log.Printf("incoming connection established.") - // Copy both ways. - go io.Copy(inConn, next) - go io.Copy(next, inConn) + // Copy both ways. We wrap everything in another + // Reader/Writer to prevent optimizations that + // otherwise call splice() to move data between + // sockets. That penalizes netstack, but isn't relevant + // to real use cases where only one end of netstack is + // attached to a socket. + go io.Copy(io.MultiWriter(inConn), io.MultiReader(next)) + go io.Copy(io.MultiWriter(next), io.MultiReader(inConn)) // Print stats every second. go func() {