Skip to content

Commit b5ff816

Browse files
Naoya Horiguchitorvalds
Naoya Horiguchi
authored andcommitted
mm: thp: introduce separate TTU flag for thp freezing
TTU_MIGRATION is used to convert pte into migration entry until thp split completes. This behavior conflicts with thp migration added later patches, so let's introduce a new TTU flag specifically for freezing. try_to_unmap() is used both for thp split (via freeze_page()) and page migration (via __unmap_and_move()). In freeze_page(), ttu_flag given for head page is like below (assuming anonymous thp): (TTU_IGNORE_MLOCK | TTU_IGNORE_ACCESS | TTU_RMAP_LOCKED | \ TTU_MIGRATION | TTU_SPLIT_HUGE_PMD) and ttu_flag given for tail pages is: (TTU_IGNORE_MLOCK | TTU_IGNORE_ACCESS | TTU_RMAP_LOCKED | \ TTU_MIGRATION) __unmap_and_move() calls try_to_unmap() with ttu_flag: (TTU_MIGRATION | TTU_IGNORE_MLOCK | TTU_IGNORE_ACCESS) Now I'm trying to insert a branch for thp migration at the top of try_to_unmap_one() like below static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma, unsigned long address, void *arg) { ... /* PMD-mapped THP migration entry */ if (!pvmw.pte && (flags & TTU_MIGRATION)) { if (!PageAnon(page)) continue; set_pmd_migration_entry(&pvmw, page); continue; } ... } so try_to_unmap() for tail pages called by thp split can go into thp migration code path (which converts *pmd* into migration entry), while the expectation is to freeze thp (which converts *pte* into migration entry.) I detected this failure as a "bad page state" error in a testcase where split_huge_page() is called from queue_pages_pte_range(). Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Naoya Horiguchi <[email protected]> Signed-off-by: Zi Yan <[email protected]> Acked-by: Kirill A. Shutemov <[email protected]> Cc: "H. Peter Anvin" <[email protected]> Cc: Anshuman Khandual <[email protected]> Cc: Dave Hansen <[email protected]> Cc: David Nellans <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Mel Gorman <[email protected]> Cc: Minchan Kim <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Vlastimil Babka <[email protected]> Cc: Andrea Arcangeli <[email protected]> Cc: Michal Hocko <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent eee4818 commit b5ff816

File tree

3 files changed

+7
-5
lines changed

3 files changed

+7
-5
lines changed

include/linux/rmap.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,9 @@ enum ttu_flags {
9393
TTU_BATCH_FLUSH = 0x40, /* Batch TLB flushes where possible
9494
* and caller guarantees they will
9595
* do a final flush if necessary */
96-
TTU_RMAP_LOCKED = 0x80 /* do not grab rmap lock:
96+
TTU_RMAP_LOCKED = 0x80, /* do not grab rmap lock:
9797
* caller holds it */
98+
TTU_SPLIT_FREEZE = 0x100, /* freeze pte under splitting thp */
9899
};
99100

100101
#ifdef CONFIG_MMU

mm/huge_memory.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2210,7 +2210,7 @@ static void freeze_page(struct page *page)
22102210
VM_BUG_ON_PAGE(!PageHead(page), page);
22112211

22122212
if (PageAnon(page))
2213-
ttu_flags |= TTU_MIGRATION;
2213+
ttu_flags |= TTU_SPLIT_FREEZE;
22142214

22152215
unmap_success = try_to_unmap(page, ttu_flags);
22162216
VM_BUG_ON_PAGE(!unmap_success, page);

mm/rmap.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,7 +1348,7 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
13481348

13491349
if (flags & TTU_SPLIT_HUGE_PMD) {
13501350
split_huge_pmd_address(vma, address,
1351-
flags & TTU_MIGRATION, page);
1351+
flags & TTU_SPLIT_FREEZE, page);
13521352
}
13531353

13541354
/*
@@ -1445,7 +1445,7 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
14451445
*/
14461446
dec_mm_counter(mm, mm_counter(page));
14471447
} else if (IS_ENABLED(CONFIG_MIGRATION) &&
1448-
(flags & TTU_MIGRATION)) {
1448+
(flags & (TTU_MIGRATION|TTU_SPLIT_FREEZE))) {
14491449
swp_entry_t entry;
14501450
pte_t swp_pte;
14511451
/*
@@ -1575,7 +1575,8 @@ bool try_to_unmap(struct page *page, enum ttu_flags flags)
15751575
* locking requirements of exec(), migration skips
15761576
* temporary VMAs until after exec() completes.
15771577
*/
1578-
if ((flags & TTU_MIGRATION) && !PageKsm(page) && PageAnon(page))
1578+
if ((flags & (TTU_MIGRATION|TTU_SPLIT_FREEZE))
1579+
&& !PageKsm(page) && PageAnon(page))
15791580
rwc.invalid_vma = invalid_migration_vma;
15801581

15811582
if (flags & TTU_RMAP_LOCKED)

0 commit comments

Comments
 (0)