Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm: compaction: validate pfn range passed to isolate_freepages_block

Commit 0bf380bc70ec ("mm: compaction: check pfn_valid when entering a
new MAX_ORDER_NR_PAGES block during isolation for migration") added a
check for pfn_valid() when isolating pages for migration as the scanner
does not necessarily start pageblock-aligned.

Since commit c89511ab2f8f ("mm: compaction: Restart compaction from near
where it left off"), the free scanner has the same problem. This patch
makes sure that the pfn range passed to isolate_freepages_block() is
within the same block so that pfn_valid() checks are unnecessary.

In answer to Henrik's wondering why others have not reported this:
reproducing this requires a large enough hole with the right aligment to
have compaction walk into a PFN range with no memmap. Size and
alignment depends in the memory model - 4M for FLATMEM and 128M for
SPARSEMEM on x86. It needs a "lucky" machine.

Reported-by: Henrik Rydberg <rydberg@euromail.se>
Signed-off-by: Mel Gorman <mgorman@suse.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Mel Gorman and committed by
Linus Torvalds
60177d31 04c5decd

+9 -1
+9 -1
mm/compaction.c
··· 713 713 714 714 /* Found a block suitable for isolating free pages from */ 715 715 isolated = 0; 716 - end_pfn = min(pfn + pageblock_nr_pages, zone_end_pfn); 716 + 717 + /* 718 + * As pfn may not start aligned, pfn+pageblock_nr_page 719 + * may cross a MAX_ORDER_NR_PAGES boundary and miss 720 + * a pfn_valid check. Ensure isolate_freepages_block() 721 + * only scans within a pageblock 722 + */ 723 + end_pfn = ALIGN(pfn + 1, pageblock_nr_pages); 724 + end_pfn = min(end_pfn, zone_end_pfn); 717 725 isolated = isolate_freepages_block(cc, pfn, end_pfn, 718 726 freelist, false); 719 727 nr_freepages += isolated;