From: Bernd Schubert <[email protected]>
To: Luis Henriques <[email protected]>, Bernd Schubert <[email protected]>
Cc: Miklos Szeredi <[email protected]>, Jens Axboe <[email protected]>,
Pavel Begunkov <[email protected]>,
[email protected], [email protected],
Joanne Koong <[email protected]>,
Josef Bacik <[email protected]>,
Amir Goldstein <[email protected]>,
Ming Lei <[email protected]>, David Wei <[email protected]>
Subject: Re: [PATCH v9 10/17] fuse: Add io-uring sqe commit and fetch support
Date: Tue, 7 Jan 2025 16:59:18 +0100 [thread overview]
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>
On 1/7/25 15:42, Luis Henriques wrote:
> Hi,
>
> On Tue, Jan 07 2025, Bernd Schubert wrote:
>
>> This adds support for fuse request completion through ring SQEs
>> (FUSE_URING_CMD_COMMIT_AND_FETCH handling). After committing
>> the ring entry it becomes available for new fuse requests.
>> Handling of requests through the ring (SQE/CQE handling)
>> is complete now.
>>
>> Fuse request data are copied through the mmaped ring buffer,
>> there is no support for any zero copy yet.
>
> Please find below a few more comments.
Thanks, I fixed all comments, except of retry in fuse_uring_next_fuse_req.
[...]
>
> Also, please note that I'm trying to understand this patchset (and the
> whole fuse-over-io-uring thing), so most of my comments are minor nits.
> And those that are not may simply be wrong! I'm just noting them as I
> navigate through the code.
>
> (And by the way, thanks for this work!)
>
>> +/*
>> + * Get the next fuse req and send it
>> + */
>> +static void fuse_uring_next_fuse_req(struct fuse_ring_ent *ring_ent,
>> + struct fuse_ring_queue *queue,
>> + unsigned int issue_flags)
>> +{
>> + int err;
>> + bool has_next;
>> +
>> +retry:
>> + spin_lock(&queue->lock);
>> + fuse_uring_ent_avail(ring_ent, queue);
>> + has_next = fuse_uring_ent_assign_req(ring_ent);
>> + spin_unlock(&queue->lock);
>> +
>> + if (has_next) {
>> + err = fuse_uring_send_next_to_ring(ring_ent, issue_flags);
>> + if (err)
>> + goto retry;
>
> I wonder whether this is safe. Maybe this is *obviously* safe, but I'm
> still trying to understand this patchset; so, for me, it is not :-)
>
> Would it be worth it trying to limit the maximum number of retries?
No, we cannot limit retries. Let's do a simple example with one ring
entry and also just one queue. Multiple applications create fuse
requests. The first application fills the only available ring entry
and submits it, the others just get queued in queue->fuse_req_queue.
After that the application just waits request_wait_answer()
On commit of the first request the ring task has to take the next
request from queue->fuse_req_queue - if something fails with that
request it has to complete it and proceed to the next request.
If we would introduce a max-retries here, it would put the ring entry
on hold (FRRS_AVAILABLE) and until another application comes, it would
forever wait there. The applications waiting in request_wait_answer
would never complete either.
>
>> + }
>> +}
>> +
>> +static int fuse_ring_ent_set_commit(struct fuse_ring_ent *ent)
>> +{
>> + struct fuse_ring_queue *queue = ent->queue;
>> +
>> + lockdep_assert_held(&queue->lock);
>> +
>> + if (WARN_ON_ONCE(ent->state != FRRS_USERSPACE))
>> + return -EIO;
>> +
>> + ent->state = FRRS_COMMIT;
>> + list_move(&ent->list, &queue->ent_commit_queue);
>> +
>> + return 0;
>> +}
>> +
>> +/* FUSE_URING_CMD_COMMIT_AND_FETCH handler */
>> +static int fuse_uring_commit_fetch(struct io_uring_cmd *cmd, int issue_flags,
>> + struct fuse_conn *fc)
>> +{
>> + const struct fuse_uring_cmd_req *cmd_req = io_uring_sqe_cmd(cmd->sqe);
>> + struct fuse_ring_ent *ring_ent;
>> + int err;
>> + struct fuse_ring *ring = fc->ring;
>> + struct fuse_ring_queue *queue;
>> + uint64_t commit_id = READ_ONCE(cmd_req->commit_id);
>> + unsigned int qid = READ_ONCE(cmd_req->qid);
>> + struct fuse_pqueue *fpq;
>> + struct fuse_req *req;
>> +
>> + err = -ENOTCONN;
>> + if (!ring)
>> + return err;
>> +
>> + if (qid >= ring->nr_queues)
>> + return -EINVAL;
>> +
>> + queue = ring->queues[qid];
>> + if (!queue)
>> + return err;
>> + fpq = &queue->fpq;
>> +
>> + spin_lock(&queue->lock);
>> + /* Find a request based on the unique ID of the fuse request
>> + * This should get revised, as it needs a hash calculation and list
>> + * search. And full struct fuse_pqueue is needed (memory overhead).
>> + * As well as the link from req to ring_ent.
>> + */
>> + req = fuse_request_find(fpq, commit_id);
>> + err = -ENOENT;
>> + if (!req) {
>> + pr_info("qid=%d commit_id %llu not found\n", queue->qid,
>> + commit_id);
>> + spin_unlock(&queue->lock);
>> + return err;
>> + }
>> + list_del_init(&req->list);
>> + ring_ent = req->ring_entry;
>> + req->ring_entry = NULL;
>> +
>> + err = fuse_ring_ent_set_commit(ring_ent);
>> + if (err != 0) {
>
> I'm probably missing something, but because we removed 'req' from the list
> above, aren't we leaking it if we get an error here?
Hmm, yeah, that is debatable. We basically have a grave error here.
Either kernel or userspace are doing something wrong. Though probably
you are right and we should end the request with EIO.
Thanks,
Bernd
next prev parent reply other threads:[~2025-01-07 15:59 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-07 0:25 [PATCH v9 00/17] fuse: fuse-over-io-uring Bernd Schubert
2025-01-07 0:25 ` [PATCH v9 01/17] fuse: rename to fuse_dev_end_requests and make non-static Bernd Schubert
2025-01-07 0:25 ` [PATCH v9 02/17] fuse: Move fuse_get_dev to header file Bernd Schubert
2025-01-07 0:25 ` [PATCH v9 03/17] fuse: Move request bits Bernd Schubert
2025-01-07 0:25 ` [PATCH v9 04/17] fuse: Add fuse-io-uring design documentation Bernd Schubert
2025-01-07 0:25 ` [PATCH v9 05/17] fuse: make args->in_args[0] to be always the header Bernd Schubert
2025-01-07 0:25 ` [PATCH v9 06/17] fuse: {io-uring} Handle SQEs - register commands Bernd Schubert
2025-01-07 9:56 ` Luis Henriques
2025-01-07 12:07 ` Bernd Schubert
2025-01-17 11:06 ` Pavel Begunkov
2025-01-19 22:47 ` Bernd Schubert
2025-01-07 0:25 ` [PATCH v9 07/17] fuse: Make fuse_copy non static Bernd Schubert
2025-01-07 0:25 ` [PATCH v9 08/17] fuse: Add fuse-io-uring handling into fuse_copy Bernd Schubert
2025-01-10 22:18 ` Joanne Koong
2025-01-07 0:25 ` [PATCH v9 09/17] fuse: {io-uring} Make hash-list req unique finding functions non-static Bernd Schubert
2025-01-07 0:25 ` [PATCH v9 10/17] fuse: Add io-uring sqe commit and fetch support Bernd Schubert
2025-01-07 14:42 ` Luis Henriques
2025-01-07 15:59 ` Bernd Schubert [this message]
2025-01-07 16:21 ` Luis Henriques
2025-01-13 22:44 ` Joanne Koong
2025-01-20 0:33 ` Bernd Schubert
2025-01-17 11:18 ` Pavel Begunkov
2025-01-17 11:20 ` Bernd Schubert
2025-01-07 0:25 ` [PATCH v9 11/17] fuse: {io-uring} Handle teardown of ring entries Bernd Schubert
2025-01-07 15:31 ` Luis Henriques
2025-01-17 11:23 ` Pavel Begunkov
2025-01-07 0:25 ` [PATCH v9 12/17] fuse: {io-uring} Make fuse_dev_queue_{interrupt,forget} non-static Bernd Schubert
2025-01-07 0:25 ` [PATCH v9 13/17] fuse: Allow to queue fg requests through io-uring Bernd Schubert
2025-01-07 15:54 ` Luis Henriques
2025-01-07 18:59 ` Bernd Schubert
2025-01-07 21:25 ` Luis Henriques
2025-01-17 11:47 ` Pavel Begunkov
2025-01-17 21:52 ` Bernd Schubert
2025-01-07 0:25 ` [PATCH v9 14/17] fuse: Allow to queue bg " Bernd Schubert
2025-01-17 11:49 ` Pavel Begunkov
2025-01-07 0:25 ` [PATCH v9 15/17] fuse: {io-uring} Prevent mount point hang on fuse-server termination Bernd Schubert
2025-01-07 16:14 ` Luis Henriques
2025-01-07 19:03 ` Bernd Schubert
2025-01-17 11:52 ` Pavel Begunkov
2025-01-07 0:25 ` [PATCH v9 16/17] fuse: block request allocation until io-uring init is complete Bernd Schubert
2025-01-07 0:25 ` [PATCH v9 17/17] fuse: enable fuse-over-io-uring Bernd Schubert
2025-01-17 11:52 ` Pavel Begunkov
2025-01-17 9:07 ` [PATCH v9 00/17] fuse: fuse-over-io-uring Miklos Szeredi
2025-01-17 9:12 ` Bernd Schubert
2025-01-17 12:01 ` Pavel Begunkov
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 \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox