From: Josef Bacik <josef@toxicpanda.com>
To: yangyun <yangyun50@huawei.com>
Cc: Miklos Szeredi <miklos@szeredi.hu>,
linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 2/2] fuse: add support for no forget requests
Date: Fri, 26 Jul 2024 11:40:17 -0400 [thread overview]
Message-ID: <20240726154017.GE3432726@perftesting> (raw)
In-Reply-To: <20240726083752.302301-3-yangyun50@huawei.com>
On Fri, Jul 26, 2024 at 04:37:52PM +0800, yangyun wrote:
> FUSE_FORGET requests are not used if the fuse file system does not
> implement the forget operation in userspace (e.g., fuse file system
> does not cache any inodes).
>
> However, the kernel is invisible to the userspace implementation and
> always sends FUSE_FORGET requests, which can lead to performance
> degradation because of useless contex switch and memory copy in some
> cases (e.g., many inodes are evicted from icache which was described
> in commit 07e77dca8a1f ("fuse: separate queue for FORGET requests")).
>
> Just like 'no_interrupt' in 'struct fuse_conn', we add 'no_forget'.
> But since FUSE_FORGET request does not have a reply from userspce,
> we can not use ENOSYS to reflect the 'no_forget' assignment. So add
> the FUSE_NO_FORGET_SUPPORT init flag.
>
> Besides, if no_forget is enabled, 'nlookup' in 'struct fuse_inode'
> does not used and its value change can be disabled which are protected
> by spin_lock to reduce lock contention.
>
> Signed-off-by: yangyun <yangyun50@huawei.com>
> ---
> fs/fuse/dev.c | 6 ++++++
> fs/fuse/dir.c | 4 +---
> fs/fuse/fuse_i.h | 24 ++++++++++++++++++++++++
> fs/fuse/inode.c | 10 +++++-----
> fs/fuse/readdir.c | 8 ++------
> include/uapi/linux/fuse.h | 3 +++
> 6 files changed, 41 insertions(+), 14 deletions(-)
>
> diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
> index 932356833b0d..10890db9426b 100644
> --- a/fs/fuse/dev.c
> +++ b/fs/fuse/dev.c
> @@ -238,6 +238,9 @@ void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget,
> {
> struct fuse_iqueue *fiq = &fc->iq;
>
> + if (fc->no_forget)
> + return;
> +
> forget->forget_one.nodeid = nodeid;
> forget->forget_one.nlookup = nlookup;
>
> @@ -257,6 +260,9 @@ void fuse_force_forget(struct fuse_mount *fm, u64 nodeid)
> struct fuse_forget_in inarg;
> FUSE_ARGS(args);
>
> + if (fm->fc->no_forget)
> + return;
> +
> memset(&inarg, 0, sizeof(inarg));
> inarg.nlookup = 1;
> args.opcode = FUSE_FORGET;
> diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
> index 6bfb3a128658..833225ed1d4f 100644
> --- a/fs/fuse/dir.c
> +++ b/fs/fuse/dir.c
> @@ -236,9 +236,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
> fuse_force_forget(fm, outarg.nodeid);
> goto invalid;
> }
> - spin_lock(&fi->lock);
> - fi->nlookup++;
> - spin_unlock(&fi->lock);
> + fuse_nlookup_inc_if_enabled(fm->fc, fi);
> }
> if (ret == -ENOMEM || ret == -EINTR)
> goto out;
> diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
> index b9a5b8ec0de5..924d6b0ad700 100644
> --- a/fs/fuse/fuse_i.h
> +++ b/fs/fuse/fuse_i.h
> @@ -860,6 +860,9 @@ struct fuse_conn {
> /** Passthrough support for read/write IO */
> unsigned int passthrough:1;
>
> + /** Do not send FORGET request */
> + unsigned int no_forget:1;
> +
> /** Maximum stack depth for passthrough backing files */
> int max_stack_depth;
>
> @@ -1029,6 +1032,27 @@ static inline void fuse_sync_bucket_dec(struct fuse_sync_bucket *bucket)
> rcu_read_unlock();
> }
>
> +static inline void fuse_nlookup_inc_if_enabled(struct fuse_conn *fc, struct fuse_inode *fi)
> +{
> + if (fc->no_forget)
> + return;
> +
> + spin_lock(&fi->lock);
> + fi->nlookup++;
> + spin_unlock(&fi->lock);
> +}
> +
> +static inline void fuse_nlookup_dec_if_enabled(struct fuse_conn *fc, struct fuse_inode *fi)
> +{
> + if (fc->no_forget)
> + return;
> +
> + spin_lock(&fi->lock);
> + fi->nlookup--;
> + spin_lock(&fi->lock);
> +}
This naming scheme is overly verbose, you can simply have
fuse_inc_nlookup()
fuse_dec_nlookup()
Thanks,
Josef
next prev parent reply other threads:[~2024-07-26 15:40 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-26 8:37 [PATCH 0/2] fuse: add no forget support yangyun
2024-07-26 8:37 ` [PATCH 1/2] fuse: replace fuse_queue_forget with fuse_force_forget if error yangyun
2024-07-26 15:39 ` Josef Bacik
2024-07-27 10:05 ` yangyun
2024-08-22 15:26 ` Miklos Szeredi
2024-08-23 11:58 ` yangyun
2024-07-26 8:37 ` [PATCH 2/2] fuse: add support for no forget requests yangyun
2024-07-26 15:40 ` Josef Bacik [this message]
2024-07-27 10:08 ` yangyun
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=20240726154017.GE3432726@perftesting \
--to=josef@toxicpanda.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=miklos@szeredi.hu \
--cc=yangyun50@huawei.com \
/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.