mm/gup.c: use is_vm_hugetlb_page() to check whether to follow huge
[linux-2.6-microblaze.git] / mm / gup.c
index 8f236a3..6cb7180 100644 (file)
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -323,7 +323,7 @@ static struct page *follow_pmd_mask(struct vm_area_struct *vma,
        pmdval = READ_ONCE(*pmd);
        if (pmd_none(pmdval))
                return no_page_table(vma, flags);
-       if (pmd_huge(pmdval) && vma->vm_flags & VM_HUGETLB) {
+       if (pmd_huge(pmdval) && is_vm_hugetlb_page(vma)) {
                page = follow_huge_pmd(mm, address, pmd, flags);
                if (page)
                        return page;
@@ -433,7 +433,7 @@ static struct page *follow_pud_mask(struct vm_area_struct *vma,
        pud = pud_offset(p4dp, address);
        if (pud_none(*pud))
                return no_page_table(vma, flags);
-       if (pud_huge(*pud) && vma->vm_flags & VM_HUGETLB) {
+       if (pud_huge(*pud) && is_vm_hugetlb_page(vma)) {
                page = follow_huge_pud(mm, address, pud, flags);
                if (page)
                        return page;
@@ -734,11 +734,17 @@ static int check_vma_flags(struct vm_area_struct *vma, unsigned long gup_flags)
  *             Or NULL if the caller does not require them.
  * @nonblocking: whether waiting for disk IO or mmap_sem contention
  *
- * Returns number of pages pinned. This may be fewer than the number
- * requested. If nr_pages is 0 or negative, returns 0. If no pages
- * were pinned, returns -errno. Each page returned must be released
- * with a put_page() call when it is finished with. vmas will only
- * remain valid while mmap_sem is held.
+ * Returns either number of pages pinned (which may be less than the
+ * number requested), or an error. Details about the return value:
+ *
+ * -- If nr_pages is 0, returns 0.
+ * -- If nr_pages is >0, but no pages were pinned, returns -errno.
+ * -- If nr_pages is >0, and some pages were pinned, returns the number of
+ *    pages pinned. Again, this may be less than nr_pages.
+ *
+ * The caller is responsible for releasing returned @pages, via put_page().
+ *
+ * @vmas are valid only as long as mmap_sem is held.
  *
  * Must be called with mmap_sem held.  It may be released.  See below.
  *
@@ -1107,11 +1113,17 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk,
  *             subsequently whether VM_FAULT_RETRY functionality can be
  *             utilised. Lock must initially be held.
  *
- * Returns number of pages pinned. This may be fewer than the number
- * requested. If nr_pages is 0 or negative, returns 0. If no pages
- * were pinned, returns -errno. Each page returned must be released
- * with a put_page() call when it is finished with. vmas will only
- * remain valid while mmap_sem is held.
+ * Returns either number of pages pinned (which may be less than the
+ * number requested), or an error. Details about the return value:
+ *
+ * -- If nr_pages is 0, returns 0.
+ * -- If nr_pages is >0, but no pages were pinned, returns -errno.
+ * -- If nr_pages is >0, and some pages were pinned, returns the number of
+ *    pages pinned. Again, this may be less than nr_pages.
+ *
+ * The caller is responsible for releasing returned @pages, via put_page().
+ *
+ * @vmas are valid only as long as mmap_sem is held.
  *
  * Must be called with mmap_sem held for read or write.
  *
@@ -1443,6 +1455,7 @@ static long check_and_migrate_cma_pages(struct task_struct *tsk,
        bool drain_allow = true;
        bool migrate_allow = true;
        LIST_HEAD(cma_page_list);
+       long ret = nr_pages;
 
 check_again:
        for (i = 0; i < nr_pages;) {
@@ -1504,17 +1517,18 @@ check_again:
                 * again migrating any new CMA pages which we failed to isolate
                 * earlier.
                 */
-               nr_pages = __get_user_pages_locked(tsk, mm, start, nr_pages,
+               ret = __get_user_pages_locked(tsk, mm, start, nr_pages,
                                                   pages, vmas, NULL,
                                                   gup_flags);
 
-               if ((nr_pages > 0) && migrate_allow) {
+               if ((ret > 0) && migrate_allow) {
+                       nr_pages = ret;
                        drain_allow = true;
                        goto check_again;
                }
        }
 
-       return nr_pages;
+       return ret;
 }
 #else
 static long check_and_migrate_cma_pages(struct task_struct *tsk,
@@ -2223,7 +2237,7 @@ static int gup_pud_range(p4d_t p4d, unsigned long addr, unsigned long end,
                pud_t pud = READ_ONCE(*pudp);
 
                next = pud_addr_end(addr, end);
-               if (pud_none(pud))
+               if (unlikely(!pud_present(pud)))
                        return 0;
                if (unlikely(pud_huge(pud))) {
                        if (!gup_huge_pud(pud, pudp, addr, next, flags,