aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZach Brown <zach.brown@oracle.com>2010-07-23 13:36:58 -0400
committerAndy Grover <andy.grover@oracle.com>2010-09-08 21:16:48 -0400
commitffcec0e110c198717eb0f6ac000c1e5397db9451 (patch)
tree3bb8796f26a1e8730d576a099a6f6cc10c9d35d8
parent5adb5bc65f93e52341c3fc9d03d4030dd375e256 (diff)
RDS: don't call rds_conn_shutdown() from rds_conn_destroy()
rds_conn_shutdown() can return before the connection is shut down when it encounters an existing state that it doesn't understand. This lets rds_conn_destroy() then start tearing down the conn from under paths that are still using it. It's more reliable the shutdown work and wait for krdsd to complete the shutdown callback. This stopped some hangs I was seeing where krdsd was trying to shut down a freed conn. Signed-off-by: Zach Brown <zach.brown@oracle.com>
-rw-r--r--net/rds/connection.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/net/rds/connection.c b/net/rds/connection.c
index 968b7a79839..519b4fe962b 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -312,6 +312,10 @@ void rds_conn_shutdown(struct rds_connection *conn)
312 312
313/* 313/*
314 * Stop and free a connection. 314 * Stop and free a connection.
315 *
316 * This can only be used in very limited circumstances. It assumes that once
317 * the conn has been shutdown that no one else is referencing the connection.
318 * We can only ensure this in the rmmod path in the current code.
315 */ 319 */
316void rds_conn_destroy(struct rds_connection *conn) 320void rds_conn_destroy(struct rds_connection *conn)
317{ 321{
@@ -326,10 +330,11 @@ void rds_conn_destroy(struct rds_connection *conn)
326 spin_lock_irq(&rds_conn_lock); 330 spin_lock_irq(&rds_conn_lock);
327 hlist_del_init_rcu(&conn->c_hash_node); 331 hlist_del_init_rcu(&conn->c_hash_node);
328 spin_unlock_irq(&rds_conn_lock); 332 spin_unlock_irq(&rds_conn_lock);
329
330 synchronize_rcu(); 333 synchronize_rcu();
331 334
332 rds_conn_shutdown(conn); 335 /* shut the connection down */
336 rds_conn_drop(conn);
337 flush_work(&conn->c_down_w);
333 338
334 /* tear down queued messages */ 339 /* tear down queued messages */
335 list_for_each_entry_safe(rm, rtmp, 340 list_for_each_entry_safe(rm, rtmp,