aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/fmr_pool.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/core/fmr_pool.c')
-rw-r--r--drivers/infiniband/core/fmr_pool.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/drivers/infiniband/core/fmr_pool.c b/drivers/infiniband/core/fmr_pool.c
index 7f00347364f7..06d502c06a4d 100644
--- a/drivers/infiniband/core/fmr_pool.c
+++ b/drivers/infiniband/core/fmr_pool.c
@@ -139,7 +139,7 @@ static inline struct ib_pool_fmr *ib_fmr_cache_lookup(struct ib_fmr_pool *pool,
139static void ib_fmr_batch_release(struct ib_fmr_pool *pool) 139static void ib_fmr_batch_release(struct ib_fmr_pool *pool)
140{ 140{
141 int ret; 141 int ret;
142 struct ib_pool_fmr *fmr, *next; 142 struct ib_pool_fmr *fmr;
143 LIST_HEAD(unmap_list); 143 LIST_HEAD(unmap_list);
144 LIST_HEAD(fmr_list); 144 LIST_HEAD(fmr_list);
145 145
@@ -158,20 +158,6 @@ static void ib_fmr_batch_release(struct ib_fmr_pool *pool)
158#endif 158#endif
159 } 159 }
160 160
161 /*
162 * The free_list may hold FMRs that have been put there
163 * because they haven't reached the max_remap count.
164 * Invalidate their mapping as well.
165 */
166 list_for_each_entry_safe(fmr, next, &pool->free_list, list) {
167 if (fmr->remap_count == 0)
168 continue;
169 hlist_del_init(&fmr->cache_node);
170 fmr->remap_count = 0;
171 list_add_tail(&fmr->fmr->list, &fmr_list);
172 list_move(&fmr->list, &unmap_list);
173 }
174
175 list_splice(&pool->dirty_list, &unmap_list); 161 list_splice(&pool->dirty_list, &unmap_list);
176 INIT_LIST_HEAD(&pool->dirty_list); 162 INIT_LIST_HEAD(&pool->dirty_list);
177 pool->dirty_len = 0; 163 pool->dirty_len = 0;
@@ -384,6 +370,11 @@ void ib_destroy_fmr_pool(struct ib_fmr_pool *pool)
384 370
385 i = 0; 371 i = 0;
386 list_for_each_entry_safe(fmr, tmp, &pool->free_list, list) { 372 list_for_each_entry_safe(fmr, tmp, &pool->free_list, list) {
373 if (fmr->remap_count) {
374 INIT_LIST_HEAD(&fmr_list);
375 list_add_tail(&fmr->fmr->list, &fmr_list);
376 ib_unmap_fmr(&fmr_list);
377 }
387 ib_dealloc_fmr(fmr->fmr); 378 ib_dealloc_fmr(fmr->fmr);
388 list_del(&fmr->list); 379 list_del(&fmr->list);
389 kfree(fmr); 380 kfree(fmr);
@@ -407,8 +398,23 @@ EXPORT_SYMBOL(ib_destroy_fmr_pool);
407 */ 398 */
408int ib_flush_fmr_pool(struct ib_fmr_pool *pool) 399int ib_flush_fmr_pool(struct ib_fmr_pool *pool)
409{ 400{
410 int serial = atomic_inc_return(&pool->req_ser); 401 int serial;
402 struct ib_pool_fmr *fmr, *next;
403
404 /*
405 * The free_list holds FMRs that may have been used
406 * but have not been remapped enough times to be dirty.
407 * Put them on the dirty list now so that the cleanup
408 * thread will reap them too.
409 */
410 spin_lock_irq(&pool->pool_lock);
411 list_for_each_entry_safe(fmr, next, &pool->free_list, list) {
412 if (fmr->remap_count > 0)
413 list_move(&fmr->list, &pool->dirty_list);
414 }
415 spin_unlock_irq(&pool->pool_lock);
411 416
417 serial = atomic_inc_return(&pool->req_ser);
412 wake_up_process(pool->thread); 418 wake_up_process(pool->thread);
413 419
414 if (wait_event_interruptible(pool->force_wait, 420 if (wait_event_interruptible(pool->force_wait,