Ian Kent <raven@xxxxxxxxxx> writes: > The kernfs global lock restricts the ability to perform kernfs node > lookup operations in parallel during path walks. > > Change the kernfs mutex to an rwsem so that, when opportunity arises, > node searches can be done in parallel with path walk lookups. > > Signed-off-by: Ian Kent <raven@xxxxxxxxxx> > --- > fs/kernfs/dir.c | 117 ++++++++++++++++++++++++------------------- > fs/kernfs/file.c | 4 + > fs/kernfs/inode.c | 16 +++--- > fs/kernfs/kernfs-internal.h | 5 +- > fs/kernfs/mount.c | 12 ++-- > fs/kernfs/symlink.c | 4 + > include/linux/kernfs.h | 2 - > 7 files changed, 86 insertions(+), 74 deletions(-) > > diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c > index 5151c712f06f5..1e2e35a201dfb 100644 > --- a/fs/kernfs/dir.c > +++ b/fs/kernfs/dir.c > @@ -17,7 +17,7 @@ > > #include "kernfs-internal.h" > > -DEFINE_MUTEX(kernfs_mutex); > +DECLARE_RWSEM(kernfs_rwsem); > static DEFINE_SPINLOCK(kernfs_rename_lock); /* kn->parent and ->name */ > static char kernfs_pr_cont_buf[PATH_MAX]; /* protected by rename_lock */ > static DEFINE_SPINLOCK(kernfs_idr_lock); /* root->ino_idr */ > @@ -26,10 +26,21 @@ static DEFINE_SPINLOCK(kernfs_idr_lock); /* root->ino_idr */ > > static bool kernfs_active(struct kernfs_node *kn) > { > - lockdep_assert_held(&kernfs_mutex); > return atomic_read(&kn->active) >= 0; > } > > +static bool kernfs_active_write(struct kernfs_node *kn) > +{ > + lockdep_assert_held_write(&kernfs_rwsem); > + return kernfs_active(kn); > +} > + > +static bool kernfs_active_read(struct kernfs_node *kn) > +{ > + lockdep_assert_held_read(&kernfs_rwsem); > + return kernfs_active(kn); > +} This bit is unnecessary and confusing. There is nothing read/write about how the kernfs file is active (aka being used be a function). Further all that is needed for correct operation is: > static bool kernfs_active(struct kernfs_node *kn) > { > - lockdep_assert_held(&kernfs_mutex); > + lockdep_assert_held(&kernfs_rwsem); > return atomic_read(&kn->active) >= 0; > } Eric