Patch "mm/compaction: pass only pageblock aligned range to pageblock_pfn_to_page" has been added to the 4.4-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
mm/compaction: pass only pageblock aligned range to pageblock_pfn_to_page
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
mm-compaction-pass-only-pageblock-aligned-range-to-pageblock_pfn_to_page.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
e1409c325fdc1fef7b3d8025c51892355f065d15Mon Sep 17 00:00:00 2001
From: Joonsoo Kim <[email protected]>
Date: Tue, 15 Mar 2016 14:57:48 -0700
Subject: mm/compaction: pass only pageblock aligned range to pageblock_pfn_to_page
From: Joonsoo Kim <[email protected]>
commit e1409c325fdc1fef7b3d8025c51892355f065d15 upstream.
pageblock_pfn_to_page() is used to check there is valid pfn and all pages in the pageblock is in a single zone. If there is a hole in the pageblock, passing arbitrary position to pageblock_pfn_to_page() could cause to skip whole pageblock scanning, instead of just skipping the hole page. For deterministic behaviour, it's better to always pass pageblock aligned range to pageblock_pfn_to_page(). It will also help further optimization on pageblock_pfn_to_page() in the following patch.
--- mm/compaction.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-)
mm/compaction.c +30 -11
@@ -553,13 +553,17 @@ unsigned long isolate_freepages_range(struct compact_control *cc, unsigned long start_pfn, unsigned long end_pfn) { - unsigned long isolated, pfn, block_end_pfn; + unsigned long isolated, pfn, block_start_pfn, block_end_pfn;LIST_HEAD (freelist); pfn = start_pfn; + block_start_pfn = pfn & ~(pageblock_nr_pages -1 ); +if (block_start_pfn < cc->zone->zone_start_pfn) + block_start_pfn = cc->zone->zone_start_pfn; block_end_pfn =ALIGN (pfn +1 , pageblock_nr_pages);for (; pfn < end_pfn; pfn += isolated, + block_start_pfn = block_end_pfn, block_end_pfn += pageblock_nr_pages) {/* Protect pfn from changing by isolate_freepages_block */ unsigned long isolate_start_pfn = pfn;
@@ -572,11 +576,13 @@ isolate_freepages_range(struct compact_c* scanning range to right one. */ if (pfn >= block_end_pfn) { + block_start_pfn = pfn & ~(pageblock_nr_pages -1 ); block_end_pfn =ALIGN (pfn +1 , pageblock_nr_pages); block_end_pfn =min (block_end_pfn, end_pfn); } -if (!pageblock_pfn_to_page (pfn, block_end_pfn, cc->zone)) +if (!pageblock_pfn_to_page (block_start_pfn, + block_end_pfn, cc->zone))break ; isolated = isolate_freepages_block(cc, &isolate_start_pfn,
@@ -862,18 +868,23 @@ unsigned long isolate_migratepages_range(struct compact_control *cc, unsigned long start_pfn, unsigned long end_pfn) { - unsigned long pfn, block_end_pfn; + unsigned long pfn, block_start_pfn, block_end_pfn;/* Scan block by block. First and last block may be incomplete */ pfn = start_pfn; + block_start_pfn = pfn & ~(pageblock_nr_pages -1 ); +if (block_start_pfn < cc->zone->zone_start_pfn) + block_start_pfn = cc->zone->zone_start_pfn; block_end_pfn =ALIGN (pfn +1 , pageblock_nr_pages); for (; pfn < end_pfn; pfn = block_end_pfn, + block_start_pfn = block_end_pfn, block_end_pfn += pageblock_nr_pages) { block_end_pfn = min(block_end_pfn, end_pfn); - if (!pageblock_pfn_to_page(pfn, block_end_pfn, cc->zone)) + if (!pageblock_pfn_to_page(block_start_pfn, + block_end_pfn, cc->zone)) continue; pfn = isolate_migratepages_block(cc, pfn, block_end_pfn,
@@ -1091,7 +1102,9 @@ int sysctl_compact_unevictable_allowed _static isolate_migrate_t isolate_migratepages (struct zone *zone,struct compact_control *cc) { -unsigned long low_pfn, end_pfn; +unsigned long block_start_pfn; +unsigned long block_end_pfn; +unsigned long low_pfn;unsigned long isolate_start_pfn;struct page *page; const isolate_mode_t isolate_mode =
@@ -1103,16 +1116,21 @@ static isolate_migrate_t isolate_migrate* initialized by compact_zone() */ low_pfn = cc->migrate_pfn; + block_start_pfn = cc->migrate_pfn & ~(pageblock_nr_pages -1 ); +if (block_start_pfn < zone->zone_start_pfn) + block_start_pfn = zone->zone_start_pfn;/* Only scan within a pageblock boundary */ - end_pfn =ALIGN (low_pfn +1 , pageblock_nr_pages); + block_end_pfn =ALIGN (low_pfn +1 , pageblock_nr_pages);/* * Iterate over whole pageblocks until we find the first suitable. * Do not cross the free scanner. */ -for (; end_pfn <= cc->free_pfn; - low_pfn = end_pfn, end_pfn += pageblock_nr_pages) { +for (; block_end_pfn <= cc->free_pfn; + low_pfn = block_end_pfn, + block_start_pfn = block_end_pfn, + block_end_pfn += pageblock_nr_pages) {/* * This can potentially iterate a massively long zone with
@@ -1123,7 +1141,8 @@ static isolate_migrate_t isolate_migrate && compact_should_abort(cc))break ; - page =pageblock_pfn_to_page (low_pfn, end_pfn, zone); + page =pageblock_pfn_to_page (block_start_pfn, block_end_pfn, + zone);if (!page)continue ;
@@ -1142,8 +1161,8 @@ static isolate_migrate_t isolate_migrate/* Perform the isolation */ isolate_start_pfn = low_pfn; - low_pfn =isolate_migratepages_block (cc, low_pfn, end_pfn, - isolate_mode); + low_pfn =isolate_migratepages_block (cc, low_pfn, + block_end_pfn, isolate_mode);if (!low_pfn || cc->contended) {acct_isolated (zone, cc);
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/mm-compaction-pass-only-pageblock-aligned-range-to-pageblock_pfn_to_page.patch queue-4.4/mm-compaction-fix-invalid-free_pfn-and-compact_cached_free_pfn.patch