|
@@ -894,7 +894,15 @@ again: remove_next = 1 + (end > next->vm_end);
|
|
|
static inline int is_mergeable_vma(struct vm_area_struct *vma,
|
|
|
struct file *file, unsigned long vm_flags)
|
|
|
{
|
|
|
- if (vma->vm_flags ^ vm_flags)
|
|
|
+ /*
|
|
|
+ * VM_SOFTDIRTY should not prevent from VMA merging, if we
|
|
|
+ * match the flags but dirty bit -- the caller should mark
|
|
|
+ * merged VMA as dirty. If dirty bit won't be excluded from
|
|
|
+ * comparison, we increase pressue on the memory system forcing
|
|
|
+ * the kernel to generate new VMAs when old one could be
|
|
|
+ * extended instead.
|
|
|
+ */
|
|
|
+ if ((vma->vm_flags ^ vm_flags) & ~VM_SOFTDIRTY)
|
|
|
return 0;
|
|
|
if (vma->vm_file != file)
|
|
|
return 0;
|
|
@@ -1083,7 +1091,7 @@ static int anon_vma_compatible(struct vm_area_struct *a, struct vm_area_struct *
|
|
|
return a->vm_end == b->vm_start &&
|
|
|
mpol_equal(vma_policy(a), vma_policy(b)) &&
|
|
|
a->vm_file == b->vm_file &&
|
|
|
- !((a->vm_flags ^ b->vm_flags) & ~(VM_READ|VM_WRITE|VM_EXEC)) &&
|
|
|
+ !((a->vm_flags ^ b->vm_flags) & ~(VM_READ|VM_WRITE|VM_EXEC|VM_SOFTDIRTY)) &&
|
|
|
b->vm_pgoff == a->vm_pgoff + ((b->vm_start - a->vm_start) >> PAGE_SHIFT);
|
|
|
}
|
|
|
|