Got bellow lockdep warning during tests. It is false alarm though.
[ 1184.479097] =============================================
[ 1184.479187] [ INFO: possible recursive locking detected ]
[ 1184.479277] 3.10.0-rc3+ #13 Tainted: G C
[ 1184.479355] ---------------------------------------------
[ 1184.479444] mkdir/2215 is trying to acquire lock:
[ 1184.479521] (&(&dentry->d_lock)->rlock){+.+...}, at: [<
ffffffffa06cc27c>] ll_md_blocking_ast+0x55c/0x655 [lustre]
[ 1184.479801]
but task is already holding lock:
[ 1184.479895] (&(&dentry->d_lock)->rlock){+.+...}, at: [<
ffffffffa06cc1b1>] ll_md_blocking_ast+0x491/0x655 [lustre]
[ 1184.480101]
other info that might help us debug this:
[ 1184.480206] Possible unsafe locking scenario:
[ 1184.480300] CPU0
[ 1184.480340] ----
[ 1184.480380] lock(&(&dentry->d_lock)->rlock);
[ 1184.480458] lock(&(&dentry->d_lock)->rlock);
[ 1184.480536]
*** DEADLOCK ***
[ 1184.480761] May be due to missing lock nesting notation
[ 1184.480936] 4 locks held by mkdir/2215:
[ 1184.481037] #0: (sb_writers#11){.+.+.+}, at: [<
ffffffff811531a9>] mnt_want_write+0x24/0x4b
[ 1184.481273] #1: (&type->i_mutex_dir_key#3/1){+.+.+.}, at: [<
ffffffff81144fce>] kern_path_create+0x8c/0x144
[ 1184.481513] #2: (&sb->s_type->i_lock_key#19){+.+...}, at: [<
ffffffffa06cc180>] ll_md_blocking_ast+0x460/0x655 [lustre]
[ 1184.481778] #3: (&(&dentry->d_lock)->rlock){+.+...}, at: [<
ffffffffa06cc1b1>] ll_md_blocking_ast+0x491/0x655 [lustre]
[ 1184.482050]
Signed-off-by: Peng Tao <tao.peng@emc.com>
Signed-off-by: Andreas Dilger <andreas.dilger@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
libcfs_debug_dumpstack(NULL);
}
- d_lustre_invalidate(dentry);
+ d_lustre_invalidate(dentry, 0);
}
ll_unlock_dcache(inode);
here to preserve get_cwd functionality on 2.6.
Bug 10503 */
if (!dentry->d_inode->i_nlink)
- d_lustre_invalidate(dentry);
+ d_lustre_invalidate(dentry, 0);
ll_lookup_finish_locks(&oit, dentry);
} else if (!ll_have_md_lock(dentry->d_inode, &ibits, LCK_MINMODE)) {
* ll_md_blocking_ast), unhash this dentry, and let dcache to reclaim it later;
* else dput() of the last refcount will unhash this dentry and kill it.
*/
-static inline void d_lustre_invalidate(struct dentry *dentry)
+static inline void d_lustre_invalidate(struct dentry *dentry, int nested)
{
CDEBUG(D_DENTRY, "invalidate dentry %.*s (%p) parent %p inode %p "
"refc %d\n", dentry->d_name.len, dentry->d_name.name, dentry,
dentry->d_parent, dentry->d_inode, d_refcount(dentry));
- spin_lock(&dentry->d_lock);
+ spin_lock_nested(&dentry->d_lock,
+ nested ? DENTRY_D_LOCK_NESTED : DENTRY_D_LOCK_NORMAL);
__d_lustre_invalidate(dentry);
if (d_refcount(dentry) == 0)
__d_drop(dentry);
&dentry->d_subdirs,
d_u.d_child) {
if (child->d_inode == NULL)
- d_lustre_invalidate(child);
+ d_lustre_invalidate(child, 1);
}
}
spin_unlock(&dentry->d_lock);