• Frederic Weisbecker's avatar
    kill-the-bkl/reiserfs: Fix induced mm->mmap_sem to sysfs_mutex dependency · 193be0ee
    Frederic Weisbecker authored
    Alexander Beregalov reported the following warning:
    
    	=======================================================
    	[ INFO: possible circular locking dependency detected ]
    	2.6.31-03149-gdcc030a #1
    	-------------------------------------------------------
    	udevadm/716 is trying to acquire lock:
    	 (&mm->mmap_sem){++++++}, at: [<c107249a>] might_fault+0x4a/0xa0
    
    	but task is already holding lock:
    	 (sysfs_mutex){+.+.+.}, at: [<c10cb9aa>] sysfs_readdir+0x5a/0x200
    
    	which lock already depends on the new lock.
    
    	the existing dependency chain (in reverse order) is:
    
    	-> #3 (sysfs_mutex){+.+.+.}:
    	       [...]
    
    	-> #2 (&bdev->bd_mutex){+.+.+.}:
    	       [...]
    
    	-> #1 (&REISERFS_SB(s)->lock){+.+.+.}:
    	       [...]
    
    	-> #0 (&mm->mmap_sem){++++++}:
    	       [...]
    
    On reiserfs mount path, we take the reiserfs lock and while
    initializing the journal, we open the device, taking the
    bdev->bd_mutex. Then rescan_partition() may signal the change
    to sysfs.
    
    We have then the following dependency:
    
    	reiserfs_lock -> bd_mutex -> sysfs_mutex
    
    Later, while entering reiserfs_readpage() after a pagefault in an
    mmaped reiserfs file, we are holding the mm->mmap_sem, and we are going
    to take the reiserfs lock too.
    We have then the following dependency:
    
    	mm->mmap_sem -> reiserfs_lock
    
    which, expanded with the previous dependency gives us:
    
    	mm->mmap_sem -> reiserfs_lock -> bd_mutex -> sysfs_mutex
    
    Now while entering the sysfs readdir path, we are holding the
    sysfs_mutex. And when we copy a directory entry to the user buffer, we
    might fault and then take the mm->mmap_sem lock. Which leads to the
    circular locking dependency reported.
    
    We can fix that by relaxing the reiserfs lock during the call to
    journal_init_dev(), which is the place where we open the mounted
    device.
    
    This is fine to relax the lock here because we are in the begining of
    the reiserfs mount path and there is nothing to protect at this time,
    the journal is not intialized.
    We just keep this lock around for paranoid reasons.
    Reported-by: default avatarAlexander Beregalov <a.beregalov@gmail.com>
    Tested-by: default avatarAlexander Beregalov <a.beregalov@gmail.com>
    Signed-off-by: default avatarFrederic Weisbecker <fweisbec@gmail.com>
    Cc: Jeff Mahoney <jeffm@suse.com>
    Cc: Chris Mason <chris.mason@oracle.com>
    Cc: Ingo Molnar <mingo@elte.hu>
    Cc: Alexander Beregalov <a.beregalov@gmail.com>
    Cc: Laurent Riffard <laurent.riffard@free.fr>
    193be0ee
journal.c 124 KB