Re: [PATCH v4 6/7] VFS: add lockdep monitoring of DCACHE_PAR_LOOKUP lock.

From: Borah, Chaitanya Kumar

Date: Thu Oct 01 2026 - 06:48:36 EST




On 10/1/2026 2:38 AM, NeilBrown wrote:
On Thu, 01 Oct 2026, Borah, Chaitanya Kumar wrote:
Hello Neil,

On 9/5/2026 3:18 AM, NeilBrown wrote:
From: NeilBrown <neil@xxxxxxxxxx>

DCACHE_PAR_LOOKUP acts like a lock in that threads can block waiting for
it to clear. As we plan to make changes to lock order for this lock,
teach lockdep to monitor it so as to help detect bugs early.

As NFS allocates an in-lookup dentry to unlink a silly-renamed file, and
completes the lookup in a different thread, we need interfaces to
release and the acquire ownership of the lock. This avoids lockdep
complaining that a lock is still held on return to user-space.


This seems to be causing regression in our linux-next CI [1] since
next-20260928.

<4>[ 10.773931] ======================================================
<4>[ 10.780181] WARNING: possible circular locking dependency detected
<4>[ 10.786407] 7.3.0-rc5-next-20260928-next-20260928-g6375e61c01e9+
#1 Not tainted
<4>[ 10.793773] ------------------------------------------------------
<4>[ 10.800017] podman/794 is trying to acquire lock:
<4>[ 10.804801] ffff888133cb8388
(&type->i_mutex_dir_key#3){++++}-{4:4}, at: lookup_slow+0x31/0x60
<4>[ 10.814849]
but task is already holding lock:
<4>[ 10.820743] ffff88812dbd3048 (DCACHE_PAR_LOOKUP){+.+.}-{0:0}, at:
__d_alloc_parallel+0x53a/0x920
<4>[ 10.830976]
which lock already depends on the new lock.

Detailed log can be seen found in [2].

We confirmed that reverting the patch solves the issue.

Could you please check why the patch causes this regression and provide
a fix if necessary?

Regards
Chaitanya

[1] https://intel-gfx-ci.01.org/tree/linux-next/combined-alt.html?
[2]
https://intel-gfx-ci.01.org/tree/linux-next/next-20260928/bat-arls-6/boot0.txt

Thanks for the report!
The log shows that overlayfs is involved. overlayfs has special needs
with respect to lock nesting which I hadn't allowed for.

I think this patch should fix it. Please let me know.


This works! Thank you. Hopefully it gets into linux-next soon.

Feel free to use

Tested-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@xxxxxxxxx>

Thanks,
NeilBrown


diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index e487597337e8..e1448dd776b4 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -163,10 +163,34 @@ static int ovl_dentry_weak_revalidate(struct dentry *dentry, unsigned int flags)
return ovl_dentry_revalidate_common(dentry, flags, true);
}
+#ifdef CONFIG_LOCKDEP
+#define OVL_MAX_NESTING FILESYSTEM_MAX_STACK_DEPTH
+static int ovl_dentry_init(struct dentry *dentry)
+{
+ static struct lock_class_key ovl_d_lock_key[OVL_MAX_NESTING];
+ int depth = dentry->d_sb->s_stack_depth - 1;
+
+ if (WARN_ON_ONCE(depth < 0 || depth >= OVL_MAX_NESTING))
+ depth = 0;
+
+ /* Based on lockdep_set_class() */
+ lockdep_init_map_type(&dentry->lookup_map, "DCACHE_PAR_LOOKUP_OVL",
+ &ovl_d_lock_key[depth], 0,
+ dentry->lookup_map.wait_type_inner,
+ dentry->lookup_map.wait_type_outer,
+ dentry->lookup_map.lock_type);
+
+ return 0;
+}
+#else
+#define ovl_dentry_init NULL
+#endif
+
static const struct dentry_operations ovl_dentry_operations = {
.d_real = ovl_d_real,
.d_revalidate = ovl_dentry_revalidate,
.d_weak_revalidate = ovl_dentry_weak_revalidate,
+ .d_init = ovl_dentry_init,
};
#if IS_ENABLED(CONFIG_UNICODE)
@@ -176,6 +200,7 @@ static const struct dentry_operations ovl_dentry_ci_operations = {
.d_weak_revalidate = ovl_dentry_weak_revalidate,
.d_hash = generic_ci_d_hash,
.d_compare = generic_ci_d_compare,
+ .d_init = ovl_dentry_init,
};
#endif