aboutsummaryrefslogtreecommitdiffstats
path: root/net
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
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')
-rw-r--r--net/rds/connection.c53
-rw-r--r--net/rds/rds.h2
-rw-r--r--net/rds/threads.c61
3 files changed, 63 insertions, 53 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;
diff --git a/net/rds/rds.h b/net/rds/rds.h
index c224b5bb3ba9..1d3eef67137f 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -527,6 +527,7 @@ struct rds_connection *rds_conn_create(__be32 laddr, __be32 faddr,
527 struct rds_transport *trans, gfp_t gfp); 527 struct rds_transport *trans, gfp_t gfp);
528struct rds_connection *rds_conn_create_outgoing(__be32 laddr, __be32 faddr, 528struct rds_connection *rds_conn_create_outgoing(__be32 laddr, __be32 faddr,
529 struct rds_transport *trans, gfp_t gfp); 529 struct rds_transport *trans, gfp_t gfp);
530void rds_conn_shutdown(struct rds_connection *conn);
530void rds_conn_destroy(struct rds_connection *conn); 531void rds_conn_destroy(struct rds_connection *conn);
531void rds_conn_reset(struct rds_connection *conn); 532void rds_conn_reset(struct rds_connection *conn);
532void rds_conn_drop(struct rds_connection *conn); 533void rds_conn_drop(struct rds_connection *conn);
@@ -681,6 +682,7 @@ extern unsigned int rds_sysctl_trace_level;
681int __init rds_threads_init(void); 682int __init rds_threads_init(void);
682void rds_threads_exit(void); 683void rds_threads_exit(void);
683extern struct workqueue_struct *rds_wq; 684extern struct workqueue_struct *rds_wq;
685void rds_queue_reconnect(struct rds_connection *conn);
684void rds_connect_worker(struct work_struct *); 686void rds_connect_worker(struct work_struct *);
685void rds_shutdown_worker(struct work_struct *); 687void rds_shutdown_worker(struct work_struct *);
686void rds_send_worker(struct work_struct *); 688void rds_send_worker(struct work_struct *);
diff --git a/net/rds/threads.c b/net/rds/threads.c
index 786c20eaaf5e..6e2e43d5f576 100644
--- a/net/rds/threads.c
+++ b/net/rds/threads.c
@@ -110,7 +110,7 @@ EXPORT_SYMBOL_GPL(rds_connect_complete);
110 * We should *always* start with a random backoff; otherwise a broken connection 110 * We should *always* start with a random backoff; otherwise a broken connection
111 * will always take several iterations to be re-established. 111 * will always take several iterations to be re-established.
112 */ 112 */
113static void rds_queue_reconnect(struct rds_connection *conn) 113void rds_queue_reconnect(struct rds_connection *conn)
114{ 114{
115 unsigned long rand; 115 unsigned long rand;
116 116
@@ -156,58 +156,6 @@ void rds_connect_worker(struct work_struct *work)
156 } 156 }
157} 157}
158 158
159void rds_shutdown_worker(struct work_struct *work)
160{
161 struct rds_connection *conn = container_of(work, struct rds_connection, c_down_w);
162
163 /* shut it down unless it's down already */
164 if (!rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_DOWN)) {
165 /*
166 * Quiesce the connection mgmt handlers before we start tearing
167 * things down. We don't hold the mutex for the entire
168 * duration of the shutdown operation, else we may be
169 * deadlocking with the CM handler. Instead, the CM event
170 * handler is supposed to check for state DISCONNECTING
171 */
172 mutex_lock(&conn->c_cm_lock);
173 if (!rds_conn_transition(conn, RDS_CONN_UP, RDS_CONN_DISCONNECTING) &&
174 !rds_conn_transition(conn, RDS_CONN_ERROR, RDS_CONN_DISCONNECTING)) {
175 rds_conn_error(conn, "shutdown called in state %d\n",
176 atomic_read(&conn->c_state));
177 mutex_unlock(&conn->c_cm_lock);
178 return;
179 }
180 mutex_unlock(&conn->c_cm_lock);
181
182 mutex_lock(&conn->c_send_lock);
183 conn->c_trans->conn_shutdown(conn);
184 rds_conn_reset(conn);
185 mutex_unlock(&conn->c_send_lock);
186
187 if (!rds_conn_transition(conn, RDS_CONN_DISCONNECTING, RDS_CONN_DOWN)) {
188 /* This can happen - eg when we're in the middle of tearing
189 * down the connection, and someone unloads the rds module.
190 * Quite reproduceable with loopback connections.
191 * Mostly harmless.
192 */
193 rds_conn_error(conn,
194 "%s: failed to transition to state DOWN, "
195 "current state is %d\n",
196 __func__,
197 atomic_read(&conn->c_state));
198 return;
199 }
200 }
201
202 /* Then reconnect if it's still live.
203 * The passive side of an IB loopback connection is never added
204 * to the conn hash, so we never trigger a reconnect on this
205 * conn - the reconnect is always triggered by the active peer. */
206 cancel_delayed_work(&conn->c_conn_w);
207 if (!hlist_unhashed(&conn->c_hash_node))
208 rds_queue_reconnect(conn);
209}
210
211void rds_send_worker(struct work_struct *work) 159void rds_send_worker(struct work_struct *work)
212{ 160{
213 struct rds_connection *conn = container_of(work, struct rds_connection, c_send_w.work); 161 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)
252 } 200 }
253} 201}
254 202
203void rds_shutdown_worker(struct work_struct *work)
204{
205 struct rds_connection *conn = container_of(work, struct rds_connection, c_down_w);
206
207 rds_conn_shutdown(conn);
208}
209
255void rds_threads_exit(void) 210void rds_threads_exit(void)
256{ 211{
257 destroy_workqueue(rds_wq); 212 destroy_workqueue(rds_wq);