IB/mthca: Fix and simplify page size calculation in mthca_reg_phys_mr()
authorRoland Dreier <rolandd@cisco.com>
Tue, 5 Feb 2008 04:20:42 +0000 (20:20 -0800)
committerRoland Dreier <rolandd@cisco.com>
Tue, 5 Feb 2008 04:20:42 +0000 (20:20 -0800)
commit0d89fe2c0ca12ad2ee4e35a0661319746af6e94a
treefcc5d6598121a4863740437baf10217b701ca153
parent2b5e6b120e58d44cace68e6c7204b541a8b0b43f
IB/mthca: Fix and simplify page size calculation in mthca_reg_phys_mr()

In mthca_reg_phys_mr(), we calculate the page size for the HCA
hardware to use to map the buffer list passed in by the consumer.
For example, if the consumer passes in

    [0] addr 0x1000, size 0x1000
    [1] addr 0x2000, size 0x1000

then the algorithm would come up with a page size of 0x2000 and a list
of two pages, at 0x0000 and 0x2000.  Usually, this would work fine
since the memory region would start at an offset of 0x1000 and have a
length of 0x2000.

However, the old code did not take into account the alignment of the
IO virtual address passed in.  For example, if the consumer passed in
a virtual address of 0x6000 for the above, then the offset of 0x1000
would not be used correctly because the page mask of 0x1fff would
result in an offset of 0.

We can fix this quite neatly by making sure that the page shift we use
is no bigger than the first bit where the start of the first buffer
and the IO virtual address differ.  Also, we can further simplify the
code by removing the special case for a single buffer by noticing that
it doesn't matter if we use a page size that is too big.  This allows
the loop to compute the page shift to be replaced with __ffs().

Thanks to Bryan S Rosenburg <rosnbrg@us.ibm.com> for pointing out the
original bug and suggesting several ways to improve this patch.

Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/infiniband/hw/mthca/mthca_provider.c