aboutsummaryrefslogtreecommitdiffstats
path: root/net/rds
diff options
context:
space:
mode:
authorSowmini Varadhan <sowmini.varadhan@oracle.com>2016-06-13 12:44:41 -0400
committerDavid S. Miller <davem@davemloft.net>2016-06-15 02:50:44 -0400
commitd769ef81d5b5932520fbefb02614a4380c132495 (patch)
treeaf1fedcb8109508425ee90d419d58272676af746 /net/rds
parent1c5113cf796bb730abc1798a3649b61e9e022be6 (diff)
RDS: Update rds_conn_shutdown to work with rds_conn_path
This commit changes rds_conn_shutdown to take a rds_conn_path * argument, allowing it to shutdown paths other than c_path[0] for MP-capable transports. Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/rds')
-rw-r--r--net/rds/connection.c64
-rw-r--r--net/rds/rds.h5
-rw-r--r--net/rds/send.c9
-rw-r--r--net/rds/tcp.c2
-rw-r--r--net/rds/threads.c2
5 files changed, 44 insertions, 38 deletions
diff --git a/net/rds/connection.c b/net/rds/connection.c
index a99ac69f77ac..a88d26fd8223 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -96,14 +96,16 @@ static struct rds_connection *rds_conn_lookup(struct net *net,
96 * and receiving over this connection again in the future. It is up to 96 * and receiving over this connection again in the future. It is up to
97 * the transport to have serialized this call with its send and recv. 97 * the transport to have serialized this call with its send and recv.
98 */ 98 */
99static void rds_conn_reset(struct rds_connection *conn) 99static void rds_conn_path_reset(struct rds_conn_path *cp)
100{ 100{
101 struct rds_connection *conn = cp->cp_conn;
102
101 rdsdebug("connection %pI4 to %pI4 reset\n", 103 rdsdebug("connection %pI4 to %pI4 reset\n",
102 &conn->c_laddr, &conn->c_faddr); 104 &conn->c_laddr, &conn->c_faddr);
103 105
104 rds_stats_inc(s_conn_reset); 106 rds_stats_inc(s_conn_reset);
105 rds_send_reset(conn); 107 rds_send_path_reset(cp);
106 conn->c_flags = 0; 108 cp->cp_flags = 0;
107 109
108 /* Do not clear next_rx_seq here, else we cannot distinguish 110 /* Do not clear next_rx_seq here, else we cannot distinguish
109 * retransmitted packets from new packets, and will hand all 111 * retransmitted packets from new packets, and will hand all
@@ -294,10 +296,12 @@ struct rds_connection *rds_conn_create_outgoing(struct net *net,
294} 296}
295EXPORT_SYMBOL_GPL(rds_conn_create_outgoing); 297EXPORT_SYMBOL_GPL(rds_conn_create_outgoing);
296 298
297void rds_conn_shutdown(struct rds_connection *conn) 299void rds_conn_shutdown(struct rds_conn_path *cp)
298{ 300{
301 struct rds_connection *conn = cp->cp_conn;
302
299 /* shut it down unless it's down already */ 303 /* shut it down unless it's down already */
300 if (!rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_DOWN)) { 304 if (!rds_conn_path_transition(cp, RDS_CONN_DOWN, RDS_CONN_DOWN)) {
301 /* 305 /*
302 * Quiesce the connection mgmt handlers before we start tearing 306 * Quiesce the connection mgmt handlers before we start tearing
303 * things down. We don't hold the mutex for the entire 307 * things down. We don't hold the mutex for the entire
@@ -305,35 +309,41 @@ void rds_conn_shutdown(struct rds_connection *conn)
305 * deadlocking with the CM handler. Instead, the CM event 309 * deadlocking with the CM handler. Instead, the CM event
306 * handler is supposed to check for state DISCONNECTING 310 * handler is supposed to check for state DISCONNECTING
307 */ 311 */
308 mutex_lock(&conn->c_cm_lock); 312 mutex_lock(&cp->cp_cm_lock);
309 if (!rds_conn_transition(conn, RDS_CONN_UP, RDS_CONN_DISCONNECTING) 313 if (!rds_conn_path_transition(cp, RDS_CONN_UP,
310 && !rds_conn_transition(conn, RDS_CONN_ERROR, RDS_CONN_DISCONNECTING)) { 314 RDS_CONN_DISCONNECTING) &&
311 rds_conn_error(conn, "shutdown called in state %d\n", 315 !rds_conn_path_transition(cp, RDS_CONN_ERROR,
312 atomic_read(&conn->c_state)); 316 RDS_CONN_DISCONNECTING)) {
313 mutex_unlock(&conn->c_cm_lock); 317 rds_conn_path_error(cp,
318 "shutdown called in state %d\n",
319 atomic_read(&cp->cp_state));
320 mutex_unlock(&cp->cp_cm_lock);
314 return; 321 return;
315 } 322 }
316 mutex_unlock(&conn->c_cm_lock); 323 mutex_unlock(&cp->cp_cm_lock);
317 324
318 wait_event(conn->c_waitq, 325 wait_event(cp->cp_waitq,
319 !test_bit(RDS_IN_XMIT, &conn->c_flags)); 326 !test_bit(RDS_IN_XMIT, &cp->cp_flags));
320 wait_event(conn->c_waitq, 327 wait_event(cp->cp_waitq,
321 !test_bit(RDS_RECV_REFILL, &conn->c_flags)); 328 !test_bit(RDS_RECV_REFILL, &cp->cp_flags));
322 329
323 conn->c_trans->conn_shutdown(conn); 330 if (!conn->c_trans->t_mp_capable)
324 rds_conn_reset(conn); 331 conn->c_trans->conn_shutdown(conn);
332 else
333 conn->c_trans->conn_path_shutdown(cp);
334 rds_conn_path_reset(cp);
325 335
326 if (!rds_conn_transition(conn, RDS_CONN_DISCONNECTING, RDS_CONN_DOWN)) { 336 if (!rds_conn_path_transition(cp, RDS_CONN_DISCONNECTING,
337 RDS_CONN_DOWN)) {
327 /* This can happen - eg when we're in the middle of tearing 338 /* This can happen - eg when we're in the middle of tearing
328 * down the connection, and someone unloads the rds module. 339 * down the connection, and someone unloads the rds module.
329 * Quite reproduceable with loopback connections. 340 * Quite reproduceable with loopback connections.
330 * Mostly harmless. 341 * Mostly harmless.
331 */ 342 */
332 rds_conn_error(conn, 343 rds_conn_path_error(cp, "%s: failed to transition "
333 "%s: failed to transition to state DOWN, " 344 "to state DOWN, current state "
334 "current state is %d\n", 345 "is %d\n", __func__,
335 __func__, 346 atomic_read(&cp->cp_state));
336 atomic_read(&conn->c_state));
337 return; 347 return;
338 } 348 }
339 } 349 }
@@ -342,13 +352,13 @@ void rds_conn_shutdown(struct rds_connection *conn)
342 * The passive side of an IB loopback connection is never added 352 * The passive side of an IB loopback connection is never added
343 * to the conn hash, so we never trigger a reconnect on this 353 * to the conn hash, so we never trigger a reconnect on this
344 * conn - the reconnect is always triggered by the active peer. */ 354 * conn - the reconnect is always triggered by the active peer. */
345 cancel_delayed_work_sync(&conn->c_conn_w); 355 cancel_delayed_work_sync(&cp->cp_conn_w);
346 rcu_read_lock(); 356 rcu_read_lock();
347 if (!hlist_unhashed(&conn->c_hash_node)) { 357 if (!hlist_unhashed(&conn->c_hash_node)) {
348 rcu_read_unlock(); 358 rcu_read_unlock();
349 if (conn->c_trans->t_type != RDS_TRANS_TCP || 359 if (conn->c_trans->t_type != RDS_TRANS_TCP ||
350 conn->c_path[0].cp_outgoing == 1) 360 cp->cp_outgoing == 1)
351 rds_queue_reconnect(&conn->c_path[0]); 361 rds_queue_reconnect(cp);
352 } else { 362 } else {
353 rcu_read_unlock(); 363 rcu_read_unlock();
354 } 364 }
diff --git a/net/rds/rds.h b/net/rds/rds.h
index 85f98bd88c1c..2e35b738176f 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -456,6 +456,7 @@ struct rds_transport {
456 void (*conn_free)(void *data); 456 void (*conn_free)(void *data);
457 int (*conn_connect)(struct rds_connection *conn); 457 int (*conn_connect)(struct rds_connection *conn);
458 void (*conn_shutdown)(struct rds_connection *conn); 458 void (*conn_shutdown)(struct rds_connection *conn);
459 void (*conn_path_shutdown)(struct rds_conn_path *conn);
459 void (*xmit_prepare)(struct rds_connection *conn); 460 void (*xmit_prepare)(struct rds_connection *conn);
460 void (*xmit_path_prepare)(struct rds_conn_path *cp); 461 void (*xmit_path_prepare)(struct rds_conn_path *cp);
461 void (*xmit_complete)(struct rds_connection *conn); 462 void (*xmit_complete)(struct rds_connection *conn);
@@ -653,7 +654,7 @@ struct rds_connection *rds_conn_create(struct net *net,
653struct rds_connection *rds_conn_create_outgoing(struct net *net, 654struct rds_connection *rds_conn_create_outgoing(struct net *net,
654 __be32 laddr, __be32 faddr, 655 __be32 laddr, __be32 faddr,
655 struct rds_transport *trans, gfp_t gfp); 656 struct rds_transport *trans, gfp_t gfp);
656void rds_conn_shutdown(struct rds_connection *conn); 657void rds_conn_shutdown(struct rds_conn_path *cpath);
657void rds_conn_destroy(struct rds_connection *conn); 658void rds_conn_destroy(struct rds_connection *conn);
658void rds_conn_drop(struct rds_connection *conn); 659void rds_conn_drop(struct rds_connection *conn);
659void rds_conn_path_drop(struct rds_conn_path *cpath); 660void rds_conn_path_drop(struct rds_conn_path *cpath);
@@ -786,7 +787,7 @@ void rds_inc_info_copy(struct rds_incoming *inc,
786 787
787/* send.c */ 788/* send.c */
788int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len); 789int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len);
789void rds_send_reset(struct rds_connection *conn); 790void rds_send_path_reset(struct rds_conn_path *conn);
790int rds_send_xmit(struct rds_conn_path *cp); 791int rds_send_xmit(struct rds_conn_path *cp);
791struct sockaddr_in; 792struct sockaddr_in;
792void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest); 793void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest);
diff --git a/net/rds/send.c b/net/rds/send.c
index 369bd6690218..ee43d6b2ea8f 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -62,7 +62,7 @@ static void rds_send_remove_from_sock(struct list_head *messages, int status);
62 * Reset the send state. Callers must ensure that this doesn't race with 62 * Reset the send state. Callers must ensure that this doesn't race with
63 * rds_send_xmit(). 63 * rds_send_xmit().
64 */ 64 */
65static void rds_send_path_reset(struct rds_conn_path *cp) 65void rds_send_path_reset(struct rds_conn_path *cp)
66{ 66{
67 struct rds_message *rm, *tmp; 67 struct rds_message *rm, *tmp;
68 unsigned long flags; 68 unsigned long flags;
@@ -99,12 +99,7 @@ static void rds_send_path_reset(struct rds_conn_path *cp)
99 list_splice_init(&cp->cp_retrans, &cp->cp_send_queue); 99 list_splice_init(&cp->cp_retrans, &cp->cp_send_queue);
100 spin_unlock_irqrestore(&cp->cp_lock, flags); 100 spin_unlock_irqrestore(&cp->cp_lock, flags);
101} 101}
102 102EXPORT_SYMBOL_GPL(rds_send_path_reset);
103void rds_send_reset(struct rds_connection *conn)
104{
105 rds_send_path_reset(&conn->c_path[0]);
106}
107EXPORT_SYMBOL_GPL(rds_send_reset);
108 103
109static int acquire_in_xmit(struct rds_conn_path *cp) 104static int acquire_in_xmit(struct rds_conn_path *cp)
110{ 105{
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index 4bc1c153e93a..0e757a0d7421 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -186,7 +186,7 @@ void rds_tcp_reset_callbacks(struct socket *sock,
186 release_sock(osock->sk); 186 release_sock(osock->sk);
187 sock_release(osock); 187 sock_release(osock);
188newsock: 188newsock:
189 rds_send_reset(conn); 189 rds_send_path_reset(&conn->c_path[0]);
190 lock_sock(sock->sk); 190 lock_sock(sock->sk);
191 write_lock_bh(&sock->sk->sk_callback_lock); 191 write_lock_bh(&sock->sk->sk_callback_lock);
192 tc->t_sock = sock; 192 tc->t_sock = sock;
diff --git a/net/rds/threads.c b/net/rds/threads.c
index 94cca66ba5d6..9fbe95bb14a9 100644
--- a/net/rds/threads.c
+++ b/net/rds/threads.c
@@ -225,7 +225,7 @@ void rds_shutdown_worker(struct work_struct *work)
225 struct rds_conn_path, 225 struct rds_conn_path,
226 cp_down_w); 226 cp_down_w);
227 227
228 rds_conn_shutdown(cp->cp_conn); 228 rds_conn_shutdown(cp);
229} 229}
230 230
231void rds_threads_exit(void) 231void rds_threads_exit(void)