Subject: pmd_trans_huge migrate bugcheck From: Andrea Arcangeli No pmd_trans_huge should ever materialize in migration ptes areas, because we split the hugepage before migration ptes are instantiated. Signed-off-by: Andrea Arcangeli Acked-by: Rik van Riel --- diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h @@ -107,6 +107,10 @@ static inline int PageTransHuge(struct p VM_BUG_ON(PageTail(page)); return PageHead(page); } +static inline int PageTransCompound(struct page *page) +{ + return PageCompound(page); +} #else /* CONFIG_TRANSPARENT_HUGEPAGE */ #define transparent_hugepage_enabled(__vma) 0 #define transparent_hugepage_defrag(__vma) 0 @@ -124,6 +128,7 @@ static inline int split_huge_page(struct #define wait_split_huge_page(__anon_vma, __pmd) \ do { } while (0) #define PageTransHuge(page) 0 +#define PageTransCompound(page) 0 static inline int hugepage_madvise(unsigned long *vm_flags) { BUG_ON(0); diff --git a/mm/migrate.c b/mm/migrate.c --- a/mm/migrate.c +++ b/mm/migrate.c @@ -99,6 +99,7 @@ static int remove_migration_pte(struct p goto out; pmd = pmd_offset(pud, addr); + VM_BUG_ON(pmd_trans_huge(*pmd)); if (!pmd_present(*pmd)) goto out; @@ -819,6 +820,10 @@ static int do_move_page_to_node_array(st if (PageReserved(page) || PageKsm(page)) goto put_and_set; + if (unlikely(PageTransCompound(page))) + if (unlikely(split_huge_page(page))) + goto put_and_set; + pp->page = page; err = page_to_nid(page);