mm: use mm_populate() for mremap() of VM_LOCKED vmas
Signed-off-by: Michel Lespinasse <walken@google.com>
Acked-by: Rik van Riel <riel@redhat.com>
Tested-by: Andy Lutomirski <luto@amacapital.net>
Cc: Greg Ungerer <gregungerer@westnet.com.au>
Cc: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff --git a/mm/mremap.c b/mm/mremap.c
index f9766f4..ebe27a8 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -209,7 +209,7 @@
static unsigned long move_vma(struct vm_area_struct *vma,
unsigned long old_addr, unsigned long old_len,
- unsigned long new_len, unsigned long new_addr)
+ unsigned long new_len, unsigned long new_addr, bool *locked)
{
struct mm_struct *mm = vma->vm_mm;
struct vm_area_struct *new_vma;
@@ -300,9 +300,7 @@
if (vm_flags & VM_LOCKED) {
mm->locked_vm += new_len >> PAGE_SHIFT;
- if (new_len > old_len)
- mlock_vma_pages_range(new_vma, new_addr + old_len,
- new_addr + new_len);
+ *locked = true;
}
return new_addr;
@@ -367,9 +365,8 @@
return ERR_PTR(-EAGAIN);
}
-static unsigned long mremap_to(unsigned long addr,
- unsigned long old_len, unsigned long new_addr,
- unsigned long new_len)
+static unsigned long mremap_to(unsigned long addr, unsigned long old_len,
+ unsigned long new_addr, unsigned long new_len, bool *locked)
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
@@ -419,7 +416,7 @@
if (ret & ~PAGE_MASK)
goto out1;
- ret = move_vma(vma, addr, old_len, new_len, new_addr);
+ ret = move_vma(vma, addr, old_len, new_len, new_addr, locked);
if (!(ret & ~PAGE_MASK))
goto out;
out1:
@@ -457,6 +454,7 @@
struct vm_area_struct *vma;
unsigned long ret = -EINVAL;
unsigned long charged = 0;
+ bool locked = false;
down_write(¤t->mm->mmap_sem);
@@ -479,7 +477,8 @@
if (flags & MREMAP_FIXED) {
if (flags & MREMAP_MAYMOVE)
- ret = mremap_to(addr, old_len, new_addr, new_len);
+ ret = mremap_to(addr, old_len, new_addr, new_len,
+ &locked);
goto out;
}
@@ -521,8 +520,8 @@
vm_stat_account(mm, vma->vm_flags, vma->vm_file, pages);
if (vma->vm_flags & VM_LOCKED) {
mm->locked_vm += pages;
- mlock_vma_pages_range(vma, addr + old_len,
- addr + new_len);
+ locked = true;
+ new_addr = addr;
}
ret = addr;
goto out;
@@ -548,11 +547,13 @@
goto out;
}
- ret = move_vma(vma, addr, old_len, new_len, new_addr);
+ ret = move_vma(vma, addr, old_len, new_len, new_addr, &locked);
}
out:
if (ret & ~PAGE_MASK)
vm_unacct_memory(charged);
up_write(¤t->mm->mmap_sem);
+ if (locked && new_len > old_len)
+ mm_populate(new_addr + old_len, new_len - old_len);
return ret;
}