User: | Jiri Slaby |
Error type: | Double Lock |
Error type description: | Some lock is locked twice unintentionally in a sequence |
File location: | mm/mmap.c |
Line in file: | 2398 |
Project: | Linux Kernel |
Project version: | 2.6.28 |
Tools: |
Undetermined 1
|
Entered: | 2012-02-27 21:22:42 UTC |
2368 * A single task can't take more than one mm_take_all_locks() in a row 2369 * or it would deadlock. 2370 * 2371 * The LSB in anon_vma->head.next and the AS_MM_ALL_LOCKS bitflag in 2372 * mapping->flags avoid to take the same lock twice, if more than one 2373 * vma in this mm is backed by the same anon_vma or address_space. 2374 * 2375 * We can take all the locks in random order because the VM code 2376 * taking i_mmap_lock or anon_vma->lock outside the mmap_sem never 2377 * takes more than one of them in a row. Secondly we're protected 2378 * against a concurrent mm_take_all_locks() by the mm_all_locks_mutex. 2379 * 2380 * mm_take_all_locks() and mm_drop_all_locks are expensive operations 2381 * that may have to take thousand of locks. 2382 * 2383 * mm_take_all_locks() can fail if it's interrupted by signals. 2384 */ 2385int mm_take_all_locks(struct mm_struct *mm) 2386{ 2387 struct vm_area_struct *vma; 2388 int ret = -EINTR; 2389 2390 BUG_ON(down_read_trylock(&mm->mmap_sem)); 2391 2392 mutex_lock(&mm_all_locks_mutex); 2393 2394 for (vma = mm->mmap; vma; vma = vma->vm_next) { 2395 if (signal_pending(current)) 2396 goto out_unlock; 2397 if (vma->vm_file && vma->vm_file->f_mapping) 2398 vm_lock_mapping(mm, vma->vm_file->f_mapping); 2399 } 2400 2401 for (vma = mm->mmap; vma; vma = vma->vm_next) { 2402 if (signal_pending(current)) 2403 goto out_unlock; 2404 if (vma->anon_vma) 2405 vm_lock_anon_vma(mm, vma->anon_vma); 2406 } 2407 2408 ret = 0;