Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=a3cd7d9070be417a21905c997ee32d756d999b38
Commit:     a3cd7d9070be417a21905c997ee32d756d999b38
Parent:     a656eb758fc6e6a42659ecf5ba34a5c5a2aeec17
Author:     Olaf Kirch <[EMAIL PROTECTED]>
AuthorDate: Wed Jan 16 18:37:16 2008 +0100
Committer:  Roland Dreier <[EMAIL PROTECTED]>
CommitDate: Fri Jan 25 14:15:43 2008 -0800

    IB/fmr_pool: ib_fmr_pool_flush() should flush all dirty FMRs
    
    When a FMR is released via ib_fmr_pool_unmap(), the FMR usually ends
    up on the free_list rather than the dirty_list (because we allow a
    certain number of remappings before actually requiring a flush).
    
    However, ib_fmr_batch_release() only looks at dirty_list when flushing
    out old mappings.  This means that when ib_fmr_pool_flush() is used to
    force a flush of the FMR pool, some dirty FMRs that have not reached
    their maximum remap count will not actually be flushed.
    
    Fix this by flushing all FMRs that have been used at least once in
    ib_fmr_batch_release().
    
    Signed-off-by: Olaf Kirch <[EMAIL PROTECTED]>
    Signed-off-by: Roland Dreier <[EMAIL PROTECTED]>
---
 drivers/infiniband/core/fmr_pool.c |   21 +++++++++++++++------
 1 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/infiniband/core/fmr_pool.c 
b/drivers/infiniband/core/fmr_pool.c
index 4a476a8..6c7aa59 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,
 static void ib_fmr_batch_release(struct ib_fmr_pool *pool)
 {
        int                 ret;
-       struct ib_pool_fmr *fmr;
+       struct ib_pool_fmr *fmr, *next;
        LIST_HEAD(unmap_list);
        LIST_HEAD(fmr_list);
 
@@ -158,6 +158,20 @@ static void ib_fmr_batch_release(struct ib_fmr_pool *pool)
 #endif
        }
 
+       /*
+        * The free_list may hold FMRs that have been put there
+        * because they haven't reached the max_remap count.
+        * Invalidate their mapping as well.
+        */
+       list_for_each_entry_safe(fmr, next, &pool->free_list, list) {
+               if (fmr->remap_count == 0)
+                       continue;
+               hlist_del_init(&fmr->cache_node);
+               fmr->remap_count = 0;
+               list_add_tail(&fmr->fmr->list, &fmr_list);
+               list_move(&fmr->list, &unmap_list);
+       }
+
        list_splice(&pool->dirty_list, &unmap_list);
        INIT_LIST_HEAD(&pool->dirty_list);
        pool->dirty_len = 0;
@@ -367,11 +381,6 @@ void ib_destroy_fmr_pool(struct ib_fmr_pool *pool)
 
        i = 0;
        list_for_each_entry_safe(fmr, tmp, &pool->free_list, list) {
-               if (fmr->remap_count) {
-                       INIT_LIST_HEAD(&fmr_list);
-                       list_add_tail(&fmr->fmr->list, &fmr_list);
-                       ib_unmap_fmr(&fmr_list);
-               }
                ib_dealloc_fmr(fmr->fmr);
                list_del(&fmr->list);
                kfree(fmr);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to