lkml.org 
[lkml]   [2004]   [Mar]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH 4/6] mremap vma_relink_file
Subtle point from Rajesh Venkatasubramanian: when mremap's move_vma
fails and so rewinds, before moving the file-based ptes back, we must
move new_vma before old vma in the i_mmap or i_mmap_shared list,
so that when racing against vmtruncate we cannot propagate pages
to be truncated back from new_vma into the just cleaned old_vma.

--- mremap3/include/linux/mm.h 2004-03-30 21:24:48.666410384 +0100
+++ mremap4/include/linux/mm.h 2004-03-30 21:25:00.131667400 +0100
@@ -540,6 +540,7 @@ extern void __vma_link_rb(struct mm_stru
struct rb_node **, struct rb_node *);
extern struct vm_area_struct *copy_vma(struct vm_area_struct *,
unsigned long addr, unsigned long len, unsigned long pgoff);
+extern void vma_relink_file(struct vm_area_struct *, struct vm_area_struct *);
extern void exit_mmap(struct mm_struct *);

extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
--- mremap3/mm/mmap.c 2004-03-30 21:24:48.668410080 +0100
+++ mremap4/mm/mmap.c 2004-03-30 21:25:00.133667096 +0100
@@ -1517,3 +1517,24 @@ struct vm_area_struct *copy_vma(struct v
}
return new_vma;
}
+
+/*
+ * Position vma after prev in shared file list:
+ * for mremap move error recovery racing against vmtruncate.
+ */
+void vma_relink_file(struct vm_area_struct *vma, struct vm_area_struct *prev)
+{
+ struct mm_struct *mm = vma->vm_mm;
+ struct address_space *mapping;
+
+ if (vma->vm_file) {
+ mapping = vma->vm_file->f_mapping;
+ if (mapping) {
+ down(&mapping->i_shared_sem);
+ spin_lock(&mm->page_table_lock);
+ list_move(&vma->shared, &prev->shared);
+ spin_unlock(&mm->page_table_lock);
+ up(&mapping->i_shared_sem);
+ }
+ }
+}
--- mremap3/mm/mremap.c 2004-03-30 21:24:48.671409624 +0100
+++ mremap4/mm/mremap.c 2004-03-30 21:25:00.136666640 +0100
@@ -187,7 +187,14 @@ static unsigned long move_vma(struct vm_
* On error, move entries back from new area to old,
* which will succeed since page tables still there,
* and then proceed to unmap new area instead of old.
+ *
+ * Subtle point from Rajesh Venkatasubramanian: before
+ * moving file-based ptes, move new_vma before old vma
+ * in the i_mmap or i_mmap_shared list, so when racing
+ * against vmtruncate we cannot propagate pages to be
+ * truncated back from new_vma into just cleaned old.
*/
+ vma_relink_file(vma, new_vma);
move_page_tables(new_vma, old_addr, new_addr, moved_len);
vma = new_vma;
old_len = new_len;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 14:02    [W:0.040 / U:0.012 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site