rds: tcp: set linger to 1 when unloading a rds-tcp
authorSowmini Varadhan <sowmini.varadhan@oracle.com>
Wed, 21 Jun 2017 20:40:13 +0000 (13:40 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 22 Jun 2017 15:34:04 +0000 (11:34 -0400)
If we are unloading the rds_tcp module, we can set linger to 1
and drop pending packets to accelerate reconnect. The peer will
end up resetting the connection based on new generation numbers
of the new incarnation, so hanging on to unsent TCP packets via
linger is mostly pointless in this case.

Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Tested-by: Jenny Xu <jenny.x.xu@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/rds/connection.c
net/rds/rds.h
net/rds/tcp.h
net/rds/tcp_connect.c
net/rds/tcp_listen.c

index 382443b060cbff7f864f307130331a103f21d2ec..50a3789ac23e4630e096fc4539e9fd8e99551a0e 100644 (file)
@@ -412,6 +412,7 @@ void rds_conn_destroy(struct rds_connection *conn)
                 "%pI4\n", conn, &conn->c_laddr,
                 &conn->c_faddr);
 
+       conn->c_destroy_in_prog = 1;
        /* Ensure conn will not be scheduled for reconnect */
        spin_lock_irq(&rds_conn_lock);
        hlist_del_init_rcu(&conn->c_hash_node);
index aa696b361e20712700a24497bde3654b5aa1aa60..4a25db7075b182943fdb0da59d99ea29985a7ecb 100644 (file)
@@ -137,7 +137,8 @@ struct rds_connection {
        __be32                  c_faddr;
        unsigned int            c_loopback:1,
                                c_ping_triggered:1,
-                               c_pad_to_32:30;
+                               c_destroy_in_prog:1,
+                               c_pad_to_32:29;
        int                     c_npaths;
        struct rds_connection   *c_passive;
        struct rds_transport    *c_trans;
index 56ea6620fcf97ce40d0926089b5e5b188ea1a1fe..f8800b7ce79cad1b0f5bfc89a224210841efcc75 100644 (file)
@@ -71,6 +71,7 @@ void rds_tcp_listen_data_ready(struct sock *sk);
 int rds_tcp_accept_one(struct socket *sock);
 int rds_tcp_keepalive(struct socket *sock);
 void *rds_tcp_listen_sock_def_readable(struct net *net);
+void rds_tcp_set_linger(struct socket *sock);
 
 /* tcp_recv.c */
 int rds_tcp_recv_init(void);
index 5a62a083bb5a9533b0b0d1af3dad0d0e46624d70..cbe08a1fa4c71b93b0f81cd4a5782cd777c24b49 100644 (file)
@@ -170,6 +170,8 @@ void rds_tcp_conn_path_shutdown(struct rds_conn_path *cp)
                 cp->cp_conn, tc, sock);
 
        if (sock) {
+               if (cp->cp_conn->c_destroy_in_prog)
+                       rds_tcp_set_linger(sock);
                sock->ops->shutdown(sock, RCV_SHUTDOWN | SEND_SHUTDOWN);
                lock_sock(sock->sk);
                rds_tcp_restore_callbacks(sock, tc); /* tc->tc_sock = NULL */
index 6089e9a8e00a8caa522be050f0148ea6e1b3d8d6..c6dc8caaf5caba922bd2d2975ae05766a0d706f5 100644 (file)
@@ -112,7 +112,7 @@ struct rds_tcp_connection *rds_tcp_accept_one_path(struct rds_connection *conn)
        return NULL;
 }
 
-static void rds_tcp_set_linger(struct socket *sock)
+void rds_tcp_set_linger(struct socket *sock)
 {
        struct linger no_linger = {
                .l_onoff = 1,