summaryrefslogtreecommitdiffstats
path: root/net/rds/ib.c
diff options
context:
space:
mode:
authorZach Brown <zach.brown@oracle.com>2010-06-25 23:59:49 +0200
committerAndy Grover <andy.grover@oracle.com>2010-09-09 03:16:32 +0200
commit24fa163a4bae74b3378d30e1bc776568cfca8121 (patch)
tree309638f0739708cecd066ebad43f95832e3f8dd8 /net/rds/ib.c
parentRDS/IB: Make ib_recv_refill return void (diff)
downloadlinux-24fa163a4bae74b3378d30e1bc776568cfca8121.tar.xz
linux-24fa163a4bae74b3378d30e1bc776568cfca8121.zip
RDS/IB: wait for IB dev freeing work to finish during rmmod
The RDS IB client removal callback can queue work to drop the final reference to an IB device. We have to make sure that this function has returned before we complete rmmod or the work threads can try to execute freed code. Signed-off-by: Zach Brown <zach.brown@oracle.com>
Diffstat (limited to '')
-rw-r--r--net/rds/ib.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/net/rds/ib.c b/net/rds/ib.c
index b21e24fd060c..fc14f637d645 100644
--- a/net/rds/ib.c
+++ b/net/rds/ib.c
@@ -336,11 +336,18 @@ static int rds_ib_laddr_check(__be32 addr)
return ret;
}
+static void rds_ib_unregister_client(void)
+{
+ ib_unregister_client(&rds_ib_client);
+ /* wait for rds_ib_dev_free() to complete */
+ flush_workqueue(rds_wq);
+}
+
void rds_ib_exit(void)
{
rds_info_deregister_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info);
rds_ib_destroy_nodev_conns();
- ib_unregister_client(&rds_ib_client);
+ rds_ib_unregister_client();
rds_ib_sysctl_exit();
rds_ib_recv_exit();
rds_trans_unregister(&rds_ib_transport);
@@ -404,7 +411,7 @@ out_recv:
out_sysctl:
rds_ib_sysctl_exit();
out_ibreg:
- ib_unregister_client(&rds_ib_client);
+ rds_ib_unregister_client();
out:
return ret;
}