diff options
-rw-r--r-- | mm/mremap.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/mm/mremap.c b/mm/mremap.c index a39b7b91be46..93adddecf978 100644 --- a/mm/mremap.c +++ b/mm/mremap.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/hugetlb.h> | 11 | #include <linux/hugetlb.h> |
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/shm.h> | 13 | #include <linux/shm.h> |
14 | #include <linux/ksm.h> | ||
14 | #include <linux/mman.h> | 15 | #include <linux/mman.h> |
15 | #include <linux/swap.h> | 16 | #include <linux/swap.h> |
16 | #include <linux/capability.h> | 17 | #include <linux/capability.h> |
@@ -182,6 +183,17 @@ static unsigned long move_vma(struct vm_area_struct *vma, | |||
182 | if (mm->map_count >= sysctl_max_map_count - 3) | 183 | if (mm->map_count >= sysctl_max_map_count - 3) |
183 | return -ENOMEM; | 184 | return -ENOMEM; |
184 | 185 | ||
186 | /* | ||
187 | * Advise KSM to break any KSM pages in the area to be moved: | ||
188 | * it would be confusing if they were to turn up at the new | ||
189 | * location, where they happen to coincide with different KSM | ||
190 | * pages recently unmapped. But leave vma->vm_flags as it was, | ||
191 | * so KSM can come around to merge on vma and new_vma afterwards. | ||
192 | */ | ||
193 | if (ksm_madvise(vma, old_addr, old_addr + old_len, | ||
194 | MADV_UNMERGEABLE, &vm_flags)) | ||
195 | return -ENOMEM; | ||
196 | |||
185 | new_pgoff = vma->vm_pgoff + ((old_addr - vma->vm_start) >> PAGE_SHIFT); | 197 | new_pgoff = vma->vm_pgoff + ((old_addr - vma->vm_start) >> PAGE_SHIFT); |
186 | new_vma = copy_vma(&vma, new_addr, new_len, new_pgoff); | 198 | new_vma = copy_vma(&vma, new_addr, new_len, new_pgoff); |
187 | if (!new_vma) | 199 | if (!new_vma) |