Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'rds-tcp-fixes'

Sowmini Varadhan says:

====================
rds: tcp: fixes

Patch1 is a bug fix for correct reconnect when a connection
is restarted. Patch 2 accelerates cleanup by setting linger
to 1 and sending a RST to the peer.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+19 -13
+1
net/rds/connection.c
··· 412 412 "%pI4\n", conn, &conn->c_laddr, 413 413 &conn->c_faddr); 414 414 415 + conn->c_destroy_in_prog = 1; 415 416 /* Ensure conn will not be scheduled for reconnect */ 416 417 spin_lock_irq(&rds_conn_lock); 417 418 hlist_del_init_rcu(&conn->c_hash_node);
+3 -1
net/rds/rds.h
··· 137 137 __be32 c_faddr; 138 138 unsigned int c_loopback:1, 139 139 c_ping_triggered:1, 140 - c_pad_to_32:30; 140 + c_destroy_in_prog:1, 141 + c_pad_to_32:29; 141 142 int c_npaths; 142 143 struct rds_connection *c_passive; 143 144 struct rds_transport *c_trans; ··· 828 827 is_acked_func is_acked); 829 828 void rds_send_path_drop_acked(struct rds_conn_path *cp, u64 ack, 830 829 is_acked_func is_acked); 830 + void rds_send_ping(struct rds_connection *conn, int cp_index); 831 831 int rds_send_pong(struct rds_conn_path *cp, __be16 dport); 832 832 833 833 /* rdma.c */
+3 -3
net/rds/recv.c
··· 227 227 } 228 228 /* if RDS_EXTHDR_NPATHS was not found, default to a single-path */ 229 229 conn->c_npaths = max_t(int, conn->c_npaths, 1); 230 + conn->c_ping_triggered = 0; 230 231 rds_conn_peer_gen_update(conn, new_peer_gen_num); 231 232 } 232 233 ··· 245 244 * called after reception of the probe-pong on all mprds_paths. 246 245 * Otherwise (sender of probe-ping is not the smaller ip addr): just call 247 246 * rds_conn_path_connect_if_down on the hashed path. (see rule 4) 248 - * 4. when cp_index > 0, rds_connect_worker must only trigger 249 - * a connection if laddr < faddr. 247 + * 4. rds_connect_worker must only trigger a connection if laddr < faddr. 250 248 * 5. sender may end up queuing the packet on the cp. will get sent out later. 251 249 * when connection is completed. 252 250 */ ··· 256 256 257 257 if (conn->c_npaths > 1 && 258 258 IS_CANONICAL(conn->c_laddr, conn->c_faddr)) { 259 - for (i = 1; i < conn->c_npaths; i++) { 259 + for (i = 0; i < conn->c_npaths; i++) { 260 260 cp = &conn->c_path[i]; 261 261 rds_conn_path_connect_if_down(cp); 262 262 }
+6 -8
net/rds/send.c
··· 971 971 return ret; 972 972 } 973 973 974 - static void rds_send_ping(struct rds_connection *conn); 975 - 976 974 static int rds_send_mprds_hash(struct rds_sock *rs, struct rds_connection *conn) 977 975 { 978 976 int hash; ··· 980 982 else 981 983 hash = RDS_MPATH_HASH(rs, conn->c_npaths); 982 984 if (conn->c_npaths == 0 && hash != 0) { 983 - rds_send_ping(conn); 985 + rds_send_ping(conn, 0); 984 986 985 987 if (conn->c_npaths == 0) { 986 988 wait_event_interruptible(conn->c_hs_waitq, ··· 1280 1282 return rds_send_probe(cp, 0, dport, 0); 1281 1283 } 1282 1284 1283 - static void 1284 - rds_send_ping(struct rds_connection *conn) 1285 + void 1286 + rds_send_ping(struct rds_connection *conn, int cp_index) 1285 1287 { 1286 1288 unsigned long flags; 1287 - struct rds_conn_path *cp = &conn->c_path[0]; 1289 + struct rds_conn_path *cp = &conn->c_path[cp_index]; 1288 1290 1289 1291 spin_lock_irqsave(&cp->cp_lock, flags); 1290 1292 if (conn->c_ping_triggered) { ··· 1293 1295 } 1294 1296 conn->c_ping_triggered = 1; 1295 1297 spin_unlock_irqrestore(&cp->cp_lock, flags); 1296 - rds_send_probe(&conn->c_path[0], cpu_to_be16(RDS_FLAG_PROBE_PORT), 1297 - 0, 0); 1298 + rds_send_probe(cp, cpu_to_be16(RDS_FLAG_PROBE_PORT), 0, 0); 1298 1299 } 1300 + EXPORT_SYMBOL_GPL(rds_send_ping);
+1
net/rds/tcp.h
··· 71 71 int rds_tcp_accept_one(struct socket *sock); 72 72 int rds_tcp_keepalive(struct socket *sock); 73 73 void *rds_tcp_listen_sock_def_readable(struct net *net); 74 + void rds_tcp_set_linger(struct socket *sock); 74 75 75 76 /* tcp_recv.c */ 76 77 int rds_tcp_recv_init(void);
+2
net/rds/tcp_connect.c
··· 170 170 cp->cp_conn, tc, sock); 171 171 172 172 if (sock) { 173 + if (cp->cp_conn->c_destroy_in_prog) 174 + rds_tcp_set_linger(sock); 173 175 sock->ops->shutdown(sock, RCV_SHUTDOWN | SEND_SHUTDOWN); 174 176 lock_sock(sock->sk); 175 177 rds_tcp_restore_callbacks(sock, tc); /* tc->tc_sock = NULL */
+3 -1
net/rds/tcp_listen.c
··· 112 112 return NULL; 113 113 } 114 114 115 - static void rds_tcp_set_linger(struct socket *sock) 115 + void rds_tcp_set_linger(struct socket *sock) 116 116 { 117 117 struct linger no_linger = { 118 118 .l_onoff = 1, ··· 192 192 } 193 193 new_sock = NULL; 194 194 ret = 0; 195 + if (conn->c_npaths == 0) 196 + rds_send_ping(cp->cp_conn, cp->cp_index); 195 197 goto out; 196 198 rst_nsk: 197 199 /* reset the newly returned accept sock and bail.