aboutsummaryrefslogtreecommitdiffstats
path: root/net/rds
diff options
context:
space:
mode:
authorZach Brown <zach.brown@oracle.com>2010-06-25 17:59:49 -0400
committerAndy Grover <andy.grover@oracle.com>2010-09-08 21:16:32 -0400
commit24fa163a4bae74b3378d30e1bc776568cfca8121 (patch)
tree309638f0739708cecd066ebad43f95832e3f8dd8 /net/rds
parentb6fb0df12db6c8b6bbcc7b5c9459b3bbf5f0cee6 (diff)
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 'net/rds')
-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)
336 return ret; 336 return ret;
337} 337}
338 338
339static void rds_ib_unregister_client(void)
340{
341 ib_unregister_client(&rds_ib_client);
342 /* wait for rds_ib_dev_free() to complete */
343 flush_workqueue(rds_wq);
344}
345
339void rds_ib_exit(void) 346void rds_ib_exit(void)
340{ 347{
341 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);
342 rds_ib_destroy_nodev_conns(); 349 rds_ib_destroy_nodev_conns();
343 ib_unregister_client(&rds_ib_client); 350 rds_ib_unregister_client();
344 rds_ib_sysctl_exit(); 351 rds_ib_sysctl_exit();
345 rds_ib_recv_exit(); 352 rds_ib_recv_exit();
346 rds_trans_unregister(&rds_ib_transport); 353 rds_trans_unregister(&rds_ib_transport);
@@ -404,7 +411,7 @@ out_recv:
404out_sysctl: 411out_sysctl:
405 rds_ib_sysctl_exit(); 412 rds_ib_sysctl_exit();
406out_ibreg: 413out_ibreg:
407 ib_unregister_client(&rds_ib_client); 414 rds_ib_unregister_client();
408out: 415out:
409 return ret; 416 return ret;
410} 417}