[ofa-general] Re: [PATCH] IB/mthca: Clear ICM pages before handing to FW
Eli Cohen
eli at dev.mellanox.co.il
Sun Jun 22 23:35:37 PDT 2008
On Sun, Jun 22, 2008 at 12:57:26PM -0700, Roland Dreier wrote:
> I would expect all the other costs of mapping pages into/out of the ICM
> to be large enough that the cost of zeroing a page is not too big a
> deal. But if there is anyone who cares we can always make this
> __GFP_ZERO flag conditional on FW version I guess.
Makes sense.
> To the best of my knowledge, kmap_atomic() cannot fail -- and if you
> think about it, what could make it fail? The whole point of
> kmap_atomic() is that there is a per-cpu pre-reserved slot to map the
> memory at for highmem pages, so it has to always work.
Looking at the implementation of kmap_atomic() quoted bellow:
void *page_address(struct page *page)
{
unsigned long flags;
void *ret;
struct page_address_slot *pas;
if (!PageHighMem(page))
return lowmem_page_address(page);
pas = page_slot(page);
ret = NULL;
spin_lock_irqsave(&pas->lock, flags);
if (!list_empty(&pas->lh)) {
struct page_address_map *pam;
list_for_each_entry(pam, &pas->lh, list) {
if (pam->page == page) {
ret = pam->virtual;
goto done;
}
}
}
done:
spin_unlock_irqrestore(&pas->lock, flags);
return ret;
}
static inline void *kmap_atomic(struct page *page, enum km_type idx)
{
pagefault_disable();
return page_address(page);
}
I can't see page_address doing anything actively to map the page. It
just searches for the page and returns it's mapping. But I'm probably
missing something.
> As far as I can
> see, __GFP_ZERO allocations use clear_highpage() internally anyway, so
> it ends up being the same thing.
Yes, now I can see that.
>
> Since just adding __GFP_ZERO is so much simpler, I'll just commit the
> patch below and send it to Linus in a day or two if it seems OK to you:
>
> commit 801d1ad7b6bdb3418a462c6b4950aee56dbac940
> Author: Eli Cohen <eli at mellanox.co.il>
> Date: Sun Jun 22 12:56:58 2008 -0700
>
> 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 uses __GFP_ZERO to
> allocate all ICM pages passed to the FW. Once firmware with a fix is
> released, we can make the workaround conditional on firmware version.
>
> This fixes the bug reported by Arthur Kepner <akepner at sgi.com> here:
> http://lists.openfabrics.org/pipermail/general/2008-May/050026.html
>
> Signed-off-by: Eli Cohen <eli at mellanox.co.il>
>
> [ Rewritten to be a one-liner using __GFP_ZERO instead of vmap()ing
> ICM memory and memset()ing it to 0. - Roland ]
>
> Signed-off-by: Roland Dreier <rolandd at cisco.com>
>
> diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
> index 9e77ba9..1f7d1a2 100644
> --- a/drivers/infiniband/hw/mthca/mthca_memfree.c
> +++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
> @@ -107,7 +107,11 @@ static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_m
> {
> struct page *page;
>
> - page = alloc_pages(gfp_mask, order);
> + /*
> + * Use __GFP_ZERO because buggy firmware assumes ICM pages are
> + * cleared, and subtle failures are seen if they aren't.
> + */
> + page = alloc_pages(gfp_mask | __GFP_ZERO, order);
> if (!page)
> return -ENOMEM;
>
Of course. Go ahead and send it.
Thanks.
More information about the general
mailing list