All of lore.kernel.org
 help / color / mirror / Atom feed
From: Miklos Szeredi <miklos@szeredi.hu>
To: Ian Kent <raven@themaw.net>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Tejun Heo <tj@kernel.org>, Eric Sandeen <sandeen@sandeen.net>,
	Fox Chen <foxhlchen@gmail.com>,
	Brice Goglin <brice.goglin@gmail.com>,
	Al Viro <viro@zeniv.linux.org.uk>,
	Rick Lindsley <ricklind@linux.vnet.ibm.com>,
	David Howells <dhowells@redhat.com>,
	Marcelo Tosatti <mtosatti@redhat.com>,
	linux-fsdevel <linux-fsdevel@vger.kernel.org>,
	Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: [REPOST PATCH v4 4/5] kernfs: use i_lock to protect concurrent inode updates
Date: Tue, 1 Jun 2021 15:18:54 +0200	[thread overview]
Message-ID: <CAJfpegshedor_ZiQ_8EdLGRG0AEWb5Sy5Pa4SwPg9+f196_mGg@mail.gmail.com> (raw)
In-Reply-To: <162218366632.34379.11311748209082333016.stgit@web.messagingengine.com>

On Fri, 28 May 2021 at 08:34, Ian Kent <raven@themaw.net> wrote:
>
> 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 operations and path
> walks when the number of concurrent 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 additional lock is
> needed to protect against multiple processes concurrently updating
> the inode attributes and link count in kernfs_refresh_inode().
>
> The inode i_lock seems like the sensible thing to use to protect these
> inode attribute updates so use it in kernfs_refresh_inode().
>
> Signed-off-by: Ian Kent <raven@themaw.net>
> ---
>  fs/kernfs/inode.c |   10 ++++++----
>  fs/kernfs/mount.c |    4 ++--
>  2 files changed, 8 insertions(+), 6 deletions(-)
>
> diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
> index 3b01e9e61f14e..6728ecd81eb37 100644
> --- a/fs/kernfs/inode.c
> +++ b/fs/kernfs/inode.c
> @@ -172,6 +172,7 @@ static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode)
>  {
>         struct kernfs_iattrs *attrs = kn->iattr;
>
> +       spin_lock(&inode->i_lock);
>         inode->i_mode = kn->mode;
>         if (attrs)
>                 /*
> @@ -182,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(&inode->i_lock);
>  }
>
>  int kernfs_iop_getattr(struct user_namespace *mnt_userns,
> @@ -191,9 +193,9 @@ int kernfs_iop_getattr(struct user_namespace *mnt_userns,
>         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(&init_user_ns, inode, stat);
>         return 0;
> @@ -284,9 +286,9 @@ int kernfs_iop_permission(struct user_namespace *mnt_userns,
>
>         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(&init_user_ns, inode, mask);
>  }
> diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c
> index baa4155ba2edf..f2f909d09f522 100644
> --- a/fs/kernfs/mount.c
> +++ b/fs/kernfs/mount.c
> @@ -255,9 +255,9 @@ static int kernfs_fill_super(struct super_block *sb, struct kernfs_fs_context *k
>         sb->s_shrink.seeks = 0;
>
>         /* get root inode, initialize and unlock it */
> -       down_write(&kernfs_rwsem);
> +       down_read(&kernfs_rwsem);
>         inode = kernfs_get_inode(sb, info->root->kn);
> -       up_write(&kernfs_rwsem);
> +       up_read(&kernfs_rwsem);
>         if (!inode) {
>                 pr_debug("kernfs: could not get root inode\n");
>                 return -ENOMEM;
>

This last hunk is not mentioned in the patch header.  Why is this needed?

Otherwise looks good.

Thanks,
Miklos

  parent reply	other threads:[~2021-06-01 13:19 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-28  6:33 [REPOST PATCH v4 0/5] kernfs: proposed locking and concurrency improvement Ian Kent
2021-05-28  6:33 ` [REPOST PATCH v4 1/5] kernfs: move revalidate to be near lookup Ian Kent
2021-06-03 14:50   ` Eric W. Biederman
2021-06-04  2:29     ` Ian Kent
2021-05-28  6:34 ` [REPOST PATCH v4 2/5] kernfs: use VFS negative dentry caching Ian Kent
2021-06-01 12:41   ` Miklos Szeredi
2021-06-02  3:44     ` Ian Kent
2021-06-02  8:58       ` Miklos Szeredi
2021-06-02 10:57         ` Ian Kent
2021-06-03  2:15           ` Ian Kent
2021-06-03 23:57             ` Ian Kent
2021-06-04  1:07               ` Ian Kent
2021-06-03 17:26   ` Eric W. Biederman
2021-06-03 18:06     ` Miklos Szeredi
2021-06-03 22:02       ` Eric W. Biederman
2021-06-04  3:14         ` Ian Kent
2021-06-04 14:28           ` Eric W. Biederman
2021-06-05  3:19             ` Ian Kent
2021-06-05 20:52               ` Eric W. Biederman
2021-05-28  6:34 ` [REPOST PATCH v4 3/5] kernfs: switch kernfs to use an rwsem Ian Kent
2021-06-01 13:11   ` Miklos Szeredi
2021-06-03 16:59   ` Eric W. Biederman
2021-05-28  6:34 ` [REPOST PATCH v4 4/5] kernfs: use i_lock to protect concurrent inode updates Ian Kent
2021-05-31 14:53   ` [kernfs] 9a658329cd: stress-ng.get.ops_per_sec 191.4% improvement kernel test robot
2021-05-31 14:53     ` kernel test robot
2021-06-01 13:18   ` Miklos Szeredi [this message]
2021-06-02  5:41     ` [REPOST PATCH v4 4/5] kernfs: use i_lock to protect concurrent inode updates Ian Kent
2021-05-28  6:34 ` [REPOST PATCH v4 5/5] kernfs: add kernfs_need_inode_refresh() Ian Kent
2021-05-28  8:56 ` [REPOST PATCH v4 0/5] kernfs: proposed locking and concurrency improvement Greg Kroah-Hartman
2021-05-28 11:56   ` Fox Chen
2021-05-30  4:44   ` Fox Chen

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=CAJfpegshedor_ZiQ_8EdLGRG0AEWb5Sy5Pa4SwPg9+f196_mGg@mail.gmail.com \
    --to=miklos@szeredi.hu \
    --cc=brice.goglin@gmail.com \
    --cc=dhowells@redhat.com \
    --cc=foxhlchen@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mtosatti@redhat.com \
    --cc=raven@themaw.net \
    --cc=ricklind@linux.vnet.ibm.com \
    --cc=sandeen@sandeen.net \
    --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.