RDS: move rds_shutdown_worker impl. to rds_conn_shutdown
Andy Grover [Fri, 11 Jun 2010 20:49:13 +0000 (13:49 -0700)]
This fits better in connection.c, rather than threads.c.

Signed-off-by: Andy Grover <andy.grover@oracle.com>

net/rds/connection.c
net/rds/rds.h
net/rds/threads.c

index 7619b67..895e39c 100644 (file)
@@ -263,6 +263,59 @@ struct rds_connection *rds_conn_create_outgoing(__be32 laddr, __be32 faddr,
 }
 EXPORT_SYMBOL_GPL(rds_conn_create_outgoing);
 
+void rds_conn_shutdown(struct rds_connection *conn)
+{
+       /* shut it down unless it's down already */
+       if (!rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_DOWN)) {
+               /*
+                * Quiesce the connection mgmt handlers before we start tearing
+                * things down. We don't hold the mutex for the entire
+                * duration of the shutdown operation, else we may be
+                * deadlocking with the CM handler. Instead, the CM event
+                * handler is supposed to check for state DISCONNECTING
+                */
+               mutex_lock(&conn->c_cm_lock);
+               if (!rds_conn_transition(conn, RDS_CONN_UP, RDS_CONN_DISCONNECTING)
+                && !rds_conn_transition(conn, RDS_CONN_ERROR, RDS_CONN_DISCONNECTING)) {
+                       rds_conn_error(conn, "shutdown called in state %d\n",
+                                       atomic_read(&conn->c_state));
+                       mutex_unlock(&conn->c_cm_lock);
+                       return;
+               }
+               mutex_unlock(&conn->c_cm_lock);
+
+               mutex_lock(&conn->c_send_lock);
+               conn->c_trans->conn_shutdown(conn);
+               rds_conn_reset(conn);
+               mutex_unlock(&conn->c_send_lock);
+
+               if (!rds_conn_transition(conn, RDS_CONN_DISCONNECTING, RDS_CONN_DOWN)) {
+                       /* This can happen - eg when we're in the middle of tearing
+                        * down the connection, and someone unloads the rds module.
+                        * Quite reproduceable with loopback connections.
+                        * Mostly harmless.
+                        */
+                       rds_conn_error(conn,
+                               "%s: failed to transition to state DOWN, "
+                               "current state is %d\n",
+                               __func__,
+                               atomic_read(&conn->c_state));
+                       return;
+               }
+       }
+
+       /* Then reconnect if it's still live.
+        * The passive side of an IB loopback connection is never added
+        * to the conn hash, so we never trigger a reconnect on this
+        * conn - the reconnect is always triggered by the active peer. */
+       cancel_delayed_work_sync(&conn->c_conn_w);
+       if (!hlist_unhashed(&conn->c_hash_node))
+               rds_queue_reconnect(conn);
+}
+
+/*
+ * Stop and free a connection.
+ */
 void rds_conn_destroy(struct rds_connection *conn)
 {
        struct rds_message *rm, *rtmp;
index c224b5b..1d3eef6 100644 (file)
@@ -527,6 +527,7 @@ struct rds_connection *rds_conn_create(__be32 laddr, __be32 faddr,
                                       struct rds_transport *trans, gfp_t gfp);
 struct rds_connection *rds_conn_create_outgoing(__be32 laddr, __be32 faddr,
                               struct rds_transport *trans, gfp_t gfp);
+void rds_conn_shutdown(struct rds_connection *conn);
 void rds_conn_destroy(struct rds_connection *conn);
 void rds_conn_reset(struct rds_connection *conn);
 void rds_conn_drop(struct rds_connection *conn);
@@ -681,6 +682,7 @@ extern unsigned int  rds_sysctl_trace_level;
 int __init rds_threads_init(void);
 void rds_threads_exit(void);
 extern struct workqueue_struct *rds_wq;
+void rds_queue_reconnect(struct rds_connection *conn);
 void rds_connect_worker(struct work_struct *);
 void rds_shutdown_worker(struct work_struct *);
 void rds_send_worker(struct work_struct *);
index 786c20e..6e2e43d 100644 (file)
@@ -110,7 +110,7 @@ EXPORT_SYMBOL_GPL(rds_connect_complete);
  * We should *always* start with a random backoff; otherwise a broken connection
  * will always take several iterations to be re-established.
  */
-static void rds_queue_reconnect(struct rds_connection *conn)
+void rds_queue_reconnect(struct rds_connection *conn)
 {
        unsigned long rand;
 
@@ -156,58 +156,6 @@ void rds_connect_worker(struct work_struct *work)
        }
 }
 
-void rds_shutdown_worker(struct work_struct *work)
-{
-       struct rds_connection *conn = container_of(work, struct rds_connection, c_down_w);
-
-       /* shut it down unless it's down already */
-       if (!rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_DOWN)) {
-               /*
-                * Quiesce the connection mgmt handlers before we start tearing
-                * things down. We don't hold the mutex for the entire
-                * duration of the shutdown operation, else we may be
-                * deadlocking with the CM handler. Instead, the CM event
-                * handler is supposed to check for state DISCONNECTING
-                */
-               mutex_lock(&conn->c_cm_lock);
-               if (!rds_conn_transition(conn, RDS_CONN_UP, RDS_CONN_DISCONNECTING) &&
-                   !rds_conn_transition(conn, RDS_CONN_ERROR, RDS_CONN_DISCONNECTING)) {
-                       rds_conn_error(conn, "shutdown called in state %d\n",
-                                       atomic_read(&conn->c_state));
-                       mutex_unlock(&conn->c_cm_lock);
-                       return;
-               }
-               mutex_unlock(&conn->c_cm_lock);
-
-               mutex_lock(&conn->c_send_lock);
-               conn->c_trans->conn_shutdown(conn);
-               rds_conn_reset(conn);
-               mutex_unlock(&conn->c_send_lock);
-
-               if (!rds_conn_transition(conn, RDS_CONN_DISCONNECTING, RDS_CONN_DOWN)) {
-                       /* This can happen - eg when we're in the middle of tearing
-                        * down the connection, and someone unloads the rds module.
-                        * Quite reproduceable with loopback connections.
-                        * Mostly harmless.
-                        */
-                       rds_conn_error(conn,
-                               "%s: failed to transition to state DOWN, "
-                               "current state is %d\n",
-                               __func__,
-                               atomic_read(&conn->c_state));
-                       return;
-               }
-       }
-
-       /* Then reconnect if it's still live.
-        * The passive side of an IB loopback connection is never added
-        * to the conn hash, so we never trigger a reconnect on this
-        * conn - the reconnect is always triggered by the active peer. */
-       cancel_delayed_work(&conn->c_conn_w);
-       if (!hlist_unhashed(&conn->c_hash_node))
-               rds_queue_reconnect(conn);
-}
-
 void rds_send_worker(struct work_struct *work)
 {
        struct rds_connection *conn = container_of(work, struct rds_connection, c_send_w.work);
@@ -252,6 +200,13 @@ void rds_recv_worker(struct work_struct *work)
        }
 }
 
+void rds_shutdown_worker(struct work_struct *work)
+{
+       struct rds_connection *conn = container_of(work, struct rds_connection, c_down_w);
+
+       rds_conn_shutdown(conn);
+}
+
 void rds_threads_exit(void)
 {
        destroy_workqueue(rds_wq);