From 8dc5ba15c54942aabf0e2f30b73c202a252633c1 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 23 Jan 2017 17:05:19 -0800 Subject: [PATCH] mm: fix and clarify section_active_mask() section_active_mask() converts a range of pfns into a bitmask where each bit represents a 2M sub-range of a 128MB section (on x86_64). Clarify that we expect that the arguments do not cross a section boundary, fix the case where the start pfn is section aligned, but nr_pages is less than a section, and use ULONG_MAX instead of -1 to represent to the mask full case. Cc: Michal Hocko Cc: Vlastimil Babka Cc: Johannes Weiner Cc: Logan Gunthorpe Cc: Mel Gorman Cc: Stephen Bates Reported-by: Andrew Morton Signed-off-by: Dan Williams --- mm/sparse.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/mm/sparse.c b/mm/sparse.c index 4267d09b656b..7bb792b719b5 100644 --- a/mm/sparse.c +++ b/mm/sparse.c @@ -195,11 +195,18 @@ static unsigned long section_active_mask(unsigned long pfn, int idx_start, idx_size; phys_addr_t start, size; + WARN_ON((pfn & ~PAGE_SECTION_MASK) + nr_pages > PAGES_PER_SECTION); if (!nr_pages) return 0; + /* + * The size is the number of pages left in the section or + * nr_pages, whichever is smaller. The size will be rounded up + * to the next SECTION_ACTIVE_SIZE boundary, the start will be + * rounded down. + */ start = PFN_PHYS(pfn); - size = PFN_PHYS(min(nr_pages, PAGES_PER_SECTION + size = PFN_PHYS(min_not_zero(nr_pages, PAGES_PER_SECTION - (pfn & ~PAGE_SECTION_MASK))); size = ALIGN(size, SECTION_ACTIVE_SIZE); @@ -207,7 +214,7 @@ static unsigned long section_active_mask(unsigned long pfn, idx_size = section_active_index(size); if (idx_size == 0) - return -1; + return ULONG_MAX; /* full section */ return ((1UL << idx_size) - 1) << idx_start; } -- 2.7.4