With new refcounting VMAs can start or end in the middle of huge page. We need to modify code to call split_huge_page() properly. Signed-off-by: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx> --- mm/migrate.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/mm/migrate.c b/mm/migrate.c index f1a12ced2531..4dc941100388 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -1235,7 +1235,7 @@ static int do_move_page_to_node_array(struct mm_struct *mm, vma = find_vma(mm, pp->addr); if (!vma || pp->addr < vma->vm_start || !vma_migratable(vma)) goto set_status; - +retry: page = follow_page(vma, pp->addr, FOLL_GET); err = PTR_ERR(page); @@ -1246,9 +1246,27 @@ static int do_move_page_to_node_array(struct mm_struct *mm, if (!page) goto set_status; - if (PageTransHuge(page) && split_huge_page(page)) { - err = -EBUSY; - goto set_status; + if (PageTransCompound(page)) { + struct page *head_page = compound_head(page); + + /* + * split_huge_page() wants pin to be only on head page + */ + if (page != head_page) { + get_page(head_page); + put_page(page); + } + + err = split_huge_page(head_page); + if (err) { + put_page(head_page); + goto set_status; + } + + if (page != head_page) { + put_page(head_page); + goto retry; + } } /* Use PageReserved to check for zero page */ -- 2.1.1 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>