Skip to content

Commit be21b32

Browse files
nariba-fjakpm00
authored andcommitted
mm, compaction: fix fast_isolate_around() to stay within boundaries
Depending on the memory configuration, isolate_freepages_block() may scan pages out of the target range and causes panic. Panic can occur on systems with multiple zones in a single pageblock. The reason it is rare is that it only happens in special configurations. Depending on how many similar systems there are, it may be a good idea to fix this problem for older kernels as well. The problem is that pfn as argument of fast_isolate_around() could be out of the target range. Therefore we should consider the case where pfn < start_pfn, and also the case where end_pfn < pfn. This problem should have been addressd by the commit 6e2b704 ("mm, compaction: make fast_isolate_freepages() stay within zone") but there was an oversight. Case1: pfn < start_pfn <at memory compaction for node Y> | node X's zone | node Y's zone +-----------------+------------------------------... pageblock ^ ^ ^ +-----------+-----------+-----------+-----------+... ^ ^ ^ ^ ^ end_pfn ^ start_pfn = cc->zone->zone_start_pfn pfn <---------> scanned range by "Scan After" Case2: end_pfn < pfn <at memory compaction for node X> | node X's zone | node Y's zone +-----------------+------------------------------... pageblock ^ ^ ^ +-----------+-----------+-----------+-----------+... ^ ^ ^ ^ ^ pfn ^ end_pfn start_pfn <---------> scanned range by "Scan Before" It seems that there is no good reason to skip nr_isolated pages just after given pfn. So let perform simple scan from start to end instead of dividing the scan into "Before" and "After". Link: https://lkml.kernel.org/r/[email protected] Fixes: 6e2b704 ("mm, compaction: make fast_isolate_freepages() stay within zone"). Signed-off-by: NARIBAYASHI Akira <[email protected]> Cc: David Rientjes <[email protected]> Cc: Mel Gorman <[email protected]> Cc: Vlastimil Babka <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent eba3923 commit be21b32

1 file changed

Lines changed: 5 additions & 13 deletions

File tree

mm/compaction.c

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,7 +1344,7 @@ move_freelist_tail(struct list_head *freelist, struct page *freepage)
13441344
}
13451345

13461346
static void
1347-
fast_isolate_around(struct compact_control *cc, unsigned long pfn, unsigned long nr_isolated)
1347+
fast_isolate_around(struct compact_control *cc, unsigned long pfn)
13481348
{
13491349
unsigned long start_pfn, end_pfn;
13501350
struct page *page;
@@ -1365,21 +1365,13 @@ fast_isolate_around(struct compact_control *cc, unsigned long pfn, unsigned long
13651365
if (!page)
13661366
return;
13671367

1368-
/* Scan before */
1369-
if (start_pfn != pfn) {
1370-
isolate_freepages_block(cc, &start_pfn, pfn, &cc->freepages, 1, false);
1371-
if (cc->nr_freepages >= cc->nr_migratepages)
1372-
return;
1373-
}
1374-
1375-
/* Scan after */
1376-
start_pfn = pfn + nr_isolated;
1377-
if (start_pfn < end_pfn)
1378-
isolate_freepages_block(cc, &start_pfn, end_pfn, &cc->freepages, 1, false);
1368+
isolate_freepages_block(cc, &start_pfn, end_pfn, &cc->freepages, 1, false);
13791369

13801370
/* Skip this pageblock in the future as it's full or nearly full */
13811371
if (cc->nr_freepages < cc->nr_migratepages)
13821372
set_pageblock_skip(page);
1373+
1374+
return;
13831375
}
13841376

13851377
/* Search orders in round-robin fashion */
@@ -1556,7 +1548,7 @@ fast_isolate_freepages(struct compact_control *cc)
15561548
return cc->free_pfn;
15571549

15581550
low_pfn = page_to_pfn(page);
1559-
fast_isolate_around(cc, low_pfn, nr_isolated);
1551+
fast_isolate_around(cc, low_pfn);
15601552
return low_pfn;
15611553
}
15621554

0 commit comments

Comments
 (0)