SUNRPC: Set the TCP_SYNCNT to match the socket timeout
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Sat, 19 Aug 2023 21:32:21 +0000 (17:32 -0400)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Thu, 24 Aug 2023 17:24:15 +0000 (13:24 -0400)
Set the TCP SYN count so that we abort the connection attempt at around
the expected timeout value.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
net/sunrpc/xprtsock.c

index 9f010369100a206ea9e51d7d84324c13853053ef..47d0b6a8c32e53b011b62ca7c5a498d2daf09248 100644 (file)
@@ -2230,9 +2230,13 @@ static void xs_tcp_set_socket_timeouts(struct rpc_xprt *xprt,
                struct socket *sock)
 {
        struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
+       struct net *net = sock_net(sock->sk);
+       unsigned long connect_timeout;
+       unsigned long syn_retries;
        unsigned int keepidle;
        unsigned int keepcnt;
        unsigned int timeo;
+       unsigned long t;
 
        spin_lock(&xprt->transport_lock);
        keepidle = DIV_ROUND_UP(xprt->timeout->to_initval, HZ);
@@ -2250,6 +2254,16 @@ static void xs_tcp_set_socket_timeouts(struct rpc_xprt *xprt,
 
        /* TCP user timeout (see RFC5482) */
        tcp_sock_set_user_timeout(sock->sk, timeo);
+
+       /* Connect timeout */
+       connect_timeout = max_t(unsigned long,
+                               DIV_ROUND_UP(xprt->connect_timeout, HZ), 1);
+       syn_retries = max_t(unsigned long,
+                           READ_ONCE(net->ipv4.sysctl_tcp_syn_retries), 1);
+       for (t = 0; t <= syn_retries && (1UL << t) < connect_timeout; t++)
+               ;
+       if (t <= syn_retries)
+               tcp_sock_set_syncnt(sock->sk, t - 1);
 }
 
 static void xs_tcp_set_connect_timeout(struct rpc_xprt *xprt,