Skip to content

Commit

Permalink
cma: fix calculation of aligned offset
Browse files Browse the repository at this point in the history
The align_offset parameter is used by bitmap_find_next_zero_area_off()
to represent the offset of map's base from the previous alignment
boundary; the function ensures that the returned index, plus the
align_offset, honors the specified align_mask.

The logic introduced by commit b5be83e ("mm: cma: align to physical
address, not CMA region position") has the cma driver calculate the
offset to the *next* alignment boundary.  In most cases, the base
alignment is greater than that specified when making allocations,
resulting in a zero offset whether we align up or down.  In the example
given with the commit, the base alignment (8MB) was half the requested
alignment (16MB) so the math also happened to work since the offset is
8MB in both directions.  However, when requesting allocations with an
alignment greater than twice that of the base, the returned index would
not be correctly aligned.

Also, the align_order arguments of cma_bitmap_aligned_mask() and
cma_bitmap_aligned_offset() should not be negative so the argument type
was made unsigned.

Fixes: b5be83e ("mm: cma: align to physical address, not CMA region position")
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Angus Clark <[email protected]>
Signed-off-by: Doug Berger <[email protected]>
Acked-by: Gregory Fong <[email protected]>
Cc: Doug Berger <[email protected]>
Cc: Angus Clark <[email protected]>
Cc: Laura Abbott <[email protected]>
Cc: Vlastimil Babka <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Lucas Stach <[email protected]>
Cc: Catalin Marinas <[email protected]>
Cc: Shiraz Hashim <[email protected]>
Cc: Jaewon Kim <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Doug Berger authored and torvalds committed Jul 10, 2017
1 parent a52149f commit e048cb3
Showing 1 changed file with 6 additions and 9 deletions.
15 changes: 6 additions & 9 deletions mm/cma.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,25 +59,22 @@ const char *cma_get_name(const struct cma *cma)
}

static unsigned long cma_bitmap_aligned_mask(const struct cma *cma,
int align_order)
unsigned int align_order)
{
if (align_order <= cma->order_per_bit)
return 0;
return (1UL << (align_order - cma->order_per_bit)) - 1;
}

/*
* Find a PFN aligned to the specified order and return an offset represented in
* order_per_bits.
* Find the offset of the base PFN from the specified align_order.
* The value returned is represented in order_per_bits.
*/
static unsigned long cma_bitmap_aligned_offset(const struct cma *cma,
int align_order)
unsigned int align_order)
{
if (align_order <= cma->order_per_bit)
return 0;

return (ALIGN(cma->base_pfn, (1UL << align_order))
- cma->base_pfn) >> cma->order_per_bit;
return (cma->base_pfn & ((1UL << align_order) - 1))
>> cma->order_per_bit;
}

static unsigned long cma_bitmap_pages_to_bits(const struct cma *cma,
Expand Down

0 comments on commit e048cb3

Please sign in to comment.