Skip to content

Commit 829ae0f

Browse files
Gavin Shanakpm00
authored andcommitted
mm: migrate: fix THP's mapcount on isolation
The issue is reported when removing memory through virtio_mem device. The transparent huge page, experienced copy-on-write fault, is wrongly regarded as pinned. The transparent huge page is escaped from being isolated in isolate_migratepages_block(). The transparent huge page can't be migrated and the corresponding memory block can't be put into offline state. Fix it by replacing page_mapcount() with total_mapcount(). With this, the transparent huge page can be isolated and migrated, and the memory block can be put into offline state. Besides, The page's refcount is increased a bit earlier to avoid the page is released when the check is executed. Link: https://lkml.kernel.org/r/[email protected] Fixes: 1da2f32 ("mm,thp,compaction,cma: allow THP migration for CMA allocations") Signed-off-by: Gavin Shan <[email protected]> Reported-by: Zhenyu Zhang <[email protected]> Tested-by: Zhenyu Zhang <[email protected]> Suggested-by: David Hildenbrand <[email protected]> Acked-by: David Hildenbrand <[email protected]> Cc: Alistair Popple <[email protected]> Cc: Hugh Dickins <[email protected]> Cc: Kirill A. Shutemov <[email protected]> Cc: Matthew Wilcox <[email protected]> Cc: William Kucharski <[email protected]> Cc: Zi Yan <[email protected]> Cc: <[email protected]> [5.7+] Signed-off-by: Andrew Morton <[email protected]>
1 parent 4aaf269 commit 829ae0f

File tree

1 file changed

+11
-11
lines changed

1 file changed

+11
-11
lines changed

mm/compaction.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -984,29 +984,29 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
984984
goto isolate_fail;
985985
}
986986

987+
/*
988+
* Be careful not to clear PageLRU until after we're
989+
* sure the page is not being freed elsewhere -- the
990+
* page release code relies on it.
991+
*/
992+
if (unlikely(!get_page_unless_zero(page)))
993+
goto isolate_fail;
994+
987995
/*
988996
* Migration will fail if an anonymous page is pinned in memory,
989997
* so avoid taking lru_lock and isolating it unnecessarily in an
990998
* admittedly racy check.
991999
*/
9921000
mapping = page_mapping(page);
993-
if (!mapping && page_count(page) > page_mapcount(page))
994-
goto isolate_fail;
1001+
if (!mapping && (page_count(page) - 1) > total_mapcount(page))
1002+
goto isolate_fail_put;
9951003

9961004
/*
9971005
* Only allow to migrate anonymous pages in GFP_NOFS context
9981006
* because those do not depend on fs locks.
9991007
*/
10001008
if (!(cc->gfp_mask & __GFP_FS) && mapping)
1001-
goto isolate_fail;
1002-
1003-
/*
1004-
* Be careful not to clear PageLRU until after we're
1005-
* sure the page is not being freed elsewhere -- the
1006-
* page release code relies on it.
1007-
*/
1008-
if (unlikely(!get_page_unless_zero(page)))
1009-
goto isolate_fail;
1009+
goto isolate_fail_put;
10101010

10111011
/* Only take pages on LRU: a check now makes later tests safe */
10121012
if (!PageLRU(page))

0 commit comments

Comments
 (0)