Re: [RESEND 3/7] mm/gup: Change GUP fast to use flags rather than a write 'bool'

2019-03-25 Thread Ira Weiny
On Fri, Mar 22, 2019 at 03:05:53PM -0700, Dan Williams wrote:
> On Sun, Mar 17, 2019 at 7:36 PM  wrote:
> >
> > From: Ira Weiny 
> >
> > To facilitate additional options to get_user_pages_fast() change the
> > singular write parameter to be gup_flags.
> >
> > This patch does not change any functionality.  New functionality will
> > follow in subsequent patches.
> >
> > Some of the get_user_pages_fast() call sites were unchanged because they
> > already passed FOLL_WRITE or 0 for the write parameter.
> >
> > Signed-off-by: Ira Weiny 
> >
> > ---
> > Changes from V1:
> > Rebase to current merge tree
> > arch/powerpc/mm/mmu_context_iommu.c no longer calls gup_fast
> > The gup_longterm was converted in patch 1
> >
> >  arch/mips/mm/gup.c | 11 ++-
> >  arch/powerpc/kvm/book3s_64_mmu_hv.c|  4 ++--
> >  arch/powerpc/kvm/e500_mmu.c|  2 +-
> >  arch/s390/kvm/interrupt.c  |  2 +-
> >  arch/s390/mm/gup.c | 12 ++--
> >  arch/sh/mm/gup.c   | 11 ++-
> >  arch/sparc/mm/gup.c|  9 +
> >  arch/x86/kvm/paging_tmpl.h |  2 +-
> >  arch/x86/kvm/svm.c |  2 +-
> >  drivers/fpga/dfl-afu-dma-region.c  |  2 +-
> >  drivers/gpu/drm/via/via_dmablit.c  |  3 ++-
> >  drivers/infiniband/hw/hfi1/user_pages.c|  3 ++-
> >  drivers/misc/genwqe/card_utils.c   |  2 +-
> >  drivers/misc/vmw_vmci/vmci_host.c  |  2 +-
> >  drivers/misc/vmw_vmci/vmci_queue_pair.c|  6 --
> >  drivers/platform/goldfish/goldfish_pipe.c  |  3 ++-
> >  drivers/rapidio/devices/rio_mport_cdev.c   |  4 +++-
> >  drivers/sbus/char/oradax.c |  2 +-
> >  drivers/scsi/st.c  |  3 ++-
> >  drivers/staging/gasket/gasket_page_table.c |  4 ++--
> >  drivers/tee/tee_shm.c  |  2 +-
> >  drivers/vfio/vfio_iommu_spapr_tce.c|  3 ++-
> >  drivers/vhost/vhost.c  |  2 +-
> >  drivers/video/fbdev/pvr2fb.c   |  2 +-
> >  drivers/virt/fsl_hypervisor.c  |  2 +-
> >  drivers/xen/gntdev.c   |  2 +-
> >  fs/orangefs/orangefs-bufmap.c  |  2 +-
> >  include/linux/mm.h |  4 ++--
> >  kernel/futex.c |  2 +-
> >  lib/iov_iter.c |  7 +--
> >  mm/gup.c   | 10 +-
> >  mm/util.c  |  8 
> >  net/ceph/pagevec.c |  2 +-
> >  net/rds/info.c |  2 +-
> >  net/rds/rdma.c |  3 ++-
> >  35 files changed, 79 insertions(+), 63 deletions(-)
> 
> 
> >
> > diff --git a/arch/mips/mm/gup.c b/arch/mips/mm/gup.c
> > index 0d14e0d8eacf..4c2b4483683c 100644
> > --- a/arch/mips/mm/gup.c
> > +++ b/arch/mips/mm/gup.c
> > @@ -235,7 +235,7 @@ int __get_user_pages_fast(unsigned long start, int 
> > nr_pages, int write,
> >   * get_user_pages_fast() - pin user pages in memory
> >   * @start: starting user address
> >   * @nr_pages:  number of pages from start to pin
> > - * @write: whether pages will be written to
> > + * @gup_flags: flags modifying pin behaviour
> >   * @pages: array that receives pointers to the pages pinned.
> >   * Should be at least nr_pages long.
> >   *
> > @@ -247,8 +247,8 @@ int __get_user_pages_fast(unsigned long start, int 
> > nr_pages, int write,
> >   * requested. If nr_pages is 0 or negative, returns 0. If no pages
> >   * were pinned, returns -errno.
> >   */
> > -int get_user_pages_fast(unsigned long start, int nr_pages, int write,
> > -   struct page **pages)
> > +int get_user_pages_fast(unsigned long start, int nr_pages,
> > +   unsigned int gup_flags, struct page **pages)
> 
> This looks a tad scary given all related thrash especially when it's
> only 1 user that wants to do get_user_page_fast_longterm, right?

Agreed but the discussion back in Feb agreed that it would be better to make
get_user_pages_fast() use flags rather than add another *_longterm call, and I
agree.

> Maybe
> something like the following. Note I explicitly moved the flags to the
> end so that someone half paying attention that calls
> __get_user_pages_fast will get a compile error if they specify the
> args in the same order.

I did this to remain consistent with the other public calls.  They put the
"return" pages parameter at the end.  For example get_user_pages() is defined
this way with pages and vmas at the end.

long get_user_pages(unsigned long start, unsigned long nr_pages,
unsigned int gup_flags, struct page **pages,
struct vm_area_struct **vmas)

I'm pretty sure I got all the callers.  Is this worth making the signature
"non-standard" WRT the other calls?


Re: [RESEND 3/7] mm/gup: Change GUP fast to use flags rather than a write 'bool'

2019-03-22 Thread Dan Williams
On Sun, Mar 17, 2019 at 7:36 PM  wrote:
>
> From: Ira Weiny 
>
> To facilitate additional options to get_user_pages_fast() change the
> singular write parameter to be gup_flags.
>
> This patch does not change any functionality.  New functionality will
> follow in subsequent patches.
>
> Some of the get_user_pages_fast() call sites were unchanged because they
> already passed FOLL_WRITE or 0 for the write parameter.
>
> Signed-off-by: Ira Weiny 
>
> ---
> Changes from V1:
> Rebase to current merge tree
> arch/powerpc/mm/mmu_context_iommu.c no longer calls gup_fast
> The gup_longterm was converted in patch 1
>
>  arch/mips/mm/gup.c | 11 ++-
>  arch/powerpc/kvm/book3s_64_mmu_hv.c|  4 ++--
>  arch/powerpc/kvm/e500_mmu.c|  2 +-
>  arch/s390/kvm/interrupt.c  |  2 +-
>  arch/s390/mm/gup.c | 12 ++--
>  arch/sh/mm/gup.c   | 11 ++-
>  arch/sparc/mm/gup.c|  9 +
>  arch/x86/kvm/paging_tmpl.h |  2 +-
>  arch/x86/kvm/svm.c |  2 +-
>  drivers/fpga/dfl-afu-dma-region.c  |  2 +-
>  drivers/gpu/drm/via/via_dmablit.c  |  3 ++-
>  drivers/infiniband/hw/hfi1/user_pages.c|  3 ++-
>  drivers/misc/genwqe/card_utils.c   |  2 +-
>  drivers/misc/vmw_vmci/vmci_host.c  |  2 +-
>  drivers/misc/vmw_vmci/vmci_queue_pair.c|  6 --
>  drivers/platform/goldfish/goldfish_pipe.c  |  3 ++-
>  drivers/rapidio/devices/rio_mport_cdev.c   |  4 +++-
>  drivers/sbus/char/oradax.c |  2 +-
>  drivers/scsi/st.c  |  3 ++-
>  drivers/staging/gasket/gasket_page_table.c |  4 ++--
>  drivers/tee/tee_shm.c  |  2 +-
>  drivers/vfio/vfio_iommu_spapr_tce.c|  3 ++-
>  drivers/vhost/vhost.c  |  2 +-
>  drivers/video/fbdev/pvr2fb.c   |  2 +-
>  drivers/virt/fsl_hypervisor.c  |  2 +-
>  drivers/xen/gntdev.c   |  2 +-
>  fs/orangefs/orangefs-bufmap.c  |  2 +-
>  include/linux/mm.h |  4 ++--
>  kernel/futex.c |  2 +-
>  lib/iov_iter.c |  7 +--
>  mm/gup.c   | 10 +-
>  mm/util.c  |  8 
>  net/ceph/pagevec.c |  2 +-
>  net/rds/info.c |  2 +-
>  net/rds/rdma.c |  3 ++-
>  35 files changed, 79 insertions(+), 63 deletions(-)


>
> diff --git a/arch/mips/mm/gup.c b/arch/mips/mm/gup.c
> index 0d14e0d8eacf..4c2b4483683c 100644
> --- a/arch/mips/mm/gup.c
> +++ b/arch/mips/mm/gup.c
> @@ -235,7 +235,7 @@ int __get_user_pages_fast(unsigned long start, int 
> nr_pages, int write,
>   * get_user_pages_fast() - pin user pages in memory
>   * @start: starting user address
>   * @nr_pages:  number of pages from start to pin
> - * @write: whether pages will be written to
> + * @gup_flags: flags modifying pin behaviour
>   * @pages: array that receives pointers to the pages pinned.
>   * Should be at least nr_pages long.
>   *
> @@ -247,8 +247,8 @@ int __get_user_pages_fast(unsigned long start, int 
> nr_pages, int write,
>   * requested. If nr_pages is 0 or negative, returns 0. If no pages
>   * were pinned, returns -errno.
>   */
> -int get_user_pages_fast(unsigned long start, int nr_pages, int write,
> -   struct page **pages)
> +int get_user_pages_fast(unsigned long start, int nr_pages,
> +   unsigned int gup_flags, struct page **pages)

This looks a tad scary given all related thrash especially when it's
only 1 user that wants to do get_user_page_fast_longterm, right? Maybe
something like the following. Note I explicitly moved the flags to the
end so that someone half paying attention that calls
__get_user_pages_fast will get a compile error if they specify the
args in the same order.

diff --git a/include/linux/mm.h b/include/linux/mm.h
index 76ba638ceda8..c6c743bc2c68 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1505,8 +1505,15 @@ static inline long
get_user_pages_longterm(unsigned long start,
 }
 #endif /* CONFIG_FS_DAX */

-int get_user_pages_fast(unsigned long start, int nr_pages, int write,
-   struct page **pages);
+
+int __get_user_pages_fast(unsigned long start, int nr_pages,
+   struct page **pages, unsigned int gup_flags);
+
+static inline int get_user_pages_fast(unsigned long start, int
nr_pages, int write,
+   struct page **pages)
+{
+   return __get_user_pages_fast(start, nr_pages, pages, write ?
FOLL_WRITE);
+}

 /* Container for pinned pfns / pages */
 struct frame_vector {


[RESEND 3/7] mm/gup: Change GUP fast to use flags rather than a write 'bool'

2019-03-17 Thread ira . weiny
From: Ira Weiny 

To facilitate additional options to get_user_pages_fast() change the
singular write parameter to be gup_flags.

This patch does not change any functionality.  New functionality will
follow in subsequent patches.

Some of the get_user_pages_fast() call sites were unchanged because they
already passed FOLL_WRITE or 0 for the write parameter.

Signed-off-by: Ira Weiny 

---
Changes from V1:
Rebase to current merge tree
arch/powerpc/mm/mmu_context_iommu.c no longer calls gup_fast
The gup_longterm was converted in patch 1

 arch/mips/mm/gup.c | 11 ++-
 arch/powerpc/kvm/book3s_64_mmu_hv.c|  4 ++--
 arch/powerpc/kvm/e500_mmu.c|  2 +-
 arch/s390/kvm/interrupt.c  |  2 +-
 arch/s390/mm/gup.c | 12 ++--
 arch/sh/mm/gup.c   | 11 ++-
 arch/sparc/mm/gup.c|  9 +
 arch/x86/kvm/paging_tmpl.h |  2 +-
 arch/x86/kvm/svm.c |  2 +-
 drivers/fpga/dfl-afu-dma-region.c  |  2 +-
 drivers/gpu/drm/via/via_dmablit.c  |  3 ++-
 drivers/infiniband/hw/hfi1/user_pages.c|  3 ++-
 drivers/misc/genwqe/card_utils.c   |  2 +-
 drivers/misc/vmw_vmci/vmci_host.c  |  2 +-
 drivers/misc/vmw_vmci/vmci_queue_pair.c|  6 --
 drivers/platform/goldfish/goldfish_pipe.c  |  3 ++-
 drivers/rapidio/devices/rio_mport_cdev.c   |  4 +++-
 drivers/sbus/char/oradax.c |  2 +-
 drivers/scsi/st.c  |  3 ++-
 drivers/staging/gasket/gasket_page_table.c |  4 ++--
 drivers/tee/tee_shm.c  |  2 +-
 drivers/vfio/vfio_iommu_spapr_tce.c|  3 ++-
 drivers/vhost/vhost.c  |  2 +-
 drivers/video/fbdev/pvr2fb.c   |  2 +-
 drivers/virt/fsl_hypervisor.c  |  2 +-
 drivers/xen/gntdev.c   |  2 +-
 fs/orangefs/orangefs-bufmap.c  |  2 +-
 include/linux/mm.h |  4 ++--
 kernel/futex.c |  2 +-
 lib/iov_iter.c |  7 +--
 mm/gup.c   | 10 +-
 mm/util.c  |  8 
 net/ceph/pagevec.c |  2 +-
 net/rds/info.c |  2 +-
 net/rds/rdma.c |  3 ++-
 35 files changed, 79 insertions(+), 63 deletions(-)

diff --git a/arch/mips/mm/gup.c b/arch/mips/mm/gup.c
index 0d14e0d8eacf..4c2b4483683c 100644
--- a/arch/mips/mm/gup.c
+++ b/arch/mips/mm/gup.c
@@ -235,7 +235,7 @@ int __get_user_pages_fast(unsigned long start, int 
nr_pages, int write,
  * get_user_pages_fast() - pin user pages in memory
  * @start: starting user address
  * @nr_pages:  number of pages from start to pin
- * @write: whether pages will be written to
+ * @gup_flags: flags modifying pin behaviour
  * @pages: array that receives pointers to the pages pinned.
  * Should be at least nr_pages long.
  *
@@ -247,8 +247,8 @@ int __get_user_pages_fast(unsigned long start, int 
nr_pages, int write,
  * requested. If nr_pages is 0 or negative, returns 0. If no pages
  * were pinned, returns -errno.
  */
-int get_user_pages_fast(unsigned long start, int nr_pages, int write,
-   struct page **pages)
+int get_user_pages_fast(unsigned long start, int nr_pages,
+   unsigned int gup_flags, struct page **pages)
 {
struct mm_struct *mm = current->mm;
unsigned long addr, len, end;
@@ -273,7 +273,8 @@ int get_user_pages_fast(unsigned long start, int nr_pages, 
int write,
next = pgd_addr_end(addr, end);
if (pgd_none(pgd))
goto slow;
-   if (!gup_pud_range(pgd, addr, next, write, pages, ))
+   if (!gup_pud_range(pgd, addr, next, gup_flags & FOLL_WRITE,
+  pages, ))
goto slow;
} while (pgdp++, addr = next, addr != end);
local_irq_enable();
@@ -289,7 +290,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, 
int write,
pages += nr;
 
ret = get_user_pages_unlocked(start, (end - start) >> PAGE_SHIFT,
- pages, write ? FOLL_WRITE : 0);
+ pages, gup_flags);
 
/* Have to be a bit careful with return values */
if (nr > 0) {
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c 
b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index be7bc070eae5..ab3d484c5e2e 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -600,7 +600,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct 
kvm_vcpu *vcpu,
/* If writing != 0, then the HPTE must allow writing, if we get here */
write_ok = writing;
hva =