On Tue, May 27, 2014 at 02:40:54AM +0100, Al Viro wrote: > It looks plausible, but I doubt that serializing check_submounts_and_drop() > will suffice - shrink_dcache_parent() is just as unpleasant and it *is* > triggered in the same situations. Moreover, the lack of loop in memory > shrinkers doesn't help - we might get shrink_dentry_list() from one of > those and loops that keep calling d_walk() from check_submounts_and_drop() > or shrink_dcache_parent()... > > > Anyway, I'd like Mika to test the stupid "let's serialize the dentry > > shrinking in check_submounts_and_drop()" to see if his problem goes > > away. I agree that it's not the _proper_ fix, but we're damn late in > > the rc series.. > > That we are... FWIW, if the nastiness matches the description above, > the right place to do something probably would be when those two > suckers get positive return value from d_walk() along with an empty > shrink list. I wonder if we should do down_read() in shrink_dentry_list() > and down_write();up_write() in that case in shrink_dcache_parent() and > check_submounts_and_drop(). How about the following? As the matter of fact, let's try this instead - retry the same sucker immediately in case if trylocks fail. Comments? diff --git a/fs/dcache.c b/fs/dcache.c index 42ae01e..d58d4cc 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -798,6 +798,7 @@ static void shrink_dentry_list(struct list_head *list) while (!list_empty(list)) { dentry = list_entry(list->prev, struct dentry, d_lru); +again: spin_lock(&dentry->d_lock); /* * The dispose list is isolated and dentries are not accounted @@ -830,7 +831,8 @@ static void shrink_dentry_list(struct list_head *list) */ d_shrink_add(dentry, list); spin_unlock(&dentry->d_lock); - continue; + cpu_relax(); + goto again; } /* * We need to prune ancestors too. This is necessary to prevent -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html