On Tue, 14 Nov 2017 11:56:34 -0800 Dan Williams <dan.j.williams@xxxxxxxxx> wrote: > Until there is a solution to the dma-to-dax vs truncate problem it is > not safe to allow long standing memory registrations against > filesytem-dax vmas. Device-dax vmas do not have this problem and are > explicitly allowed. > > This is temporary until a "memory registration with layout-lease" > mechanism can be implemented for the affected sub-systems (RDMA and > V4L2). > > --- a/mm/gup.c > +++ b/mm/gup.c > @@ -1095,6 +1095,70 @@ long get_user_pages(unsigned long start, unsigned long nr_pages, > } > EXPORT_SYMBOL(get_user_pages); > > +#ifdef CONFIG_FS_DAX > +/* > + * This is the same as get_user_pages() in that it assumes we are > + * operating on the current task's mm, but it goes further to validate > + * that the vmas associated with the address range are suitable for > + * longterm elevated page reference counts. For example, filesystem-dax > + * 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. > + * > + * "longterm" == userspace controlled elevated page count lifetime. > + * Contrast this to iov_iter_get_pages() usages which are transient. > + */ > +long get_user_pages_longterm(unsigned long start, unsigned long nr_pages, > + unsigned int gup_flags, struct page **pages, > + struct vm_area_struct **vmas_arg) > +{ > + struct vm_area_struct **vmas = vmas_arg; > + struct vm_area_struct *vma_prev = NULL; > + long rc, i; > + > + if (!pages) > + return -EINVAL; > + > + if (!vmas) { > + vmas = kzalloc(sizeof(struct vm_area_struct *) * nr_pages, > + GFP_KERNEL); > + if (!vmas) > + return -ENOMEM; > + } > > ... > I'll do this: --- a/mm/gup.c~mm-introduce-get_user_pages_longterm-fix +++ a/mm/gup.c @@ -1120,8 +1120,8 @@ long get_user_pages_longterm(unsigned lo return -EINVAL; if (!vmas) { - vmas = kzalloc(sizeof(struct vm_area_struct *) * nr_pages, - GFP_KERNEL); + vmas = kcalloc(nr_pages, sizeof(struct vm_area_struct *), + GFP_KERNEL); if (!vmas) return -ENOMEM; } _