[ofa-general] [PATCH] IB/mthca: Clear ICM pages before handing to FW
Eli Cohen
eli at dev.mellanox.co.il
Sun Jun 22 08:55:59 PDT 2008
>From 086179f2ab6950b339dbb4e66f749a7c87e9a5be Mon Sep 17 00:00:00 2001
From: Eli Cohen <eli at mellanox.co.il>
Date: Fri, 20 Jun 2008 15:36:44 +0300
Subject: [PATCH] IB/mthca: Clear ICM pages before handing to FW
Current memfree FW has a bug which in some cases, assumes that ICM
pages passed to it are cleared -- this patch will clear any ICM page
passed to the FW. It is essential to use this patch since there are
many cards already in use which use FW with this bug. At some time
when we're sure all systems are updated with the new FW (yet to be
released), we can remove this patch.
Signed-off-by: Eli Cohen <eli at mellanox.co.il>
---
This fixes the bug reported by Arthur from SGI here:
http://lists.openfabrics.org/pipermail/general/2008-May/050026.html
drivers/infiniband/hw/mthca/mthca_memfree.c | 29 +++++++++++++++++++++++++++
1 files changed, 29 insertions(+), 0 deletions(-)
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index 9e77ba9..9596c9b 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -103,6 +103,33 @@ void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm, int coherent)
kfree(icm);
}
+static void clear_pages(struct page *page, int npages)
+{
+ struct page **page_arr;
+ int i;
+ void *buf;
+
+ page_arr = kmalloc(npages * sizeof *page_arr, GFP_KERNEL);
+ if (!page_arr) {
+ printk(KERN_WARNING "page array alloc failure\n");
+ return;
+ }
+
+ for (i = 0; i < npages; ++i)
+ page_arr[i] = page++;
+
+ buf = vmap(page_arr, npages, VM_MAP, PAGE_KERNEL);
+ if (!buf) {
+ printk(KERN_WARNING "vmap failed\n");
+ goto exit;
+ }
+ memset(buf, 0, PAGE_SIZE * npages);
+ vunmap(buf);
+
+exit:
+ kfree(page_arr);
+}
+
static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_mask)
{
struct page *page;
@@ -111,6 +138,8 @@ static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_m
if (!page)
return -ENOMEM;
+ clear_pages(page, 1 << order);
+
sg_set_page(mem, page, PAGE_SIZE << order, 0);
return 0;
}
--
1.5.5.4
More information about the general
mailing list