diff options
author | Sowmini Varadhan <sowmini.varadhan@oracle.com> | 2016-06-13 09:44:42 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-06-14 23:50:44 -0700 |
commit | 3ecc5693c02bb154bc8609c640eb862804c4aabb (patch) | |
tree | 39e88c9b47c49568aee3906e9e8299c824a5b548 /net/rds | |
parent | d769ef81d5b5932520fbefb02614a4380c132495 (diff) | |
download | linux-stable-3ecc5693c02bb154bc8609c640eb862804c4aabb.tar.gz linux-stable-3ecc5693c02bb154bc8609c640eb862804c4aabb.tar.bz2 linux-stable-3ecc5693c02bb154bc8609c640eb862804c4aabb.zip |
RDS: Update rds_conn_destroy to be MP capable
Refactor rds_conn_destroy() so that the per-path dismantling
is done in rds_conn_path_destroy, and then iterate as needed
over rds_conn_path_destroy().
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 | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/net/rds/connection.c b/net/rds/connection.c index a88d26fd8223..a4b07c899d89 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -36,7 +36,6 @@ #include <linux/export.h> #include <net/inet_hashtables.h> -#include "rds_single_path.h" #include "rds.h" #include "loop.h" @@ -364,6 +363,34 @@ void rds_conn_shutdown(struct rds_conn_path *cp) } } +/* destroy a single rds_conn_path. rds_conn_destroy() iterates over + * all paths using rds_conn_path_destroy() + */ +static void rds_conn_path_destroy(struct rds_conn_path *cp) +{ + struct rds_message *rm, *rtmp; + + rds_conn_path_drop(cp); + flush_work(&cp->cp_down_w); + + /* make sure lingering queued work won't try to ref the conn */ + cancel_delayed_work_sync(&cp->cp_send_w); + cancel_delayed_work_sync(&cp->cp_recv_w); + + /* tear down queued messages */ + list_for_each_entry_safe(rm, rtmp, + &cp->cp_send_queue, + m_conn_item) { + list_del_init(&rm->m_conn_item); + BUG_ON(!list_empty(&rm->m_sock_item)); + rds_message_put(rm); + } + if (cp->cp_xmit_rm) + rds_message_put(cp->cp_xmit_rm); + + cp->cp_conn->c_trans->conn_free(cp->cp_transport_data); +} + /* * Stop and free a connection. * @@ -373,7 +400,6 @@ void rds_conn_shutdown(struct rds_conn_path *cp) */ void rds_conn_destroy(struct rds_connection *conn) { - struct rds_message *rm, *rtmp; unsigned long flags; rdsdebug("freeing conn %p for %pI4 -> " @@ -387,25 +413,19 @@ void rds_conn_destroy(struct rds_connection *conn) synchronize_rcu(); /* shut the connection down */ - rds_conn_drop(conn); - flush_work(&conn->c_down_w); - - /* make sure lingering queued work won't try to ref the conn */ - cancel_delayed_work_sync(&conn->c_send_w); - cancel_delayed_work_sync(&conn->c_recv_w); + if (!conn->c_trans->t_mp_capable) { + rds_conn_path_destroy(&conn->c_path[0]); + BUG_ON(!list_empty(&conn->c_path[0].cp_retrans)); + } else { + int i; + struct rds_conn_path *cp; - /* tear down queued messages */ - list_for_each_entry_safe(rm, rtmp, - &conn->c_send_queue, - m_conn_item) { - list_del_init(&rm->m_conn_item); - BUG_ON(!list_empty(&rm->m_sock_item)); - rds_message_put(rm); + for (i = 0; i < RDS_MPATH_WORKERS; i++) { + cp = &conn->c_path[i]; + rds_conn_path_destroy(cp); + BUG_ON(!list_empty(&cp->cp_retrans)); + } } - if (conn->c_xmit_rm) - rds_message_put(conn->c_xmit_rm); - - conn->c_trans->conn_free(conn->c_transport_data); /* * The congestion maps aren't freed up here. They're @@ -414,7 +434,6 @@ void rds_conn_destroy(struct rds_connection *conn) */ rds_cong_remove_conn(conn); - BUG_ON(!list_empty(&conn->c_retrans)); kmem_cache_free(rds_conn_slab, conn); spin_lock_irqsave(&rds_conn_lock, flags); |