Skip to content

Commit 8e279f9

Browse files
Hugh Dickinsakpm00
Hugh Dickins
authored andcommitted
mm/migrate: fix kernel BUG at mm/compaction.c:2761!
I hit the VM_BUG_ON(!list_empty(&cc->migratepages)) in compact_zone(); and if DEBUG_VM were off, then pages would be lost on a local list. Our convention is that if migrate_pages() reports complete success (0), then the migratepages list will be empty; but if it reports an error or some pages remaining, then its caller must putback_movable_pages(). There's a new case in which migrate_pages() has been reporting complete success, but returning with pages left on the migratepages list: when migrate_pages_batch() successfully split a folio on the deferred list, but then the "Failure isn't counted" call does not dispose of them all. Since that block is expecting the large folio to have been counted as 1 failure already, and since the return code is later adjusted to success whenever the returned list is found empty, the simple way to fix this safely is to count splitting the deferred folio as "a failure". Link: https://lkml.kernel.org/r/[email protected] Fixes: 7262f20 ("mm/migrate: split source folio if it is on deferred split list") Signed-off-by: Hugh Dickins <[email protected]> Cc: Baolin Wang <[email protected]> Cc: David Hildenbrand <[email protected]> Cc: "Huang, Ying" <[email protected]> Cc: Zi Yan <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent e7d2a28 commit 8e279f9

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

mm/migrate.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1654,7 +1654,12 @@ static int migrate_pages_batch(struct list_head *from,
16541654

16551655
/*
16561656
* The rare folio on the deferred split list should
1657-
* be split now. It should not count as a failure.
1657+
* be split now. It should not count as a failure:
1658+
* but increment nr_failed because, without doing so,
1659+
* migrate_pages() may report success with (split but
1660+
* unmigrated) pages still on its fromlist; whereas it
1661+
* always reports success when its fromlist is empty.
1662+
*
16581663
* Only check it without removing it from the list.
16591664
* Since the folio can be on deferred_split_scan()
16601665
* local list and removing it can cause the local list
@@ -1669,6 +1674,7 @@ static int migrate_pages_batch(struct list_head *from,
16691674
if (nr_pages > 2 &&
16701675
!list_empty(&folio->_deferred_list)) {
16711676
if (try_split_folio(folio, split_folios) == 0) {
1677+
nr_failed++;
16721678
stats->nr_thp_split += is_thp;
16731679
stats->nr_split++;
16741680
continue;

0 commit comments

Comments
 (0)