aboutsummaryrefslogtreecommitdiffstats
path: root/net/rds/ib_rdma.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/rds/ib_rdma.c')
-rw-r--r--net/rds/ib_rdma.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c
index 4ba01b9ffd44..64b5ede037c8 100644
--- a/net/rds/ib_rdma.c
+++ b/net/rds/ib_rdma.c
@@ -87,6 +87,7 @@ static struct rds_ib_device *rds_ib_get_device(__be32 ipaddr)
87 rcu_read_lock(); 87 rcu_read_lock();
88 list_for_each_entry_rcu(i_ipaddr, &rds_ibdev->ipaddr_list, list) { 88 list_for_each_entry_rcu(i_ipaddr, &rds_ibdev->ipaddr_list, list) {
89 if (i_ipaddr->ipaddr == ipaddr) { 89 if (i_ipaddr->ipaddr == ipaddr) {
90 atomic_inc(&rds_ibdev->refcount);
90 rcu_read_unlock(); 91 rcu_read_unlock();
91 return rds_ibdev; 92 return rds_ibdev;
92 } 93 }
@@ -141,8 +142,10 @@ int rds_ib_update_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr)
141 struct rds_ib_device *rds_ibdev_old; 142 struct rds_ib_device *rds_ibdev_old;
142 143
143 rds_ibdev_old = rds_ib_get_device(ipaddr); 144 rds_ibdev_old = rds_ib_get_device(ipaddr);
144 if (rds_ibdev_old) 145 if (rds_ibdev_old) {
145 rds_ib_remove_ipaddr(rds_ibdev_old, ipaddr); 146 rds_ib_remove_ipaddr(rds_ibdev_old, ipaddr);
147 rds_ib_dev_put(rds_ibdev_old);
148 }
146 149
147 return rds_ib_add_ipaddr(rds_ibdev, ipaddr); 150 return rds_ib_add_ipaddr(rds_ibdev, ipaddr);
148} 151}
@@ -163,6 +166,7 @@ void rds_ib_add_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *con
163 spin_unlock_irq(&ib_nodev_conns_lock); 166 spin_unlock_irq(&ib_nodev_conns_lock);
164 167
165 ic->rds_ibdev = rds_ibdev; 168 ic->rds_ibdev = rds_ibdev;
169 atomic_inc(&rds_ibdev->refcount);
166} 170}
167 171
168void rds_ib_remove_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *conn) 172void rds_ib_remove_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *conn)
@@ -182,6 +186,7 @@ void rds_ib_remove_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *
182 spin_unlock(&ib_nodev_conns_lock); 186 spin_unlock(&ib_nodev_conns_lock);
183 187
184 ic->rds_ibdev = NULL; 188 ic->rds_ibdev = NULL;
189 rds_ib_dev_put(rds_ibdev);
185} 190}
186 191
187void __rds_ib_destroy_conns(struct list_head *list, spinlock_t *list_lock) 192void __rds_ib_destroy_conns(struct list_head *list, spinlock_t *list_lock)
@@ -240,7 +245,7 @@ void rds_ib_get_mr_info(struct rds_ib_device *rds_ibdev, struct rds_info_rdma_co
240 245
241void rds_ib_destroy_mr_pool(struct rds_ib_mr_pool *pool) 246void rds_ib_destroy_mr_pool(struct rds_ib_mr_pool *pool)
242{ 247{
243 flush_workqueue(rds_wq); 248 cancel_work_sync(&pool->flush_worker);
244 rds_ib_flush_mr_pool(pool, 1); 249 rds_ib_flush_mr_pool(pool, 1);
245 WARN_ON(atomic_read(&pool->item_count)); 250 WARN_ON(atomic_read(&pool->item_count));
246 WARN_ON(atomic_read(&pool->free_pinned)); 251 WARN_ON(atomic_read(&pool->free_pinned));
@@ -597,6 +602,8 @@ void rds_ib_free_mr(void *trans_private, int invalidate)
597 queue_work(rds_wq, &pool->flush_worker); 602 queue_work(rds_wq, &pool->flush_worker);
598 } 603 }
599 } 604 }
605
606 rds_ib_dev_put(rds_ibdev);
600} 607}
601 608
602void rds_ib_flush_mrs(void) 609void rds_ib_flush_mrs(void)
@@ -640,6 +647,7 @@ void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents,
640 printk(KERN_WARNING "RDS/IB: map_fmr failed (errno=%d)\n", ret); 647 printk(KERN_WARNING "RDS/IB: map_fmr failed (errno=%d)\n", ret);
641 648
642 ibmr->device = rds_ibdev; 649 ibmr->device = rds_ibdev;
650 rds_ibdev = NULL;
643 651
644 out: 652 out:
645 if (ret) { 653 if (ret) {
@@ -647,5 +655,7 @@ void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents,
647 rds_ib_free_mr(ibmr, 0); 655 rds_ib_free_mr(ibmr, 0);
648 ibmr = ERR_PTR(ret); 656 ibmr = ERR_PTR(ret);
649 } 657 }
658 if (rds_ibdev)
659 rds_ib_dev_put(rds_ibdev);
650 return ibmr; 660 return ibmr;
651} 661}