aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mremap.c
diff options
context:
space:
mode:
authorMichel Lespinasse <walken@google.com>2013-02-22 19:32:41 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-23 20:50:11 -0500
commit81909b842107ef8ca499f46ecb9b7afd87c20c52 (patch)
tree0af43272c9b0eb7b23fda4ba6cb28e24ae730a93 /mm/mremap.c
parent128557ffe147c282d8a25e6faeaec6099540bea4 (diff)
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>
Diffstat (limited to 'mm/mremap.c')
-rw-r--r--mm/mremap.c25
1 files changed, 13 insertions, 12 deletions
diff --git a/mm/mremap.c b/mm/mremap.c
index f9766f460299..ebe27a8efa62 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -209,7 +209,7 @@ unsigned long move_page_tables(struct vm_area_struct *vma,
209 209
210static unsigned long move_vma(struct vm_area_struct *vma, 210static unsigned long move_vma(struct vm_area_struct *vma,
211 unsigned long old_addr, unsigned long old_len, 211 unsigned long old_addr, unsigned long old_len,
212 unsigned long new_len, unsigned long new_addr) 212 unsigned long new_len, unsigned long new_addr, bool *locked)
213{ 213{
214 struct mm_struct *mm = vma->vm_mm; 214 struct mm_struct *mm = vma->vm_mm;
215 struct vm_area_struct *new_vma; 215 struct vm_area_struct *new_vma;
@@ -300,9 +300,7 @@ static unsigned long move_vma(struct vm_area_struct *vma,
300 300
301 if (vm_flags & VM_LOCKED) { 301 if (vm_flags & VM_LOCKED) {
302 mm->locked_vm += new_len >> PAGE_SHIFT; 302 mm->locked_vm += new_len >> PAGE_SHIFT;
303 if (new_len > old_len) 303 *locked = true;
304 mlock_vma_pages_range(new_vma, new_addr + old_len,
305 new_addr + new_len);
306 } 304 }
307 305
308 return new_addr; 306 return new_addr;
@@ -367,9 +365,8 @@ Eagain:
367 return ERR_PTR(-EAGAIN); 365 return ERR_PTR(-EAGAIN);
368} 366}
369 367
370static unsigned long mremap_to(unsigned long addr, 368static unsigned long mremap_to(unsigned long addr, unsigned long old_len,
371 unsigned long old_len, unsigned long new_addr, 369 unsigned long new_addr, unsigned long new_len, bool *locked)
372 unsigned long new_len)
373{ 370{
374 struct mm_struct *mm = current->mm; 371 struct mm_struct *mm = current->mm;
375 struct vm_area_struct *vma; 372 struct vm_area_struct *vma;
@@ -419,7 +416,7 @@ static unsigned long mremap_to(unsigned long addr,
419 if (ret & ~PAGE_MASK) 416 if (ret & ~PAGE_MASK)
420 goto out1; 417 goto out1;
421 418
422 ret = move_vma(vma, addr, old_len, new_len, new_addr); 419 ret = move_vma(vma, addr, old_len, new_len, new_addr, locked);
423 if (!(ret & ~PAGE_MASK)) 420 if (!(ret & ~PAGE_MASK))
424 goto out; 421 goto out;
425out1: 422out1:
@@ -457,6 +454,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
457 struct vm_area_struct *vma; 454 struct vm_area_struct *vma;
458 unsigned long ret = -EINVAL; 455 unsigned long ret = -EINVAL;
459 unsigned long charged = 0; 456 unsigned long charged = 0;
457 bool locked = false;
460 458
461 down_write(&current->mm->mmap_sem); 459 down_write(&current->mm->mmap_sem);
462 460
@@ -479,7 +477,8 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
479 477
480 if (flags & MREMAP_FIXED) { 478 if (flags & MREMAP_FIXED) {
481 if (flags & MREMAP_MAYMOVE) 479 if (flags & MREMAP_MAYMOVE)
482 ret = mremap_to(addr, old_len, new_addr, new_len); 480 ret = mremap_to(addr, old_len, new_addr, new_len,
481 &locked);
483 goto out; 482 goto out;
484 } 483 }
485 484
@@ -521,8 +520,8 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
521 vm_stat_account(mm, vma->vm_flags, vma->vm_file, pages); 520 vm_stat_account(mm, vma->vm_flags, vma->vm_file, pages);
522 if (vma->vm_flags & VM_LOCKED) { 521 if (vma->vm_flags & VM_LOCKED) {
523 mm->locked_vm += pages; 522 mm->locked_vm += pages;
524 mlock_vma_pages_range(vma, addr + old_len, 523 locked = true;
525 addr + new_len); 524 new_addr = addr;
526 } 525 }
527 ret = addr; 526 ret = addr;
528 goto out; 527 goto out;
@@ -548,11 +547,13 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
548 goto out; 547 goto out;
549 } 548 }
550 549
551 ret = move_vma(vma, addr, old_len, new_len, new_addr); 550 ret = move_vma(vma, addr, old_len, new_len, new_addr, &locked);
552 } 551 }
553out: 552out:
554 if (ret & ~PAGE_MASK) 553 if (ret & ~PAGE_MASK)
555 vm_unacct_memory(charged); 554 vm_unacct_memory(charged);
556 up_write(&current->mm->mmap_sem); 555 up_write(&current->mm->mmap_sem);
556 if (locked && new_len > old_len)
557 mm_populate(new_addr + old_len, new_len - old_len);
557 return ret; 558 return ret;
558} 559}