aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZach Brown <zach.brown@oracle.com>2010-06-25 17:58:16 -0400
committerAndy Grover <andy.grover@oracle.com>2010-09-08 21:16:33 -0400
commit8aeb1ba6630ffd44001ae9833842794df0107676 (patch)
treebc9a78da5281b371d3a9ecb2e00f7c381d9cd33b
parent24fa163a4bae74b3378d30e1bc776568cfca8121 (diff)
RDS/IB: destroy connections on rmmod
IB connections were not being destroyed during rmmod. First, recently IB device removal callback was changed to disconnect connections that used the removing device rather than destroying them. So connections with devices during rmmod were not being destroyed. Second, rds_ib_destroy_nodev_conns() was being called before connections are disassociated with devices. It would almost never find connections in the nodev list. We first get rid of rds_ib_destroy_conns(), which is no longer called, and refactor the existing caller into the main body of the function and get rid of the list and lock wrappers. Then we call rds_ib_destroy_nodev_conns() *after* ib_unregister_client() has removed the IB device from all the conns and put the conns on the nodev list. The result is that IB connections are destroyed by rmmod. Signed-off-by: Zach Brown <zach.brown@oracle.com>
-rw-r--r--net/rds/ib.c2
-rw-r--r--net/rds/ib.h10
-rw-r--r--net/rds/ib_rdma.c9
3 files changed, 6 insertions, 15 deletions
diff --git a/net/rds/ib.c b/net/rds/ib.c
index fc14f637d645..af1ef18b6ff0 100644
--- a/net/rds/ib.c
+++ b/net/rds/ib.c
@@ -346,8 +346,8 @@ static void rds_ib_unregister_client(void)
346void rds_ib_exit(void) 346void rds_ib_exit(void)
347{ 347{
348 rds_info_deregister_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info); 348 rds_info_deregister_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info);
349 rds_ib_destroy_nodev_conns();
350 rds_ib_unregister_client(); 349 rds_ib_unregister_client();
350 rds_ib_destroy_nodev_conns();
351 rds_ib_sysctl_exit(); 351 rds_ib_sysctl_exit();
352 rds_ib_recv_exit(); 352 rds_ib_recv_exit();
353 rds_trans_unregister(&rds_ib_transport); 353 rds_trans_unregister(&rds_ib_transport);
diff --git a/net/rds/ib.h b/net/rds/ib.h
index 6265ada08959..e9f9ddf440ca 100644
--- a/net/rds/ib.h
+++ b/net/rds/ib.h
@@ -299,15 +299,7 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn,
299int rds_ib_update_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr); 299int rds_ib_update_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr);
300void rds_ib_add_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *conn); 300void rds_ib_add_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *conn);
301void rds_ib_remove_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *conn); 301void rds_ib_remove_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *conn);
302void __rds_ib_destroy_conns(struct list_head *list, spinlock_t *list_lock); 302void rds_ib_destroy_nodev_conns(void);
303static inline void rds_ib_destroy_nodev_conns(void)
304{
305 __rds_ib_destroy_conns(&ib_nodev_conns, &ib_nodev_conns_lock);
306}
307static inline void rds_ib_destroy_conns(struct rds_ib_device *rds_ibdev)
308{
309 __rds_ib_destroy_conns(&rds_ibdev->conn_list, &rds_ibdev->spinlock);
310}
311struct rds_ib_mr_pool *rds_ib_create_mr_pool(struct rds_ib_device *); 303struct rds_ib_mr_pool *rds_ib_create_mr_pool(struct rds_ib_device *);
312void rds_ib_get_mr_info(struct rds_ib_device *rds_ibdev, struct rds_info_rdma_connection *iinfo); 304void rds_ib_get_mr_info(struct rds_ib_device *rds_ibdev, struct rds_info_rdma_connection *iinfo);
313void rds_ib_destroy_mr_pool(struct rds_ib_mr_pool *); 305void rds_ib_destroy_mr_pool(struct rds_ib_mr_pool *);
diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c
index 2a4ec1182ba6..00f3995351c8 100644
--- a/net/rds/ib_rdma.c
+++ b/net/rds/ib_rdma.c
@@ -198,16 +198,15 @@ void rds_ib_remove_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *
198 rds_ib_dev_put(rds_ibdev); 198 rds_ib_dev_put(rds_ibdev);
199} 199}
200 200
201void __rds_ib_destroy_conns(struct list_head *list, spinlock_t *list_lock) 201void rds_ib_destroy_nodev_conns(void)
202{ 202{
203 struct rds_ib_connection *ic, *_ic; 203 struct rds_ib_connection *ic, *_ic;
204 LIST_HEAD(tmp_list); 204 LIST_HEAD(tmp_list);
205 205
206 /* avoid calling conn_destroy with irqs off */ 206 /* avoid calling conn_destroy with irqs off */
207 spin_lock_irq(list_lock); 207 spin_lock_irq(&ib_nodev_conns_lock);
208 list_splice(list, &tmp_list); 208 list_splice(&ib_nodev_conns, &tmp_list);
209 INIT_LIST_HEAD(list); 209 spin_unlock_irq(&ib_nodev_conns_lock);
210 spin_unlock_irq(list_lock);
211 210
212 list_for_each_entry_safe(ic, _ic, &tmp_list, ib_node) 211 list_for_each_entry_safe(ic, _ic, &tmp_list, ib_node)
213 rds_conn_destroy(ic->conn); 212 rds_conn_destroy(ic->conn);