RDS/IB: destroy connections on rmmod
authorZach Brown <zach.brown@oracle.com>
Fri, 25 Jun 2010 21:58:16 +0000 (14:58 -0700)
committerAndy Grover <andy.grover@oracle.com>
Thu, 9 Sep 2010 01:16:33 +0000 (18:16 -0700)
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>
net/rds/ib.c
net/rds/ib.h
net/rds/ib_rdma.c

index fc14f637d645a5e21aaa73a146ed0d1f9fcd35c4..af1ef18b6ff0c833c1df911e6d77889a42257e3e 100644 (file)
@@ -346,8 +346,8 @@ static void rds_ib_unregister_client(void)
 void rds_ib_exit(void)
 {
        rds_info_deregister_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info);
-       rds_ib_destroy_nodev_conns();
        rds_ib_unregister_client();
+       rds_ib_destroy_nodev_conns();
        rds_ib_sysctl_exit();
        rds_ib_recv_exit();
        rds_trans_unregister(&rds_ib_transport);
index 6265ada0895968e99101f682f3de12a2cef4026a..e9f9ddf440ca99be35e8f47c7ee55572a7779f81 100644 (file)
@@ -299,15 +299,7 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn,
 int rds_ib_update_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr);
 void rds_ib_add_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *conn);
 void rds_ib_remove_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *conn);
-void __rds_ib_destroy_conns(struct list_head *list, spinlock_t *list_lock);
-static inline void rds_ib_destroy_nodev_conns(void)
-{
-       __rds_ib_destroy_conns(&ib_nodev_conns, &ib_nodev_conns_lock);
-}
-static inline void rds_ib_destroy_conns(struct rds_ib_device *rds_ibdev)
-{
-       __rds_ib_destroy_conns(&rds_ibdev->conn_list, &rds_ibdev->spinlock);
-}
+void rds_ib_destroy_nodev_conns(void);
 struct rds_ib_mr_pool *rds_ib_create_mr_pool(struct rds_ib_device *);
 void rds_ib_get_mr_info(struct rds_ib_device *rds_ibdev, struct rds_info_rdma_connection *iinfo);
 void rds_ib_destroy_mr_pool(struct rds_ib_mr_pool *);
index 2a4ec1182ba684e67444b1b8f9b043152cc0d16d..00f3995351c8f21c833be2cd44a593f3b8f67966 100644 (file)
@@ -198,16 +198,15 @@ void rds_ib_remove_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *
        rds_ib_dev_put(rds_ibdev);
 }
 
-void __rds_ib_destroy_conns(struct list_head *list, spinlock_t *list_lock)
+void rds_ib_destroy_nodev_conns(void)
 {
        struct rds_ib_connection *ic, *_ic;
        LIST_HEAD(tmp_list);
 
        /* avoid calling conn_destroy with irqs off */
-       spin_lock_irq(list_lock);
-       list_splice(list, &tmp_list);
-       INIT_LIST_HEAD(list);
-       spin_unlock_irq(list_lock);
+       spin_lock_irq(&ib_nodev_conns_lock);
+       list_splice(&ib_nodev_conns, &tmp_list);
+       spin_unlock_irq(&ib_nodev_conns_lock);
 
        list_for_each_entry_safe(ic, _ic, &tmp_list, ib_node)
                rds_conn_destroy(ic->conn);