diff options
author | Michel Lespinasse <walken@google.com> | 2013-02-22 19:32:38 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-23 20:50:11 -0500 |
commit | a1ea9549a7254b17ba85809f4a0200abc21453a2 (patch) | |
tree | ec1f1a12a3adb777b99f98fef22c2ec4d0e18b28 /mm | |
parent | bebeb3d68b24bb4132d452c5707fe321208bcbcd (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.c | 22 |
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 | ||
262 | out: | 249 | out: |
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 | } |