Thread (57 messages) 57 messages, 8 authors, 2014-08-01

Re: [PATCH v8 05/22] Add vm_replace_mixed()

From: Kirill A. Shutemov <hidden>
Date: 2014-07-23 11:45:40
Also in: linux-fsdevel, lkml

On Tue, Jul 22, 2014 at 03:47:53PM -0400, Matthew Wilcox wrote:
quoted hunk ↗ jump to hunk
From: Matthew Wilcox <redacted>

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 <redacted>
---
 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);
zap_page_range_single() takes ptl by itself in zap_pte_range(). It's not
going to work.

And zap_page_range*() is pretty heavy weapon to shoot down one pte, which
we already have pointer to. Why?

-- 
 Kirill A. Shutemov

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help