On Tue 22-07-14 15:47:53, Matthew Wilcox wrote: > From: Matthew Wilcox <willy@xxxxxxxxxxxxxxx> > > vm_insert_mixed() will fail if there is already a valid PTE at that > location. The DAX code would rather replace the previous value with > the new PTE. > > Signed-off-by: Matthew Wilcox <willy@xxxxxxxxxxxxxxx> This looks good to me although I'm not an expert in this area. So just: Acked-by: Jan Kara <jack@xxxxxxx> Honza > --- > include/linux/mm.h | 8 ++++++-- > mm/memory.c | 34 +++++++++++++++++++++------------- > 2 files changed, 27 insertions(+), 15 deletions(-) > > diff --git a/include/linux/mm.h b/include/linux/mm.h > index e04f531..8d1194c 100644 > --- a/include/linux/mm.h > +++ b/include/linux/mm.h > @@ -1958,8 +1958,12 @@ int remap_pfn_range(struct vm_area_struct *, unsigned long addr, > int vm_insert_page(struct vm_area_struct *, unsigned long addr, struct page *); > int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr, > unsigned long pfn); > -int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, > - unsigned long pfn); > +int __vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, > + unsigned long pfn, bool replace); > +#define vm_insert_mixed(vma, addr, pfn) \ > + __vm_insert_mixed(vma, addr, pfn, false) > +#define vm_replace_mixed(vma, addr, pfn) \ > + __vm_insert_mixed(vma, addr, pfn, true) > int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start, unsigned long len); > > > diff --git a/mm/memory.c b/mm/memory.c > index 42bf429..cf06c97 100644 > --- a/mm/memory.c > +++ b/mm/memory.c > @@ -1476,7 +1476,7 @@ pte_t *__get_locked_pte(struct mm_struct *mm, unsigned long addr, > * pages reserved for the old functions anyway. > */ > static int insert_page(struct vm_area_struct *vma, unsigned long addr, > - struct page *page, pgprot_t prot) > + struct page *page, pgprot_t prot, bool replace) > { > struct mm_struct *mm = vma->vm_mm; > int retval; > @@ -1492,8 +1492,12 @@ static int insert_page(struct vm_area_struct *vma, unsigned long addr, > if (!pte) > goto out; > retval = -EBUSY; > - if (!pte_none(*pte)) > - goto out_unlock; > + if (!pte_none(*pte)) { > + if (!replace) > + goto out_unlock; > + VM_BUG_ON(!mutex_is_locked(&vma->vm_file->f_mapping->i_mmap_mutex)); > + zap_page_range_single(vma, addr, PAGE_SIZE, NULL); > + } > > /* Ok, finally just insert the thing.. */ > get_page(page); > @@ -1549,12 +1553,12 @@ int vm_insert_page(struct vm_area_struct *vma, unsigned long addr, > BUG_ON(vma->vm_flags & VM_PFNMAP); > vma->vm_flags |= VM_MIXEDMAP; > } > - return insert_page(vma, addr, page, vma->vm_page_prot); > + return insert_page(vma, addr, page, vma->vm_page_prot, false); > } > EXPORT_SYMBOL(vm_insert_page); > > static int insert_pfn(struct vm_area_struct *vma, unsigned long addr, > - unsigned long pfn, pgprot_t prot) > + unsigned long pfn, pgprot_t prot, bool replace) > { > struct mm_struct *mm = vma->vm_mm; > int retval; > @@ -1566,8 +1570,12 @@ static int insert_pfn(struct vm_area_struct *vma, unsigned long addr, > if (!pte) > goto out; > retval = -EBUSY; > - if (!pte_none(*pte)) > - goto out_unlock; > + if (!pte_none(*pte)) { > + if (!replace) > + goto out_unlock; > + VM_BUG_ON(!mutex_is_locked(&vma->vm_file->f_mapping->i_mmap_mutex)); > + zap_page_range_single(vma, addr, PAGE_SIZE, NULL); > + } > > /* Ok, finally just insert the thing.. */ > entry = pte_mkspecial(pfn_pte(pfn, prot)); > @@ -1620,14 +1628,14 @@ int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr, > if (track_pfn_insert(vma, &pgprot, pfn)) > return -EINVAL; > > - ret = insert_pfn(vma, addr, pfn, pgprot); > + ret = insert_pfn(vma, addr, pfn, pgprot, false); > > return ret; > } > EXPORT_SYMBOL(vm_insert_pfn); > > -int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, > - unsigned long pfn) > +int __vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, > + unsigned long pfn, bool replace) > { > BUG_ON(!(vma->vm_flags & VM_MIXEDMAP)); > > @@ -1645,11 +1653,11 @@ int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, > struct page *page; > > page = pfn_to_page(pfn); > - return insert_page(vma, addr, page, vma->vm_page_prot); > + return insert_page(vma, addr, page, vma->vm_page_prot, replace); > } > - return insert_pfn(vma, addr, pfn, vma->vm_page_prot); > + return insert_pfn(vma, addr, pfn, vma->vm_page_prot, replace); > } > -EXPORT_SYMBOL(vm_insert_mixed); > +EXPORT_SYMBOL(__vm_insert_mixed); > > /* > * maps a range of physical memory into the requested pages. the old > -- > 2.0.0 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Jan Kara <jack@xxxxxxx> SUSE Labs, CR -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html