[Devel] [PATCH RHEL9] fs/fuse: fix flush_bg_queue()

Alexey Kuznetsov kuznet at acronis.com
Fri Sep 29 13:00:05 MSK 2023


Ack

On Fri, Sep 29, 2023 at 5:17 PM Kui Liu <Kui.Liu at acronis.com> wrote:
>
> Currently flush_bg_queue() takes an input paramenter fiq, to which requests
>
> in the bg_queue will be dispatched without respect to what's been set to
>
> req->args->fiq. This behaviour totally breaks purpose of the request dispatching
>
> algorithm when there are multiple input queues. So instead we need to enqueue
>
> a request to its own req->args->fiq
>
>
>
> Removes the unnecessary 'spin_lock(&fc->bg_lock)' operation before return
>
> just to be unlocked later immediately. This can increase lock contention under
>
> heavy workload, thus negatively affects performance.
>
>
>
> Signed-off-by: Liu Kui <Kui.Liu at acronis.com>
>
> ---
>
> fs/fuse/dev.c | 32 +++++++++++++++-----------------
>
> 1 file changed, 15 insertions(+), 17 deletions(-)
>
>
>
> diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
>
> index fe26e8f01609..424180ff7ab2 100644
>
> --- a/fs/fuse/dev.c
>
> +++ b/fs/fuse/dev.c
>
> @@ -267,10 +267,12 @@ void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget,
>
>                }
>
> }
>
>
>
> -static void flush_bg_queue(struct fuse_conn *fc, struct fuse_iqueue *fiq)
>
> +static void flush_bg_queue_and_unlock(struct fuse_conn *fc)
>
> +__releases(fc->bg_lock)
>
> {
>
>                struct fuse_req *req, *next;
>
>                LIST_HEAD(kio_reqs);
>
> +              struct fuse_iqueue *fiq;
>
>
>
>                while (fc->active_background < fc->max_background &&
>
>                       !list_empty(&fc->bg_queue)) {
>
> @@ -287,17 +289,18 @@ static void flush_bg_queue(struct fuse_conn *fc, struct fuse_iqueue *fiq)
>
>                                                } else if (ret < 0)
>
>                                                                continue;
>
>                                }
>
> +                              fiq = req->args->fiq;
>
>                                spin_lock(&fiq->lock);
>
>                                req->in.h.unique = fuse_get_unique(fiq);
>
>                                queue_request_and_unlock(fiq, req);
>
>                }
>
>
>
>                spin_unlock(&fc->bg_lock);
>
> +
>
>                list_for_each_entry_safe(req, next, &kio_reqs, list) {
>
>                                list_del_init(&req->list);
>
>                                fc->kio.op->req_send(req, true);
>
>                }
>
> -               spin_lock(&fc->bg_lock);
>
> }
>
>
>
> /*
>
> @@ -356,8 +359,9 @@ void __fuse_request_end( struct fuse_req *req, bool flush_bg)
>
>                                fc->num_background--;
>
>                                fc->active_background--;
>
>                                if (flush_bg)
>
> -                                               flush_bg_queue(fc, fiq);
>
> -                               spin_unlock(&fc->bg_lock);
>
> +                                              flush_bg_queue_and_unlock(fc);
>
> +                              else
>
> +                                              spin_unlock(&fc->bg_lock);
>
>                }
>
>
>
>                if (test_bit(FR_ASYNC, &req->flags)) {
>
> @@ -609,6 +613,7 @@ static int fuse_request_queue_background(struct fuse_req *req)
>
>                if (ff && test_bit(FUSE_S_FAIL_IMMEDIATELY, &ff->ff_state)) {
>
>                                ret = -EIO;
>
>                } else if (likely(fc->connected)) {
>
> +                              ret = 0;
>
>                                fc->num_background++;
>
>                                if (fc->num_background == fc->max_background)
>
>                                                fc->blocked = 1;
>
> @@ -622,17 +627,14 @@ static int fuse_request_queue_background(struct fuse_req *req)
>
>                                                spin_lock(&fiq->lock);
>
>                                                req->in.h.unique = fuse_get_unique(fiq);
>
>                                                queue_request_and_unlock(fiq, req);
>
> -                                               ret = 0;
>
> -                                               goto unlock;
>
> +                              } else {
>
> +                                              list_add_tail(&req->list, &fc->bg_queue);
>
> +                                              flush_bg_queue_and_unlock(fc);
>
> +                                              goto out;
>
>                                }
>
> -
>
> -                               list_add_tail(&req->list, &fc->bg_queue);
>
> -                               flush_bg_queue(fc, fiq);
>
> -                               ret = 0;
>
>                }
>
> -unlock:
>
>                spin_unlock(&fc->bg_lock);
>
> -
>
> +out:
>
>                return ret;
>
> }
>
>
>
> @@ -2297,11 +2299,7 @@ void fuse_abort_conn(struct fuse_conn *fc)
>
>                                spin_lock(&fc->bg_lock);
>
>                                fc->blocked = 0;
>
>                                fc->max_background = UINT_MAX;
>
> -                               for_each_online_cpu(cpu)
>
> -                                               flush_bg_queue(fc, per_cpu_ptr(fc->iqs, cpu));
>
> -                               flush_bg_queue(fc, &fc->main_iq);
>
> -                               spin_unlock(&fc->bg_lock);
>
> -
>
> +                              flush_bg_queue_and_unlock(fc);
>
>
>
>                                for_each_online_cpu(cpu)
>
>                                                fuse_abort_iqueue(per_cpu_ptr(fc->iqs, cpu), &to_end);
>
> --
>
> 2.32.0 (Apple Git-132)



More information about the Devel mailing list