aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorMichel Lespinasse <walken@google.com>2013-02-22 19:32:38 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-23 20:50:11 -0500
commita1ea9549a7254b17ba85809f4a0200abc21453a2 (patch)
treeec1f1a12a3adb777b99f98fef22c2ec4d0e18b28 /mm
parentbebeb3d68b24bb4132d452c5707fe321208bcbcd (diff)
mm: use mm_populate() for blocking remap_file_pages()
Signed-off-by: Michel Lespinasse <walken@google.com> Reviewed-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')
-rw-r--r--mm/fremap.c22
1 files changed, 6 insertions, 16 deletions
diff --git a/mm/fremap.c b/mm/fremap.c
index 2db886e31044..b42e32171530 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -129,6 +129,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
129 struct vm_area_struct *vma; 129 struct vm_area_struct *vma;
130 int err = -EINVAL; 130 int err = -EINVAL;
131 int has_write_lock = 0; 131 int has_write_lock = 0;
132 vm_flags_t vm_flags;
132 133
133 if (prot) 134 if (prot)
134 return err; 135 return err;
@@ -228,30 +229,16 @@ get_write_lock:
228 /* 229 /*
229 * drop PG_Mlocked flag for over-mapped range 230 * drop PG_Mlocked flag for over-mapped range
230 */ 231 */
231 vm_flags_t saved_flags = vma->vm_flags;
232 if (!has_write_lock) 232 if (!has_write_lock)
233 goto get_write_lock; 233 goto get_write_lock;
234 vm_flags = vma->vm_flags;
234 munlock_vma_pages_range(vma, start, start + size); 235 munlock_vma_pages_range(vma, start, start + size);
235 vma->vm_flags = saved_flags; 236 vma->vm_flags = vm_flags;
236 } 237 }
237 238
238 mmu_notifier_invalidate_range_start(mm, start, start + size); 239 mmu_notifier_invalidate_range_start(mm, start, start + size);
239 err = vma->vm_ops->remap_pages(vma, start, size, pgoff); 240 err = vma->vm_ops->remap_pages(vma, start, size, pgoff);
240 mmu_notifier_invalidate_range_end(mm, start, start + size); 241 mmu_notifier_invalidate_range_end(mm, start, start + size);
241 if (!err) {
242 if (vma->vm_flags & VM_LOCKED) {
243 /*
244 * might be mapping previously unmapped range of file
245 */
246 mlock_vma_pages_range(vma, start, start + size);
247 } else if (!(flags & MAP_NONBLOCK)) {
248 if (unlikely(has_write_lock)) {
249 downgrade_write(&mm->mmap_sem);
250 has_write_lock = 0;
251 }
252 make_pages_present(start, start+size);
253 }
254 }
255 242
256 /* 243 /*
257 * We can't clear VM_NONLINEAR because we'd have to do 244 * We can't clear VM_NONLINEAR because we'd have to do
@@ -260,10 +247,13 @@ get_write_lock:
260 */ 247 */
261 248
262out: 249out:
250 vm_flags = vma->vm_flags;
263 if (likely(!has_write_lock)) 251 if (likely(!has_write_lock))
264 up_read(&mm->mmap_sem); 252 up_read(&mm->mmap_sem);
265 else 253 else
266 up_write(&mm->mmap_sem); 254 up_write(&mm->mmap_sem);
255 if (!err && ((vm_flags & VM_LOCKED) || !(flags & MAP_NONBLOCK)))
256 mm_populate(start, size);
267 257
268 return err; 258 return err;
269} 259}