OSDN Git Service

mm/hugetlb: take page table lock in follow_huge_pmd()
[android-x86/kernel.git] / mm / gup.c
index 12bc2bc..1a8ab05 100644 (file)
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -167,10 +167,10 @@ struct page *follow_page_mask(struct vm_area_struct *vma,
        if (pud_none(*pud))
                return no_page_table(vma, flags);
        if (pud_huge(*pud) && vma->vm_flags & VM_HUGETLB) {
-               if (flags & FOLL_GET)
-                       return NULL;
-               page = follow_huge_pud(mm, address, pud, flags & FOLL_WRITE);
-               return page;
+               page = follow_huge_pud(mm, address, pud, flags);
+               if (page)
+                       return page;
+               return no_page_table(vma, flags);
        }
        if (unlikely(pud_bad(*pud)))
                return no_page_table(vma, flags);
@@ -179,19 +179,10 @@ struct page *follow_page_mask(struct vm_area_struct *vma,
        if (pmd_none(*pmd))
                return no_page_table(vma, flags);
        if (pmd_huge(*pmd) && vma->vm_flags & VM_HUGETLB) {
-               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;
-               }
-               return page;
+               page = follow_huge_pmd(mm, address, pmd, flags);
+               if (page)
+                       return page;
+               return no_page_table(vma, flags);
        }
        if ((flags & FOLL_NUMA) && pmd_numa(*pmd))
                return no_page_table(vma, flags);