netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Salvatore Dipietro <dipiets@amazon.com>
To: <edumazet@google.com>, <davem@davemloft.net>,
	<dsahern@kernel.org>, <kuba@kernel.org>, <pabeni@redhat.com>
Cc: <netdev@vger.kernel.org>, <blakgeof@amazon.com>,
	<alisaidi@amazon.com>, <benh@amazon.com>,
	<dipietro.salvatore@gmail.com>,
	Salvatore Dipietro <dipiets@amazon.com>
Subject: [PATCH] tcp: disable tcp_autocorking for socket when TCP_NODELAY flag is set
Date: Fri, 8 Dec 2023 10:20:49 -0800	[thread overview]
Message-ID: <20231208182049.33775-1-dipiets@amazon.com> (raw)

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


             reply	other threads:[~2023-12-08 18:23 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-08 18:20 Salvatore Dipietro [this message]
2023-12-09 11:03 ` [PATCH] tcp: disable tcp_autocorking for socket when TCP_NODELAY flag is set 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

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=20231208182049.33775-1-dipiets@amazon.com \
    --to=dipiets@amazon.com \
    --cc=alisaidi@amazon.com \
    --cc=benh@amazon.com \
    --cc=blakgeof@amazon.com \
    --cc=davem@davemloft.net \
    --cc=dipietro.salvatore@gmail.com \
    --cc=dsahern@kernel.org \
    --cc=edumazet@google.com \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@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.
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).