aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/mmap.c')
-rw-r--r--mm/mmap.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/mm/mmap.c b/mm/mmap.c
index 971d0eda754a..339cf5c4d5d8 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2273,14 +2273,14 @@ int install_special_mapping(struct mm_struct *mm,
2273 2273
2274static DEFINE_MUTEX(mm_all_locks_mutex); 2274static DEFINE_MUTEX(mm_all_locks_mutex);
2275 2275
2276static void vm_lock_anon_vma(struct anon_vma *anon_vma) 2276static void vm_lock_anon_vma(struct mm_struct *mm, struct anon_vma *anon_vma)
2277{ 2277{
2278 if (!test_bit(0, (unsigned long *) &anon_vma->head.next)) { 2278 if (!test_bit(0, (unsigned long *) &anon_vma->head.next)) {
2279 /* 2279 /*
2280 * The LSB of head.next can't change from under us 2280 * The LSB of head.next can't change from under us
2281 * because we hold the mm_all_locks_mutex. 2281 * because we hold the mm_all_locks_mutex.
2282 */ 2282 */
2283 spin_lock(&anon_vma->lock); 2283 spin_lock_nest_lock(&anon_vma->lock, &mm->mmap_sem);
2284 /* 2284 /*
2285 * We can safely modify head.next after taking the 2285 * We can safely modify head.next after taking the
2286 * anon_vma->lock. If some other vma in this mm shares 2286 * anon_vma->lock. If some other vma in this mm shares
@@ -2296,7 +2296,7 @@ static void vm_lock_anon_vma(struct anon_vma *anon_vma)
2296 } 2296 }
2297} 2297}
2298 2298
2299static void vm_lock_mapping(struct address_space *mapping) 2299static void vm_lock_mapping(struct mm_struct *mm, struct address_space *mapping)
2300{ 2300{
2301 if (!test_bit(AS_MM_ALL_LOCKS, &mapping->flags)) { 2301 if (!test_bit(AS_MM_ALL_LOCKS, &mapping->flags)) {
2302 /* 2302 /*
@@ -2310,7 +2310,7 @@ static void vm_lock_mapping(struct address_space *mapping)
2310 */ 2310 */
2311 if (test_and_set_bit(AS_MM_ALL_LOCKS, &mapping->flags)) 2311 if (test_and_set_bit(AS_MM_ALL_LOCKS, &mapping->flags))
2312 BUG(); 2312 BUG();
2313 spin_lock(&mapping->i_mmap_lock); 2313 spin_lock_nest_lock(&mapping->i_mmap_lock, &mm->mmap_sem);
2314 } 2314 }
2315} 2315}
2316 2316
@@ -2358,11 +2358,17 @@ int mm_take_all_locks(struct mm_struct *mm)
2358 for (vma = mm->mmap; vma; vma = vma->vm_next) { 2358 for (vma = mm->mmap; vma; vma = vma->vm_next) {
2359 if (signal_pending(current)) 2359 if (signal_pending(current))
2360 goto out_unlock; 2360 goto out_unlock;
2361 if (vma->anon_vma)
2362 vm_lock_anon_vma(vma->anon_vma);
2363 if (vma->vm_file && vma->vm_file->f_mapping) 2361 if (vma->vm_file && vma->vm_file->f_mapping)
2364 vm_lock_mapping(vma->vm_file->f_mapping); 2362 vm_lock_mapping(mm, vma->vm_file->f_mapping);
2363 }
2364
2365 for (vma = mm->mmap; vma; vma = vma->vm_next) {
2366 if (signal_pending(current))
2367 goto out_unlock;
2368 if (vma->anon_vma)
2369 vm_lock_anon_vma(mm, vma->anon_vma);
2365 } 2370 }
2371
2366 ret = 0; 2372 ret = 0;
2367 2373
2368out_unlock: 2374out_unlock: