aboutsummaryrefslogtreecommitdiffstats
path: root/net/rds/connection.c
diff options
context:
space:
mode:
authorAndy Grover <andy.grover@oracle.com>2010-06-11 16:49:13 -0400
committerAndy Grover <andy.grover@oracle.com>2010-09-08 21:10:13 -0400
commit2dc393573430f853e56e25bf4b41c34ba2aa8fd6 (patch)
treef7a3ddb99aab472aa5054a10043419d4b22bb312 /net/rds/connection.c
parent9de0864cf55927a7383b5ba6e48834ff3ef053de (diff)
RDS: move rds_shutdown_worker impl. to rds_conn_shutdown
This fits better in connection.c, rather than threads.c. Signed-off-by: Andy Grover <andy.grover@oracle.com>
Diffstat (limited to 'net/rds/connection.c')
-rw-r--r--net/rds/connection.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/net/rds/connection.c b/net/rds/connection.c
index 7619b671ca28..895e39cdc6a6 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -263,6 +263,59 @@ struct rds_connection *rds_conn_create_outgoing(__be32 laddr, __be32 faddr,
263} 263}
264EXPORT_SYMBOL_GPL(rds_conn_create_outgoing); 264EXPORT_SYMBOL_GPL(rds_conn_create_outgoing);
265 265
266void rds_conn_shutdown(struct rds_connection *conn)
267{
268 /* shut it down unless it's down already */
269 if (!rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_DOWN)) {
270 /*
271 * Quiesce the connection mgmt handlers before we start tearing
272 * things down. We don't hold the mutex for the entire
273 * duration of the shutdown operation, else we may be
274 * deadlocking with the CM handler. Instead, the CM event
275 * handler is supposed to check for state DISCONNECTING
276 */
277 mutex_lock(&conn->c_cm_lock);
278 if (!rds_conn_transition(conn, RDS_CONN_UP, RDS_CONN_DISCONNECTING)
279 && !rds_conn_transition(conn, RDS_CONN_ERROR, RDS_CONN_DISCONNECTING)) {
280 rds_conn_error(conn, "shutdown called in state %d\n",
281 atomic_read(&conn->c_state));
282 mutex_unlock(&conn->c_cm_lock);
283 return;
284 }
285 mutex_unlock(&conn->c_cm_lock);
286
287 mutex_lock(&conn->c_send_lock);
288 conn->c_trans->conn_shutdown(conn);
289 rds_conn_reset(conn);
290 mutex_unlock(&conn->c_send_lock);
291
292 if (!rds_conn_transition(conn, RDS_CONN_DISCONNECTING, RDS_CONN_DOWN)) {
293 /* This can happen - eg when we're in the middle of tearing
294 * down the connection, and someone unloads the rds module.
295 * Quite reproduceable with loopback connections.
296 * Mostly harmless.
297 */
298 rds_conn_error(conn,
299 "%s: failed to transition to state DOWN, "
300 "current state is %d\n",
301 __func__,
302 atomic_read(&conn->c_state));
303 return;
304 }
305 }
306
307 /* Then reconnect if it's still live.
308 * The passive side of an IB loopback connection is never added
309 * to the conn hash, so we never trigger a reconnect on this
310 * conn - the reconnect is always triggered by the active peer. */
311 cancel_delayed_work_sync(&conn->c_conn_w);
312 if (!hlist_unhashed(&conn->c_hash_node))
313 rds_queue_reconnect(conn);
314}
315
316/*
317 * Stop and free a connection.
318 */
266void rds_conn_destroy(struct rds_connection *conn) 319void rds_conn_destroy(struct rds_connection *conn)
267{ 320{
268 struct rds_message *rm, *rtmp; 321 struct rds_message *rm, *rtmp;