From: Olaf Kirch <[EMAIL PROTECTED]> Subject: [fmr_pool] fmr_pool_flush didn't flush all MRs
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 can lead to memory corruption as the user expects *all* old mappings to go away. Signed-off-by: Olaf Kirch <[EMAIL PROTECTED]> --- drivers/infiniband/core/fmr_pool.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) Index: ofa_kernel-1.3/drivers/infiniband/core/fmr_pool.c =================================================================== --- ofa_kernel-1.3.orig/drivers/infiniband/core/fmr_pool.c +++ ofa_kernel-1.3/drivers/infiniband/core/fmr_pool.c @@ -139,7 +139,7 @@ static inline struct ib_pool_fmr *ib_fmr 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,19 @@ static void ib_fmr_batch_release(struct #endif } + /* The free_list may hold FMRs that have been put there + * because they haven't reached the max_remap count. We want + * to 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; -- Olaf Kirch | --- o --- Nous sommes du soleil we love when we play [EMAIL PROTECTED] | / | \ sol.dhoop.naytheet.ah kin.ir.samse.qurax _______________________________________________ ewg mailing list ewg@lists.openfabrics.org http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ewg