diff options
author | Sowmini Varadhan <sowmini.varadhan@oracle.com> | 2016-06-13 12:44:41 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-06-15 02:50:44 -0400 |
commit | d769ef81d5b5932520fbefb02614a4380c132495 (patch) | |
tree | af1fedcb8109508425ee90d419d58272676af746 /net/rds | |
parent | 1c5113cf796bb730abc1798a3649b61e9e022be6 (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.c | 64 | ||||
-rw-r--r-- | net/rds/rds.h | 5 | ||||
-rw-r--r-- | net/rds/send.c | 9 | ||||
-rw-r--r-- | net/rds/tcp.c | 2 | ||||
-rw-r--r-- | net/rds/threads.c | 2 |
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 | */ |
99 | static void rds_conn_reset(struct rds_connection *conn) | 99 | static 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 | } |
295 | EXPORT_SYMBOL_GPL(rds_conn_create_outgoing); | 297 | EXPORT_SYMBOL_GPL(rds_conn_create_outgoing); |
296 | 298 | ||
297 | void rds_conn_shutdown(struct rds_connection *conn) | 299 | void 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, | |||
653 | struct rds_connection *rds_conn_create_outgoing(struct net *net, | 654 | struct 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); |
656 | void rds_conn_shutdown(struct rds_connection *conn); | 657 | void rds_conn_shutdown(struct rds_conn_path *cpath); |
657 | void rds_conn_destroy(struct rds_connection *conn); | 658 | void rds_conn_destroy(struct rds_connection *conn); |
658 | void rds_conn_drop(struct rds_connection *conn); | 659 | void rds_conn_drop(struct rds_connection *conn); |
659 | void rds_conn_path_drop(struct rds_conn_path *cpath); | 660 | void 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 */ |
788 | int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len); | 789 | int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len); |
789 | void rds_send_reset(struct rds_connection *conn); | 790 | void rds_send_path_reset(struct rds_conn_path *conn); |
790 | int rds_send_xmit(struct rds_conn_path *cp); | 791 | int rds_send_xmit(struct rds_conn_path *cp); |
791 | struct sockaddr_in; | 792 | struct sockaddr_in; |
792 | void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest); | 793 | void 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 | */ |
65 | static void rds_send_path_reset(struct rds_conn_path *cp) | 65 | void 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 | 102 | EXPORT_SYMBOL_GPL(rds_send_path_reset); | |
103 | void rds_send_reset(struct rds_connection *conn) | ||
104 | { | ||
105 | rds_send_path_reset(&conn->c_path[0]); | ||
106 | } | ||
107 | EXPORT_SYMBOL_GPL(rds_send_reset); | ||
108 | 103 | ||
109 | static int acquire_in_xmit(struct rds_conn_path *cp) | 104 | static 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); |
188 | newsock: | 188 | newsock: |
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 | ||
231 | void rds_threads_exit(void) | 231 | void rds_threads_exit(void) |