The patch titled Subject: mm-gup-replace-get_user_pages_longterm-with-foll_longterm-v3 has been added to the -mm tree. Its filename is mm-gup-replace-get_user_pages_longterm-with-foll_longterm-v3.patch This patch should soon appear at http://ozlabs.org/~akpm/mmots/broken-out/mm-gup-replace-get_user_pages_longterm-with-foll_longterm-v3.patch and later at http://ozlabs.org/~akpm/mmotm/broken-out/mm-gup-replace-get_user_pages_longterm-with-foll_longterm-v3.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: Ira Weiny <ira.weiny@xxxxxxxxx> Subject: mm-gup-replace-get_user_pages_longterm-with-foll_longterm-v3 Changes from V2: Enhance commit message Add discussion from Christoph Lameter Fix comments fix typo 's/uer/user' Move FOLL_LONGTERM documentation next to FOLL_LONGTERM definition Enhance FOLL_LONGTERM documentation remove __always_inline from __gup_longterm_locked() Disallow FOLL_LONGTERM in calls which are incompatible Changes from V1: Rebased on 5.1 merge Adjusted for changes introduced by CONFIG_CMA This included changing check_and_migrate_cma_pages to do the right thing Convert a new users of GUP longterm io_uring.c xdp_umem.c Link: http://lkml.kernel.org/r/20190328084422.29911-2-ira.weiny@xxxxxxxxx Signed-off-by: Ira Weiny <ira.weiny@xxxxxxxxx> Cc: Aneesh Kumar K.V <aneesh.kumar@xxxxxxxxxxxxx> Cc: Benjamin Herrenschmidt <benh@xxxxxxxxxxxxxxxxxxx> Cc: Borislav Petkov <bp@xxxxxxxxx> Cc: Dan Williams <dan.j.williams@xxxxxxxxx> Cc: "David S. Miller" <davem@xxxxxxxxxxxxx> Cc: Heiko Carstens <heiko.carstens@xxxxxxxxxx> Cc: Ingo Molnar <mingo@xxxxxxxxxx> Cc: James Hogan <jhogan@xxxxxxxxxx> Cc: Jason Gunthorpe <jgg@xxxxxxxx> Cc: John Hubbard <jhubbard@xxxxxxxxxx> Cc: "Kirill A. Shutemov" <kirill.shutemov@xxxxxxxxxxxxxxx> Cc: Martin Schwidefsky <schwidefsky@xxxxxxxxxx> Cc: Michal Hocko <mhocko@xxxxxxxxxx> Cc: Mike Marshall <hubcap@xxxxxxxxxxxx> Cc: Paul Mackerras <paulus@xxxxxxxxx> Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx> Cc: Ralf Baechle <ralf@xxxxxxxxxxxxxx> Cc: Rich Felker <dalias@xxxxxxxx> Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Cc: Yoshinori Sato <ysato@xxxxxxxxxxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- include/linux/mm.h | 29 ++++++++++++++++++++- mm/gup.c | 59 ++++++++++++++++++++++++++----------------- 2 files changed, 64 insertions(+), 24 deletions(-) --- a/include/linux/mm.h~mm-gup-replace-get_user_pages_longterm-with-foll_longterm-v3 +++ a/include/linux/mm.h @@ -2557,7 +2557,34 @@ struct page *follow_page(struct vm_area_ #define FOLL_REMOTE 0x2000 /* we are working on non-current tsk/mm */ #define FOLL_COW 0x4000 /* internal GUP flag */ #define FOLL_ANON 0x8000 /* don't do file mappings */ -#define FOLL_LONGTERM 0x10000 /* mapping is intended for a long term pin */ +#define FOLL_LONGTERM 0x10000 /* mapping lifetime is indefinite: see below */ + +/* + * NOTE on FOLL_LONGTERM: + * + * FOLL_LONGTERM indicates that the page will be held for an indefinite time + * period _often_ under userspace control. This is contrasted with + * iov_iter_get_pages() where usages which are transient. + * + * FIXME: For pages which are part of a filesystem, mappings are subject to the + * lifetime enforced by the filesystem and we need guarantees that longterm + * users like RDMA and V4L2 only establish mappings which coordinate usage with + * the filesystem. Ideas for this coordination include revoking the longterm + * pin, delaying writeback, bounce buffer page writeback, etc. As FS DAX was + * added after the problem with filesystems was found FS DAX VMAs are + * specifically failed. Filesystem pages are still subject to bugs and use of + * FOLL_LONGTERM should be avoided on those pages. + * + * FIXME: Also NOTE that FOLL_LONGTERM is not supported in every GUP call. + * Currently only get_user_pages() and get_user_pages_fast() support this flag + * and calls to get_user_pages_[un]locked are specifically not allowed. This + * is due to an incompatibility with the FS DAX check and + * FAULT_FLAG_ALLOW_RETRY + * + * In the CMA case: longterm pins in a CMA region would unnecessarily fragment + * that region. And so CMA attempts to migrate the page before pinning when + * FOLL_LONGTERM is specified. + */ static inline int vm_fault_to_errno(vm_fault_t vm_fault, int foll_flags) { --- a/mm/gup.c~mm-gup-replace-get_user_pages_longterm-with-foll_longterm-v3 +++ a/mm/gup.c @@ -1008,6 +1008,15 @@ long get_user_pages_locked(unsigned long unsigned int gup_flags, struct page **pages, int *locked) { + /* + * FIXME: Current FOLL_LONGTERM behavior is incompatible with + * FAULT_FLAG_ALLOW_RETRY because of the FS DAX check requirement on + * vmas. As there are no users of this flag in this call we simply + * disallow this option for now. + */ + if (WARN_ON_ONCE(gup_flags & FOLL_LONGTERM)) + return -EINVAL; + return __get_user_pages_locked(current, current->mm, start, nr_pages, pages, NULL, locked, gup_flags | FOLL_TOUCH); @@ -1036,6 +1045,15 @@ long get_user_pages_unlocked(unsigned lo int locked = 1; long ret; + /* + * FIXME: Current FOLL_LONGTERM behavior is incompatible with + * FAULT_FLAG_ALLOW_RETRY because of the FS DAX check requirement on + * vmas. As there are no users of this flag in this call we simply + * disallow this option for now. + */ + if (WARN_ON_ONCE(gup_flags & FOLL_LONGTERM)) + return -EINVAL; + down_read(&mm->mmap_sem); ret = __get_user_pages_locked(current, mm, start, nr_pages, pages, NULL, &locked, gup_flags | FOLL_TOUCH); @@ -1106,6 +1124,15 @@ long get_user_pages_remote(struct task_s unsigned int gup_flags, struct page **pages, struct vm_area_struct **vmas, int *locked) { + /* + * FIXME: Current FOLL_LONGTERM behavior is incompatible with + * FAULT_FLAG_ALLOW_RETRY because of the FS DAX check requirement on + * vmas. As there are no users of this flag in this call we simply + * disallow this option for now. + */ + if (WARN_ON_ONCE(gup_flags & FOLL_LONGTERM)) + return -EINVAL; + return __get_user_pages_locked(tsk, mm, start, nr_pages, pages, vmas, locked, gup_flags | FOLL_TOUCH | FOLL_REMOTE); @@ -1276,30 +1303,16 @@ static long check_and_migrate_cma_pages( #endif /* - * __gup_longterm_locked() is a wrapper for __get_uer_pages_locked which - * allows us to process the FOLL_LONGTERM flag if present. - * - * FOLL_LONGTERM Checks for either DAX VMAs or PPC CMA regions and either fails - * the pin or attempts to migrate the page as appropriate. - * - * In the filesystem-dax case mappings are subject to the lifetime enforced by - * the filesystem and we need guarantees that longterm users like RDMA and V4L2 - * only establish mappings that have a kernel enforced revocation mechanism. - * - * In the CMA case pages can't be pinned in a CMA region as this would - * unnecessarily fragment that region. So CMA attempts to migrate the page - * before pinning. - * - * "longterm" == userspace controlled elevated page count lifetime. - * Contrast this to iov_iter_get_pages() usages which are transient. + * __gup_longterm_locked() is a wrapper for __get_user_pages_locked which + * allows us to process the FOLL_LONGTERM flag. */ -static __always_inline long __gup_longterm_locked(struct task_struct *tsk, - struct mm_struct *mm, - unsigned long start, - unsigned long nr_pages, - struct page **pages, - struct vm_area_struct **vmas, - unsigned int gup_flags) +static long __gup_longterm_locked(struct task_struct *tsk, + struct mm_struct *mm, + unsigned long start, + unsigned long nr_pages, + struct page **pages, + struct vm_area_struct **vmas, + unsigned int gup_flags) { struct vm_area_struct **vmas_tmp = vmas; unsigned long flags = 0; _ Patches currently in -mm which might be from ira.weiny@xxxxxxxxx are mm-gup-replace-get_user_pages_longterm-with-foll_longterm.patch mm-gup-replace-get_user_pages_longterm-with-foll_longterm-v3.patch mm-gup-change-write-parameter-to-flags-in-fast-walk.patch mm-gup-change-gup-fast-to-use-flags-rather-than-a-write-bool.patch mm-gup-add-foll_longterm-capability-to-gup-fast.patch mm-gup-add-foll_longterm-capability-to-gup-fast-v3.patch ib-hfi1-use-the-new-foll_longterm-flag-to-get_user_pages_fast.patch ib-hfi1-use-the-new-foll_longterm-flag-to-get_user_pages_fast-v3.patch ib-qib-use-the-new-foll_longterm-flag-to-get_user_pages_fast.patch ib-mthca-use-the-new-foll_longterm-flag-to-get_user_pages_fast.patch