From: Jens Axboe <axboe@kernel.dk>
To: Pavel Begunkov <asml.silence@gmail.com>, io-uring@vger.kernel.org
Subject: Re: [PATCH 1/1] io_uring/rw: forbid multishot async reads
Date: Mon, 17 Feb 2025 08:37:53 -0700 [thread overview]
Message-ID: <205ed24e-238f-497e-9990-6bcb08acaf61@kernel.dk> (raw)
In-Reply-To: <c5daca6a-dedd-4d6a-a30c-00b7b942d1eb@gmail.com>
On 2/17/25 7:08 AM, Pavel Begunkov wrote:
> On 2/17/25 13:58, Jens Axboe wrote:
>> On 2/17/25 6:37 AM, Pavel Begunkov wrote:
>>
>> The kiocb semantics of ki_complete == NULL -> sync kiocb is also odd,
>
> That's what is_sync_kiocb() does. Would be cleaner to use
> init_sync_kiocb(), but there is a larger chance to do sth
> wrong as it's reinitialises it entirely.
Sorry if that wasn't clear, yeah I do realize this is what
is_sync_kiocb() checks. I do agree that manually clearing is saner.
>> but probably fine for this case as read mshot strictly deals with
>> pollable files. Otherwise you'd just be blocking off this issue,
>> regardless of whether or not IOCB_NOWAIT is set.
>>
>> In any case, it'd be much nicer to container this in io_read_mshot()
>> where it arguably belongs, rather than sprinkle it in __io_read().
>> Possible?
>
> That's what I tried first, but __io_read() -> io_rw_init_file()
> reinitialises it, so I don't see any good way without some
> broader refactoring.
Would it be bad? The only reason the kiocb init part is in there is
because of the ->iopoll() check, that could still be there with the rest
of the init going into normal prep (as it arguably should).
Something like the below, totally untested...
diff --git a/io_uring/rw.c b/io_uring/rw.c
index 16f12f94943f..f8dd9a9fe9ca 100644
--- a/io_uring/rw.c
+++ b/io_uring/rw.c
@@ -264,6 +264,9 @@ static int io_prep_rw_pi(struct io_kiocb *req, struct io_rw *rw, int ddir,
return ret;
}
+static void io_complete_rw(struct kiocb *kiocb, long res);
+static void io_complete_rw_iopoll(struct kiocb *kiocb, long res);
+
static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe,
int ddir, bool do_import)
{
@@ -288,6 +291,18 @@ static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe,
}
rw->kiocb.dio_complete = NULL;
rw->kiocb.ki_flags = 0;
+ if (req->ctx->flags & IORING_SETUP_IOPOLL) {
+ if (!(rw->kiocb.ki_flags & IOCB_DIRECT))
+ return -EOPNOTSUPP;
+
+ rw->kiocb.private = NULL;
+ rw->kiocb.ki_flags |= IOCB_HIPRI;
+ rw->kiocb.ki_complete = io_complete_rw_iopoll;
+ } else {
+ if (rw->kiocb.ki_flags & IOCB_HIPRI)
+ return -EINVAL;
+ rw->kiocb.ki_complete = io_complete_rw;
+ }
rw->addr = READ_ONCE(sqe->addr);
rw->len = READ_ONCE(sqe->len);
@@ -810,23 +825,15 @@ static int io_rw_init_file(struct io_kiocb *req, fmode_t mode, int rw_type)
((file->f_flags & O_NONBLOCK && !(req->flags & REQ_F_SUPPORT_NOWAIT))))
req->flags |= REQ_F_NOWAIT;
- if (ctx->flags & IORING_SETUP_IOPOLL) {
- if (!(kiocb->ki_flags & IOCB_DIRECT) || !file->f_op->iopoll)
+ if (kiocb->ki_flags & IOCB_HIPRI) {
+ if (!file->f_op->iopoll)
return -EOPNOTSUPP;
-
- kiocb->private = NULL;
- kiocb->ki_flags |= IOCB_HIPRI;
- kiocb->ki_complete = io_complete_rw_iopoll;
req->iopoll_completed = 0;
if (ctx->flags & IORING_SETUP_HYBRID_IOPOLL) {
/* make sure every req only blocks once*/
req->flags &= ~REQ_F_IOPOLL_STATE;
req->iopoll_start = ktime_get_ns();
}
- } else {
- if (kiocb->ki_flags & IOCB_HIPRI)
- return -EINVAL;
- kiocb->ki_complete = io_complete_rw;
}
if (req->flags & REQ_F_HAS_METADATA) {
--
Jens Axboe
next prev parent reply other threads:[~2025-02-17 15:37 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-17 13:37 [PATCH 1/1] io_uring/rw: forbid multishot async reads Pavel Begunkov
2025-02-17 13:49 ` Pavel Begunkov
2025-02-17 13:58 ` Jens Axboe
2025-02-17 14:03 ` Pavel Begunkov
2025-02-17 14:04 ` Pavel Begunkov
2025-02-17 14:08 ` Pavel Begunkov
2025-02-17 15:37 ` Jens Axboe [this message]
2025-02-19 1:35 ` Pavel Begunkov
2025-02-17 14:12 ` Pavel Begunkov
2025-02-17 15:06 ` Jens Axboe
2025-02-17 15:33 ` Pavel Begunkov
2025-02-17 15:57 ` Jens Axboe
2025-02-17 17:51 ` 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 \
--in-reply-to=205ed24e-238f-497e-9990-6bcb08acaf61@kernel.dk \
--to=axboe@kernel.dk \
--cc=asml.silence@gmail.com \
--cc=io-uring@vger.kernel.org \
/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.