The patch titled Subject: mm/gup: allow VM_FAULT_RETRY for multiple times has been added to the -mm tree. Its filename is mm-gup-allow-vm_fault_retry-for-multiple-times.patch This patch should soon appear at http://ozlabs.org/~akpm/mmots/broken-out/mm-gup-allow-vm_fault_retry-for-multiple-times.patch and later at http://ozlabs.org/~akpm/mmotm/broken-out/mm-gup-allow-vm_fault_retry-for-multiple-times.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next and is updated there every 3-4 working days ------------------------------------------------------ From: Peter Xu <peterx@xxxxxxxxxx> Subject: mm/gup: allow VM_FAULT_RETRY for multiple times This is the gup counterpart of the change that allows the VM_FAULT_RETRY to happen for more than once. One thing to mention is that we must check the fatal signal here before retry because the GUP can be interrupted by that, otherwise we can loop forever. Link: http://lkml.kernel.org/r/20200220195357.16371-1-peterx@xxxxxxxxxx Signed-off-by: Peter Xu <peterx@xxxxxxxxxx> Cc: Andrea Arcangeli <aarcange@xxxxxxxxxx> Cc: Bobby Powers <bobbypowers@xxxxxxxxx> Cc: Brian Geffon <bgeffon@xxxxxxxxxx> Cc: David Hildenbrand <david@xxxxxxxxxx> Cc: Denis Plotnikov <dplotnikov@xxxxxxxxxxxxx> Cc: "Dr . David Alan Gilbert" <dgilbert@xxxxxxxxxx> Cc: Hugh Dickins <hughd@xxxxxxxxxx> Cc: Jerome Glisse <jglisse@xxxxxxxxxx> Cc: Johannes Weiner <hannes@xxxxxxxxxxx> Cc: "Kirill A . Shutemov" <kirill@xxxxxxxxxxxxx> Cc: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> Cc: Martin Cracauer <cracauer@xxxxxxxx> Cc: Marty McFadden <mcfadden8@xxxxxxxx> Cc: Matthew Wilcox <willy@xxxxxxxxxxxxx> Cc: Maya Gokhale <gokhale2@xxxxxxxx> Cc: Mel Gorman <mgorman@xxxxxxx> Cc: Mike Kravetz <mike.kravetz@xxxxxxxxxx> Cc: Mike Rapoport <rppt@xxxxxxxxxxxxxxxxxx> Cc: Pavel Emelyanov <xemul@xxxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- mm/gup.c | 27 +++++++++++++++++++++------ mm/hugetlb.c | 6 ++++-- 2 files changed, 25 insertions(+), 8 deletions(-) --- a/mm/gup.c~mm-gup-allow-vm_fault_retry-for-multiple-times +++ a/mm/gup.c @@ -861,7 +861,10 @@ static int faultin_page(struct task_stru if (*flags & FOLL_NOWAIT) fault_flags |= FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_RETRY_NOWAIT; if (*flags & FOLL_TRIED) { - VM_WARN_ON_ONCE(fault_flags & FAULT_FLAG_ALLOW_RETRY); + /* + * Note: FAULT_FLAG_ALLOW_RETRY and FAULT_FLAG_TRIED + * can co-exist + */ fault_flags |= FAULT_FLAG_TRIED; } @@ -1221,7 +1224,6 @@ retry: down_read(&mm->mmap_sem); if (!(fault_flags & FAULT_FLAG_TRIED)) { *unlocked = true; - fault_flags &= ~FAULT_FLAG_ALLOW_RETRY; fault_flags |= FAULT_FLAG_TRIED; goto retry; } @@ -1305,17 +1307,30 @@ static __always_inline long __get_user_p if (likely(pages)) pages += ret; start += ret << PAGE_SHIFT; + lock_dropped = true; +retry: /* * Repeat on the address that fired VM_FAULT_RETRY - * without FAULT_FLAG_ALLOW_RETRY but with - * FAULT_FLAG_TRIED. + * with both FAULT_FLAG_ALLOW_RETRY and + * FAULT_FLAG_TRIED. Note that GUP can be interrupted + * by fatal signals, so we need to check it before we + * start trying again otherwise it can loop forever. */ + + if (fatal_signal_pending(current)) + break; + *locked = 1; - lock_dropped = true; down_read(&mm->mmap_sem); + ret = __get_user_pages(tsk, mm, start, 1, flags | FOLL_TRIED, - pages, NULL, NULL); + pages, NULL, locked); + if (!*locked) { + /* Continue to retry until we succeeded */ + BUG_ON(ret != 0); + goto retry; + } if (ret != 1) { BUG_ON(ret > 1); if (!pages_done) --- a/mm/hugetlb.c~mm-gup-allow-vm_fault_retry-for-multiple-times +++ a/mm/hugetlb.c @@ -4349,8 +4349,10 @@ long follow_hugetlb_page(struct mm_struc fault_flags |= FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_RETRY_NOWAIT; if (flags & FOLL_TRIED) { - VM_WARN_ON_ONCE(fault_flags & - FAULT_FLAG_ALLOW_RETRY); + /* + * Note: FAULT_FLAG_ALLOW_RETRY and + * FAULT_FLAG_TRIED can co-exist + */ fault_flags |= FAULT_FLAG_TRIED; } ret = hugetlb_fault(mm, vma, vaddr, fault_flags); _ Patches currently in -mm which might be from peterx@xxxxxxxxxx are mm-gup-rename-nonblocking-to-locked-where-proper.patch mm-gup-fix-__get_user_pages-on-fault-retry-of-hugetlb.patch mm-introduce-fault_signal_pending.patch x86-mm-use-helper-fault_signal_pending.patch arc-mm-use-helper-fault_signal_pending.patch arm64-mm-use-helper-fault_signal_pending.patch powerpc-mm-use-helper-fault_signal_pending.patch sh-mm-use-helper-fault_signal_pending.patch mm-return-faster-for-non-fatal-signals-in-user-mode-faults.patch userfaultfd-dont-retake-mmap_sem-to-emulate-nopage.patch mm-introduce-fault_flag_default.patch mm-introduce-fault_flag_interruptible.patch mm-allow-vm_fault_retry-for-multiple-times.patch mm-gup-allow-vm_fault_retry-for-multiple-times.patch mm-gup-allow-to-react-to-fatal-signals.patch mm-userfaultfd-honor-fault_flag_killable-in-fault-path.patch mm-merge-parameters-for-change_protection.patch userfaultfd-wp-apply-_page_uffd_wp-bit.patch userfaultfd-wp-drop-_page_uffd_wp-properly-when-fork.patch userfaultfd-wp-add-pmd_swp_uffd_wp-helpers.patch userfaultfd-wp-support-swap-and-page-migration.patch khugepaged-skip-collapse-if-uffd-wp-detected.patch userfaultfd-wp-dont-wake-up-when-doing-write-protect.patch userfaultfd-wp-declare-_uffdio_writeprotect-conditionally.patch userfaultfd-selftests-refactor-statistics.patch userfaultfd-selftests-add-write-protect-test.patch