Subject: + mm-compaction-make-isolate_freepages-start-at-pageblock-boundary.patch added to -mm tree To: vbabka@xxxxxxx,b.zolnierkie@xxxxxxxxxxx,cl@xxxxxxxxx,d.j.shin@xxxxxxxxxxx,heesub.shin@xxxxxxxxxxx,iamjoonsoo.kim@xxxxxxx,mgorman@xxxxxxx,mina86@xxxxxxxxxx,minchan@xxxxxxxxxx,n-horiguchi@xxxxxxxxxxxxx,riel@xxxxxxxxxx,stable@xxxxxxxxxxxxxxx,sunghwan.yun@xxxxxxxxxxx From: akpm@xxxxxxxxxxxxxxxxxxxx Date: Mon, 21 Apr 2014 12:42:14 -0700 The patch titled Subject: mm/compaction: make isolate_freepages start at pageblock boundary has been added to the -mm tree. Its filename is mm-compaction-make-isolate_freepages-start-at-pageblock-boundary.patch This patch should soon appear at http://ozlabs.org/~akpm/mmots/broken-out/mm-compaction-make-isolate_freepages-start-at-pageblock-boundary.patch and later at http://ozlabs.org/~akpm/mmotm/broken-out/mm-compaction-make-isolate_freepages-start-at-pageblock-boundary.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/SubmitChecklist when testing your code *** The -mm tree is included into linux-next and is updated there every 3-4 working days ------------------------------------------------------ From: Vlastimil Babka <vbabka@xxxxxxx> Subject: mm/compaction: make isolate_freepages start at pageblock boundary The compaction freepage scanner implementation in isolate_freepages() starts by taking the current cc->free_pfn value as the first pfn. In a for loop, it scans from this first pfn to the end of the pageblock, and then subtracts pageblock_nr_pages from the first pfn to obtain the first pfn for the next for loop iteration. This means that when cc->free_pfn starts at offset X rather than being aligned on pageblock boundary, the scanner will start at offset X in all scanned pageblock, ignoring potentially many free pages. Currently this can happen when a) zone's end pfn is not pageblock aligned, or b) through zone->compact_cached_free_pfn with CONFIG_HOLES_IN_ZONE enabled and a hole spanning the beginning of a pageblock This patch fixes the problem by aligning the initial pfn in isolate_freepages() to pageblock boundary. This also permits replacing the end-of-pageblock alignment within the for loop with a simple pageblock_nr_pages increment. Signed-off-by: Vlastimil Babka <vbabka@xxxxxxx> Reported-by: Heesub Shin <heesub.shin@xxxxxxxxxxx> Acked-by: Minchan Kim <minchan@xxxxxxxxxx> Cc: Mel Gorman <mgorman@xxxxxxx> Acked-by: Joonsoo Kim <iamjoonsoo.kim@xxxxxxx> Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@xxxxxxxxxxx> Cc: Michal Nazarewicz <mina86@xxxxxxxxxx> Cc: Naoya Horiguchi <n-horiguchi@xxxxxxxxxxxxx> Cc: Christoph Lameter <cl@xxxxxxxxx> Acked-by: Rik van Riel <riel@xxxxxxxxxx> Cc: Dongjun Shin <d.j.shin@xxxxxxxxxxx> Cc: Sunghwan Yun <sunghwan.yun@xxxxxxxxxxx> Cc: <stable@xxxxxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- mm/compaction.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff -puN mm/compaction.c~mm-compaction-make-isolate_freepages-start-at-pageblock-boundary mm/compaction.c --- a/mm/compaction.c~mm-compaction-make-isolate_freepages-start-at-pageblock-boundary +++ a/mm/compaction.c @@ -671,16 +671,20 @@ static void isolate_freepages(struct zon struct compact_control *cc) { struct page *page; - unsigned long high_pfn, low_pfn, pfn, z_end_pfn, end_pfn; + unsigned long high_pfn, low_pfn, pfn, z_end_pfn; int nr_freepages = cc->nr_freepages; struct list_head *freelist = &cc->freepages; /* * Initialise the free scanner. The starting point is where we last - * scanned from (or the end of the zone if starting). The low point - * is the end of the pageblock the migration scanner is using. + * successfully isolated from, zone-cached value, or the end of the + * zone when isolating for the first time. We need this aligned to + * the pageblock boundary, because we do pfn -= pageblock_nr_pages + * in the for loop. + * The low boundary is the end of the pageblock the migration scanner + * is using. */ - pfn = cc->free_pfn; + pfn = cc->free_pfn & ~(pageblock_nr_pages-1); low_pfn = ALIGN(cc->migrate_pfn + 1, pageblock_nr_pages); /* @@ -700,6 +704,7 @@ static void isolate_freepages(struct zon for (; pfn >= low_pfn && cc->nr_migratepages > nr_freepages; pfn -= pageblock_nr_pages) { unsigned long isolated; + unsigned long end_pfn; /* * This can iterate a massively long zone without finding any @@ -734,13 +739,10 @@ static void isolate_freepages(struct zon isolated = 0; /* - * As pfn may not start aligned, pfn+pageblock_nr_page - * may cross a MAX_ORDER_NR_PAGES boundary and miss - * a pfn_valid check. Ensure isolate_freepages_block() - * only scans within a pageblock + * Take care when isolating in last pageblock of a zone which + * ends in the middle of a pageblock. */ - end_pfn = ALIGN(pfn + 1, pageblock_nr_pages); - end_pfn = min(end_pfn, z_end_pfn); + end_pfn = min(pfn + pageblock_nr_pages, z_end_pfn); isolated = isolate_freepages_block(cc, pfn, end_pfn, freelist, false); nr_freepages += isolated; _ Patches currently in -mm which might be from vbabka@xxxxxxx are mm-compaction-make-isolate_freepages-start-at-pageblock-boundary.patch mm-compactionc-isolate_freepages_block-small-tuneup.patch mm-page_alloc-prevent-migrate_reserve-pages-from-being-misplaced.patch mm-page_alloc-debug_vm-checks-for-free_list-placement-of-cma-and-reserve-pages.patch mm-compaction-clean-up-unused-code-lines.patch mm-compaction-cleanup-isolate_freepages.patch mm-compaction-cleanup-isolate_freepages-fix.patch -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html