mm: migrate: add hugepage migration code to move_pages()
[platform/adaptation/renesas_rcar/renesas_kernel.git] / mm / memory.c
index c1c6d59..2b73dbd 100644 (file)
@@ -1481,7 +1481,8 @@ struct page *follow_page_mask(struct vm_area_struct *vma,
        if (pud_none(*pud))
                goto no_page_table;
        if (pud_huge(*pud) && vma->vm_flags & VM_HUGETLB) {
-               BUG_ON(flags & FOLL_GET);
+               if (flags & FOLL_GET)
+                       goto out;
                page = follow_huge_pud(mm, address, pud, flags & FOLL_WRITE);
                goto out;
        }
@@ -1492,8 +1493,20 @@ struct page *follow_page_mask(struct vm_area_struct *vma,
        if (pmd_none(*pmd))
                goto no_page_table;
        if (pmd_huge(*pmd) && vma->vm_flags & VM_HUGETLB) {
-               BUG_ON(flags & FOLL_GET);
                page = follow_huge_pmd(mm, address, pmd, flags & FOLL_WRITE);
+               if (flags & FOLL_GET) {
+                       /*
+                        * Refcount on tail pages are not well-defined and
+                        * shouldn't be taken. The caller should handle a NULL
+                        * return when trying to follow tail pages.
+                        */
+                       if (PageHead(page))
+                               get_page(page);
+                       else {
+                               page = NULL;
+                               goto out;
+                       }
+               }
                goto out;
        }
        if ((flags & FOLL_NUMA) && pmd_numa(*pmd))