All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ian Kent <raven@themaw.net>
To: Fox Chen <foxhlchen@gmail.com>
Cc: Tejun Heo <tj@kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Rick Lindsley <ricklind@linux.vnet.ibm.com>,
	Al Viro <viro@ZenIV.linux.org.uk>,
	David Howells <dhowells@redhat.com>,
	Miklos Szeredi <miklos@szeredi.hu>,
	linux-fsdevel <linux-fsdevel@vger.kernel.org>
Subject: [PATCH 6/6] kernfs: add a spinlock to kernfs iattrs for inode updates
Date: Tue, 22 Dec 2020 15:48:39 +0800	[thread overview]
Message-ID: <160862331927.291330.16497188823501358991.stgit@mickey.themaw.net> (raw)
In-Reply-To: <160862320263.291330.9467216031366035418.stgit@mickey.themaw.net>

The inode operations .permission() and .getattr() use the kernfs node
write lock but all that's needed is to keep the rb tree stable while
updating the inode attributes as well as protecting the update itself
against concurrent changes.

And .permission() is called frequently during path walks and can cause
quite a bit of contention between kernfs node opertations and path
walks when the number of concurrant walks is high.

To change kernfs_iop_getattr() and kernfs_iop_permission() to take
the rw sem read lock instead of the write lock an addtional lock is
needed to protect against multiple processes concurrently updating
the inode attributes and link count in kernfs_refresh_inode().

So add a spin lock to the kernfs_iattrs structure to protect these
inode attributes updates and use it in kernfs_refresh_inode().

Signed-off-by: Ian Kent <raven@themaw.net>
---
 fs/kernfs/inode.c           |   11 +++++++----
 fs/kernfs/kernfs-internal.h |    1 +
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
index ddaf18198935..f583dde70174 100644
--- a/fs/kernfs/inode.c
+++ b/fs/kernfs/inode.c
@@ -55,6 +55,7 @@ static struct kernfs_iattrs *__kernfs_iattrs(struct kernfs_node *kn, int alloc)
 	simple_xattrs_init(&kn->iattr->xattrs);
 	atomic_set(&kn->iattr->nr_user_xattrs, 0);
 	atomic_set(&kn->iattr->user_xattr_size, 0);
+	spin_lock_init(&kn->iattr->inode_lock);
 out_unlock:
 	ret = kn->iattr;
 	mutex_unlock(&iattr_mutex);
@@ -171,6 +172,7 @@ static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode)
 {
 	struct kernfs_iattrs *attrs = kn->iattr;
 
+	spin_lock(&attrs->inode_lock);
 	inode->i_mode = kn->mode;
 	if (attrs)
 		/*
@@ -181,6 +183,7 @@ static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode)
 
 	if (kernfs_type(kn) == KERNFS_DIR)
 		set_nlink(inode, kn->dir.subdirs + 2);
+	spin_unlock(&attrs->inode_lock);
 }
 
 int kernfs_iop_getattr(const struct path *path, struct kstat *stat,
@@ -189,9 +192,9 @@ int kernfs_iop_getattr(const struct path *path, struct kstat *stat,
 	struct inode *inode = d_inode(path->dentry);
 	struct kernfs_node *kn = inode->i_private;
 
-	down_write(&kernfs_rwsem);
+	down_read(&kernfs_rwsem);
 	kernfs_refresh_inode(kn, inode);
-	up_write(&kernfs_rwsem);
+	up_read(&kernfs_rwsem);
 
 	generic_fillattr(inode, stat);
 	return 0;
@@ -281,9 +284,9 @@ int kernfs_iop_permission(struct inode *inode, int mask)
 
 	kn = inode->i_private;
 
-	down_write(&kernfs_rwsem);
+	down_read(&kernfs_rwsem);
 	kernfs_refresh_inode(kn, inode);
-	up_write(&kernfs_rwsem);
+	up_read(&kernfs_rwsem);
 
 	return generic_permission(inode, mask);
 }
diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h
index a7b0e2074260..184e4424b389 100644
--- a/fs/kernfs/kernfs-internal.h
+++ b/fs/kernfs/kernfs-internal.h
@@ -29,6 +29,7 @@ struct kernfs_iattrs {
 	struct simple_xattrs	xattrs;
 	atomic_t		nr_user_xattrs;
 	atomic_t		user_xattr_size;
+	spinlock_t		inode_lock;
 };
 
 /* +1 to avoid triggering overflow warning when negating it */



  parent reply	other threads:[~2020-12-22  7:50 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-22  7:47 [PATCH 0/6] kernfs: proposed locking and concurrency improvement Ian Kent
2020-12-22  7:47 ` [PATCH 1/6] kernfs: move revalidate to be near lookup Ian Kent
2020-12-22  7:47 ` [PATCH 2/6] kernfs: use VFS negative dentry caching Ian Kent
2020-12-22  7:47 ` [PATCH 3/6] kernfs: use revision to identify directory node changes Ian Kent
2020-12-22  7:48 ` [PATCH 4/6] kernfs: switch kernfs to use an rwsem Ian Kent
2020-12-22  7:48 ` [PATCH 5/6] kernfs: stay in rcu-walk mode if possible Ian Kent
2021-02-05  8:23   ` Fox Chen
2021-02-05 12:10     ` Ian Kent
2020-12-22  7:48 ` Ian Kent [this message]
2020-12-24  6:23   ` [kernfs] ca0f27ecb7: BUG:kernel_NULL_pointer_dereference,address kernel test robot
2020-12-24  6:23     ` [kernfs] ca0f27ecb7: BUG:kernel_NULL_pointer_dereference, address kernel test robot
2020-12-23  7:30 ` [PATCH 0/6] kernfs: proposed locking and concurrency improvement Fox Chen
2021-01-04  0:42   ` Ian Kent
2021-01-06  2:38     ` Fox Chen
2021-01-11  3:19       ` Ian Kent
2021-01-11  4:20         ` Ian Kent
2021-01-11  7:04           ` Fox Chen
2021-01-11  8:42             ` Ian Kent
2021-01-11  9:02               ` Fox Chen
2021-01-12  0:27                 ` Ian Kent
2021-01-13  5:17                 ` Ian Kent
2021-01-13  7:00                   ` Fox Chen
2021-01-13  7:47                     ` Ian Kent
2021-01-13  7:50                       ` Ian Kent
2021-01-13  8:00                         ` Fox Chen
2021-01-14  3:20                           ` Fox Chen
2021-01-14  5:37                           ` Ian Kent

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=160862331927.291330.16497188823501358991.stgit@mickey.themaw.net \
    --to=raven@themaw.net \
    --cc=dhowells@redhat.com \
    --cc=foxhlchen@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --cc=ricklind@linux.vnet.ibm.com \
    --cc=tj@kernel.org \
    --cc=viro@ZenIV.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.