On Thu 27-10-16 10:51:40, Lorenzo Stoakes wrote: > This patch adds a int *locked parameter to get_user_pages_remote() to allow > VM_FAULT_RETRY faulting behaviour similar to get_user_pages_[un]locked(). > > Taking into account the previous adjustments to get_user_pages*() functions > allowing for the passing of gup_flags, we are now in a position where > __get_user_pages_unlocked() need only be exported for his ability to allow > VM_FAULT_RETRY behaviour, this adjustment allows us to subsequently unexport > __get_user_pages_unlocked() as well as allowing for future flexibility in the > use of get_user_pages_remote(). I would also add that this shouldn't introduce any functional change. > Signed-off-by: Lorenzo Stoakes <lstoakes@xxxxxxxxx> Acked-by: Michal Hocko <mhocko@xxxxxxxx> > --- > drivers/gpu/drm/etnaviv/etnaviv_gem.c | 2 +- > drivers/gpu/drm/i915/i915_gem_userptr.c | 2 +- > drivers/infiniband/core/umem_odp.c | 2 +- > fs/exec.c | 2 +- > include/linux/mm.h | 2 +- > kernel/events/uprobes.c | 4 ++-- > mm/gup.c | 12 ++++++++---- > mm/memory.c | 2 +- > security/tomoyo/domain.c | 2 +- > 9 files changed, 17 insertions(+), 13 deletions(-) > > diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c > index 0370b84..0c69a97f 100644 > --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c > +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c > @@ -763,7 +763,7 @@ static struct page **etnaviv_gem_userptr_do_get_pages( > down_read(&mm->mmap_sem); > while (pinned < npages) { > ret = get_user_pages_remote(task, mm, ptr, npages - pinned, > - flags, pvec + pinned, NULL); > + flags, pvec + pinned, NULL, NULL); > if (ret < 0) > break; > > diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c > index c6f780f..836b525 100644 > --- a/drivers/gpu/drm/i915/i915_gem_userptr.c > +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c > @@ -522,7 +522,7 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work) > obj->userptr.ptr + pinned * PAGE_SIZE, > npages - pinned, > flags, > - pvec + pinned, NULL); > + pvec + pinned, NULL, NULL); > if (ret < 0) > break; > > diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c > index 1f0fe32..6b079a3 100644 > --- a/drivers/infiniband/core/umem_odp.c > +++ b/drivers/infiniband/core/umem_odp.c > @@ -578,7 +578,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt, > */ > npages = get_user_pages_remote(owning_process, owning_mm, > user_virt, gup_num_pages, > - flags, local_page_list, NULL); > + flags, local_page_list, NULL, NULL); > up_read(&owning_mm->mmap_sem); > > if (npages < 0) > diff --git a/fs/exec.c b/fs/exec.c > index 4e497b9..2cf049d 100644 > --- a/fs/exec.c > +++ b/fs/exec.c > @@ -209,7 +209,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, > * doing the exec and bprm->mm is the new process's mm. > */ > ret = get_user_pages_remote(current, bprm->mm, pos, 1, gup_flags, > - &page, NULL); > + &page, NULL, NULL); > if (ret <= 0) > return NULL; > > diff --git a/include/linux/mm.h b/include/linux/mm.h > index a92c8d7..cc15445 100644 > --- a/include/linux/mm.h > +++ b/include/linux/mm.h > @@ -1274,7 +1274,7 @@ extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, > long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, > unsigned long start, unsigned long nr_pages, > unsigned int gup_flags, struct page **pages, > - struct vm_area_struct **vmas); > + struct vm_area_struct **vmas, int *locked); > long get_user_pages(unsigned long start, unsigned long nr_pages, > unsigned int gup_flags, struct page **pages, > struct vm_area_struct **vmas); > diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c > index f9ec9ad..215871b 100644 > --- a/kernel/events/uprobes.c > +++ b/kernel/events/uprobes.c > @@ -301,7 +301,7 @@ int uprobe_write_opcode(struct mm_struct *mm, unsigned long vaddr, > retry: > /* Read the page with vaddr into memory */ > ret = get_user_pages_remote(NULL, mm, vaddr, 1, FOLL_FORCE, &old_page, > - &vma); > + &vma, NULL); > if (ret <= 0) > return ret; > > @@ -1712,7 +1712,7 @@ static int is_trap_at_addr(struct mm_struct *mm, unsigned long vaddr) > * essentially a kernel access to the memory. > */ > result = get_user_pages_remote(NULL, mm, vaddr, 1, FOLL_FORCE, &page, > - NULL); > + NULL, NULL); > if (result < 0) > return result; > > diff --git a/mm/gup.c b/mm/gup.c > index ec4f827..0567851 100644 > --- a/mm/gup.c > +++ b/mm/gup.c > @@ -920,6 +920,9 @@ EXPORT_SYMBOL(get_user_pages_unlocked); > * only intends to ensure the pages are faulted in. > * @vmas: array of pointers to vmas corresponding to each page. > * Or NULL if the caller does not require them. > + * @locked: pointer to lock flag indicating whether lock is held and > + * 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 > @@ -963,10 +966,10 @@ EXPORT_SYMBOL(get_user_pages_unlocked); > long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, > unsigned long start, unsigned long nr_pages, > unsigned int gup_flags, struct page **pages, > - struct vm_area_struct **vmas) > + struct vm_area_struct **vmas, int *locked) > { > return __get_user_pages_locked(tsk, mm, start, nr_pages, pages, vmas, > - NULL, false, > + locked, true, > gup_flags | FOLL_TOUCH | FOLL_REMOTE); > } > EXPORT_SYMBOL(get_user_pages_remote); > @@ -974,8 +977,9 @@ EXPORT_SYMBOL(get_user_pages_remote); > /* > * This is the same as get_user_pages_remote(), just with a > * less-flexible calling convention where we assume that the task > - * and mm being operated on are the current task's. We also > - * obviously don't pass FOLL_REMOTE in here. > + * and mm being operated on are the current task's and don't allow > + * passing of a locked parameter. We also obviously don't pass > + * FOLL_REMOTE in here. > */ > long get_user_pages(unsigned long start, unsigned long nr_pages, > unsigned int gup_flags, struct page **pages, > diff --git a/mm/memory.c b/mm/memory.c > index e18c57b..2f3949b 100644 > --- a/mm/memory.c > +++ b/mm/memory.c > @@ -3883,7 +3883,7 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, > struct page *page = NULL; > > ret = get_user_pages_remote(tsk, mm, addr, 1, > - gup_flags, &page, &vma); > + gup_flags, &page, &vma, NULL); > if (ret <= 0) { > #ifndef CONFIG_HAVE_IOREMAP_PROT > break; > diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c > index 682b73a..838ffa7 100644 > --- a/security/tomoyo/domain.c > +++ b/security/tomoyo/domain.c > @@ -881,7 +881,7 @@ bool tomoyo_dump_page(struct linux_binprm *bprm, unsigned long pos, > * the execve(). > */ > if (get_user_pages_remote(current, bprm->mm, pos, 1, > - FOLL_FORCE, &page, NULL) <= 0) > + FOLL_FORCE, &page, NULL, NULL) <= 0) > return false; > #else > page = bprm->page[pos / PAGE_SIZE]; > -- > 2.10.1 -- Michal Hocko SUSE Labs -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html