diff options
Diffstat (limited to 'net/rds/ib_rdma.c')
-rw-r--r-- | net/rds/ib_rdma.c | 14 |
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 | ||
168 | void rds_ib_remove_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *conn) | 172 | void 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 | ||
187 | void __rds_ib_destroy_conns(struct list_head *list, spinlock_t *list_lock) | 192 | void __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 | ||
241 | void rds_ib_destroy_mr_pool(struct rds_ib_mr_pool *pool) | 246 | void 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 | ||
602 | void rds_ib_flush_mrs(void) | 609 | void 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 | } |