Commit 1b8e3f21 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] exportfs - Remove unnecessary locking from find_exported_dentry()

From: "Jose R. Santos" <jrsantos@austin.ibm.com>

After discussing it with Neil, he fell that the original justification for
taking the kernel_lock on find_exported_dentry() is not longer valid and
should be safe to remove.

This patch fixes an issue while running SpecSFS where under memory
pressure, shrinking dcache cause find_exported_dentry() to allocate
disconnected dentries that later needed to be properly connected.  The
connecting part of the code was done with BKL taken which cause a sharp
drop in performance during iterations and profiles showing 75% time spent
on find_exported_dentry().  After applying the patch, time spent on the
function is reduce to <1%.

I have tested this on an 8-way machine with 56 filesystems for several days
now with no problems using ext2, ext3, xfs and jfs.
parent efbe9b14
...@@ -135,7 +135,6 @@ find_exported_dentry(struct super_block *sb, void *obj, void *parent, ...@@ -135,7 +135,6 @@ find_exported_dentry(struct super_block *sb, void *obj, void *parent,
* the noprogress counter. If we go through the loop 10 times (2 is * the noprogress counter. If we go through the loop 10 times (2 is
* probably enough) without getting anywhere, we just give up * probably enough) without getting anywhere, we just give up
*/ */
lock_kernel();
noprogress= 0; noprogress= 0;
while (target_dir->d_flags & DCACHE_DISCONNECTED && noprogress++ < 10) { while (target_dir->d_flags & DCACHE_DISCONNECTED && noprogress++ < 10) {
struct dentry *pd = target_dir; struct dentry *pd = target_dir;
...@@ -232,7 +231,6 @@ find_exported_dentry(struct super_block *sb, void *obj, void *parent, ...@@ -232,7 +231,6 @@ find_exported_dentry(struct super_block *sb, void *obj, void *parent,
/* something went wrong - oh-well */ /* something went wrong - oh-well */
if (!err) if (!err)
err = -ESTALE; err = -ESTALE;
unlock_kernel();
goto err_target; goto err_target;
} }
/* if we weren't after a directory, have one more step to go */ /* if we weren't after a directory, have one more step to go */
...@@ -254,7 +252,6 @@ find_exported_dentry(struct super_block *sb, void *obj, void *parent, ...@@ -254,7 +252,6 @@ find_exported_dentry(struct super_block *sb, void *obj, void *parent,
} }
} }
dput(target_dir); dput(target_dir);
unlock_kernel();
/* now result is properly connected, it is our best bet */ /* now result is properly connected, it is our best bet */
if (acceptable(context, result)) if (acceptable(context, result))
return result; return result;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment