|
@@ -74,6 +74,7 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
|
|
|
unsigned long new_addr)
|
|
unsigned long new_addr)
|
|
|
{
|
|
{
|
|
|
struct address_space *mapping = NULL;
|
|
struct address_space *mapping = NULL;
|
|
|
|
|
+ struct anon_vma *anon_vma = vma->anon_vma;
|
|
|
struct mm_struct *mm = vma->vm_mm;
|
|
struct mm_struct *mm = vma->vm_mm;
|
|
|
pte_t *old_pte, *new_pte, pte;
|
|
pte_t *old_pte, *new_pte, pte;
|
|
|
spinlock_t *old_ptl, *new_ptl;
|
|
spinlock_t *old_ptl, *new_ptl;
|
|
@@ -88,6 +89,8 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
|
|
|
mapping = vma->vm_file->f_mapping;
|
|
mapping = vma->vm_file->f_mapping;
|
|
|
mutex_lock(&mapping->i_mmap_mutex);
|
|
mutex_lock(&mapping->i_mmap_mutex);
|
|
|
}
|
|
}
|
|
|
|
|
+ if (anon_vma)
|
|
|
|
|
+ anon_vma_lock(anon_vma);
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
|
* We don't have to worry about the ordering of src and dst
|
|
* We don't have to worry about the ordering of src and dst
|
|
@@ -114,6 +117,8 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
|
|
|
spin_unlock(new_ptl);
|
|
spin_unlock(new_ptl);
|
|
|
pte_unmap(new_pte - 1);
|
|
pte_unmap(new_pte - 1);
|
|
|
pte_unmap_unlock(old_pte - 1, old_ptl);
|
|
pte_unmap_unlock(old_pte - 1, old_ptl);
|
|
|
|
|
+ if (anon_vma)
|
|
|
|
|
+ anon_vma_unlock(anon_vma);
|
|
|
if (mapping)
|
|
if (mapping)
|
|
|
mutex_unlock(&mapping->i_mmap_mutex);
|
|
mutex_unlock(&mapping->i_mmap_mutex);
|
|
|
}
|
|
}
|
|
@@ -220,15 +225,6 @@ static unsigned long move_vma(struct vm_area_struct *vma,
|
|
|
|
|
|
|
|
moved_len = move_page_tables(vma, old_addr, new_vma, new_addr, old_len);
|
|
moved_len = move_page_tables(vma, old_addr, new_vma, new_addr, old_len);
|
|
|
if (moved_len < old_len) {
|
|
if (moved_len < old_len) {
|
|
|
- /*
|
|
|
|
|
- * Before moving the page tables from the new vma to
|
|
|
|
|
- * the old vma, we need to be sure the old vma is
|
|
|
|
|
- * queued after new vma in the same_anon_vma list to
|
|
|
|
|
- * prevent SMP races with rmap_walk (that could lead
|
|
|
|
|
- * rmap_walk to miss some page table).
|
|
|
|
|
- */
|
|
|
|
|
- anon_vma_moveto_tail(vma);
|
|
|
|
|
-
|
|
|
|
|
/*
|
|
/*
|
|
|
* On error, move entries back from new area to old,
|
|
* On error, move entries back from new area to old,
|
|
|
* which will succeed since page tables still there,
|
|
* which will succeed since page tables still there,
|