[Devel] [PATCH RH7] pfcache: don't inherit vm_private_data on split and copy

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Wed Sep 26 18:41:23 MSK 2018


BUG_ON in synchronize_mapping_faults_vma triggered again, now we have:

crash> p *((struct vm_area_struct *) 0xffff88061dc890a0) -x
  vm_start = 0x7fa0b794a000,
  vm_prev = 0xffff8801194fe0e0,
  vm_flags = 0x8100073,
  vm_private_data2 = 0xffff8801194fe0e0,

Our vma has vm_private_data2 link set to different vma:

crash> p *((struct vm_area_struct *) 0xffff8801194fe0e0) -x
  vm_end = 0x7fa0b794a000,
  vm_next = 0xffff88061dc890a0,
  vm_flags = 0x8100071,

These two are neighbours and VM_WRITE flag is only set for the first
mount, looks like we got such vmas from split_vma.

So we need to reset vm_private_data2 everywhere we copy the contents of
vm_area_struct to a new entry. Found three more places searching after
"kmem_cache_alloc(vm_area_cachep, GFP_KERNEL)".

https://jira.sw.ru/browse/PSBM-88809
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
 mm/mmap.c  | 3 +++
 mm/nommu.c | 2 ++
 2 files changed, 5 insertions(+)

diff --git a/mm/mmap.c b/mm/mmap.c
index e316e1e6eabb..bcb6a9dbcc28 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2706,6 +2706,8 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
 		new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
 	}
 
+	new->vm_private_data2 = NULL;
+
 	pol = mpol_dup(vma_policy(vma));
 	if (IS_ERR(pol)) {
 		err = PTR_ERR(pol);
@@ -3260,6 +3262,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
 			new_vma->vm_start = addr;
 			new_vma->vm_end = addr + len;
 			new_vma->vm_pgoff = pgoff;
+			new_vma->vm_private_data2 = NULL;
 			pol = mpol_dup(vma_policy(vma));
 			if (IS_ERR(pol))
 				goto out_free_vma;
diff --git a/mm/nommu.c b/mm/nommu.c
index 4ad47976b81c..e9143d859b00 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1614,6 +1614,8 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
 		region->vm_pgoff = new->vm_pgoff += npages;
 	}
 
+	new->vm_private_data2 = NULL;
+
 	if (new->vm_ops && new->vm_ops->open)
 		new->vm_ops->open(new);
 
-- 
2.17.1



More information about the Devel mailing list