netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] tcp: disable tcp_autocorking for socket when TCP_NODELAY flag is set
@ 2023-12-08 18:20 Salvatore Dipietro
  2023-12-09 11:03 ` Eric Dumazet
                   ` (2 more replies)
  0 siblings, 3 replies; 28+ messages in thread
From: Salvatore Dipietro @ 2023-12-08 18:20 UTC (permalink / raw)
  To: edumazet, davem, dsahern, kuba, pabeni
  Cc: netdev, blakgeof, alisaidi, benh, dipietro.salvatore,
	Salvatore Dipietro

Based on the tcp man page, if TCP_NODELAY is set, it disables Nagle's algorithm
and packets are sent as soon as possible. However in the `tcp_push` function
where autocorking is evaluated the `nonagle` value set by TCP_NODELAY is not
considered which can trigger unexpected corking of packets and induce delays.

For example, if two packets are generated as part of a server's reply, if the
first one is not transmitted on the wire quickly enough, the second packet can
trigger the autocorking in `tcp_push` and be delayed instead of sent as soon as
possible. It will either wait for additional packets to be coalesced or an ACK
from the client before transmitting the corked packet. This can interact badly
if the receiver has tcp delayed acks enabled, introducing 40ms extra delay in
completion times. It is not always possible to control who has delayed acks
set, but it is possible to adjust when and how autocorking is triggered.
Patch prevents autocorking if the TCP_NODELAY flag is set on the socket.

Patch has been tested using an AWS c7g.2xlarge instance with Ubuntu 22.04 and
Apache Tomcat 9.0.83 running the basic servlet below:

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloWorldServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        OutputStreamWriter osw = new OutputStreamWriter(response.getOutputStream(),"UTF-8");
        String s = "a".repeat(3096);
        osw.write(s,0,s.length());
        osw.flush();
    }
}

Load was applied using  wrk2 (https://github.com/kinvolk/wrk2) from an AWS
c6i.8xlarge instance.  With the current auto-corking behavior and TCP_NODELAY
set an additional 40ms latency from P99.99+ values are observed.  With the
patch applied we see no occurrences of 40ms latencies. The patch has also been
tested with iperf and uperf benchmarks and no regression was observed.

# No patch with tcp_autocorking=1 and TCP_NODELAY set on all sockets
./wrk -t32 -c128 -d40s --latency -R10000  http://172.31.49.177:8080/hello/hello'
  ...
 50.000%    0.91ms
 75.000%    1.12ms
 90.000%    1.46ms
 99.000%    1.73ms
 99.900%    1.96ms
 99.990%   43.62ms   <<< 40+ ms extra latency
 99.999%   48.32ms
100.000%   49.34ms

# With patch
./wrk -t32 -c128 -d40s --latency -R10000  http://172.31.49.177:8080/hello/hello'
  ...
 50.000%    0.89ms
 75.000%    1.13ms
 90.000%    1.44ms
 99.000%    1.67ms
 99.900%    1.78ms
 99.990%    2.27ms   <<< no 40+ ms extra latency
 99.999%    3.71ms
100.000%    4.57ms

Signed-off-by: Salvatore Dipietro <dipiets@amazon.com>
---
 net/ipv4/tcp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index d3456cf840de..87751a2a6fff 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -716,7 +716,7 @@ void tcp_push(struct sock *sk, int flags, int mss_now,
 
 	tcp_mark_urg(tp, flags);
 
-	if (tcp_should_autocork(sk, skb, size_goal)) {
+	if (!nonagle && tcp_should_autocork(sk, skb, size_goal)) {
 
 		/* avoid atomic op if TSQ_THROTTLED bit is already set */
 		if (!test_bit(TSQ_THROTTLED, &sk->sk_tsq_flags)) {
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2024-04-22 16:17 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-08 18:20 [PATCH] tcp: disable tcp_autocorking for socket when TCP_NODELAY flag is set Salvatore Dipietro
2023-12-09 11:03 ` Eric Dumazet
2023-12-11 15:58   ` Hazem Mohamed Abuelfotoh
2023-12-12 10:41     ` Paolo Abeni
2023-12-12 11:29       ` Eric Dumazet
2023-12-12 10:57 ` Paolo Abeni
2023-12-13 14:10   ` Eric Dumazet
2023-12-13 19:00     ` Jakub Kicinski
2023-12-13 19:29       ` Eric Dumazet
2023-12-13 21:30     ` Salvatore Dipietro
2023-12-14  8:40       ` Eric Dumazet
2023-12-14  9:05         ` Eric Dumazet
2023-12-14 14:08       ` Eric Dumazet
2023-12-14 15:52         ` Geoff Blake
2023-12-14 16:07           ` Eric Dumazet
2024-01-17 21:26             ` [PATCH v2] tcp: Add memory barrier to tcp_push() Salvatore Dipietro
2024-01-17 21:58               ` Eric Dumazet
2024-01-17 23:16                 ` [PATCH v3] " Salvatore Dipietro
2024-01-18 10:38                   ` Paolo Abeni
2024-01-18 10:42                     ` Eric Dumazet
2024-01-18 16:40                       ` Jakub Kicinski
2024-01-18 17:46                     ` Geoff Blake
2024-01-18 18:30                       ` Paolo Abeni
2024-01-18 19:30                         ` Geoff Blake
2024-01-19 13:33                           ` Eric Dumazet
2024-04-17  7:33                           ` Eric Dumazet
2024-04-22 16:16                             ` Salvatore Dipietro
2023-12-13 10:40 ` [PATCH] tcp: disable tcp_autocorking for socket when TCP_NODELAY flag is set patchwork-bot+netdevbpf

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 NNTP newsgroup(s).