* [PATCH 0/2] io_uring: mshot read fix for buffer size changes @ 2023-11-05 22:30 Dylan Yudaken 2023-11-05 22:30 ` [PATCH 1/2] io_uring: do not allow multishot read to set addr or len Dylan Yudaken ` (2 more replies) 0 siblings, 3 replies; 11+ messages in thread From: Dylan Yudaken @ 2023-11-05 22:30 UTC (permalink / raw) To: io-uring; +Cc: axboe, asml.silence, Dylan Yudaken Hi, This series fixes a bug (will send a liburing patch separately showing it) where the used buffer size is clamped to the minimum of all the previous buffers selected. It also as part of this forces the multishot read API to set addr & len to 0. len should probably have some accounting post-processing if it has meaning to set it to non-zero, but I think for a new API it is simpler to overly-constrain it upfront? addr is useful to force to zero as it will allow some more bits to be used in `struct io_rw`, which is otherwise full. Dylan Yudaken (2): io_uring: do not allow multishot read to set addr or len io_uring: do not clamp read length for multishot read io_uring/rw.c | 9 +++++++++ 1 file changed, 9 insertions(+) -- 2.41.0 ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/2] io_uring: do not allow multishot read to set addr or len 2023-11-05 22:30 [PATCH 0/2] io_uring: mshot read fix for buffer size changes Dylan Yudaken @ 2023-11-05 22:30 ` Dylan Yudaken 2023-11-06 14:32 ` Jens Axboe 2023-11-05 22:30 ` [PATCH 2/2] io_uring: do not clamp read length for multishot read Dylan Yudaken 2023-11-06 20:35 ` [PATCH 0/2] io_uring: mshot read fix for buffer size changes Jens Axboe 2 siblings, 1 reply; 11+ messages in thread From: Dylan Yudaken @ 2023-11-05 22:30 UTC (permalink / raw) To: io-uring; +Cc: axboe, asml.silence, Dylan Yudaken For addr: this field is not used, since buffer select is forced. But by forcing it to be zero it leaves open future uses of the field. len is actually usable, you could imagine that you want to receive multishot up to a certain length. However right now this is not how it is implemented, and it seems safer to force this to be zero. Fixes: fc68fcda0491 ("io_uring/rw: add support for IORING_OP_READ_MULTISHOT") Signed-off-by: Dylan Yudaken <[email protected]> --- io_uring/rw.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/io_uring/rw.c b/io_uring/rw.c index 1c76de483ef6..ea86498d8769 100644 --- a/io_uring/rw.c +++ b/io_uring/rw.c @@ -111,6 +111,13 @@ int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe) rw->len = READ_ONCE(sqe->len); rw->flags = READ_ONCE(sqe->rw_flags); + if (req->opcode == IORING_OP_READ_MULTISHOT) { + if (rw->addr) + return -EINVAL; + if (rw->len) + return -EINVAL; + } + /* Have to do this validation here, as this is in io_read() rw->len might * have chanaged due to buffer selection */ -- 2.41.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 1/2] io_uring: do not allow multishot read to set addr or len 2023-11-05 22:30 ` [PATCH 1/2] io_uring: do not allow multishot read to set addr or len Dylan Yudaken @ 2023-11-06 14:32 ` Jens Axboe 2023-11-06 14:51 ` Jens Axboe 0 siblings, 1 reply; 11+ messages in thread From: Jens Axboe @ 2023-11-06 14:32 UTC (permalink / raw) To: Dylan Yudaken, io-uring; +Cc: asml.silence On 11/5/23 3:30 PM, Dylan Yudaken wrote: > For addr: this field is not used, since buffer select is forced. But by forcing > it to be zero it leaves open future uses of the field. > > len is actually usable, you could imagine that you want to receive > multishot up to a certain length. > However right now this is not how it is implemented, and it seems > safer to force this to be zero. > > Fixes: fc68fcda0491 ("io_uring/rw: add support for IORING_OP_READ_MULTISHOT") > Signed-off-by: Dylan Yudaken <[email protected]> > --- > io_uring/rw.c | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/io_uring/rw.c b/io_uring/rw.c > index 1c76de483ef6..ea86498d8769 100644 > --- a/io_uring/rw.c > +++ b/io_uring/rw.c > @@ -111,6 +111,13 @@ int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe) > rw->len = READ_ONCE(sqe->len); > rw->flags = READ_ONCE(sqe->rw_flags); > > + if (req->opcode == IORING_OP_READ_MULTISHOT) { > + if (rw->addr) > + return -EINVAL; > + if (rw->len) > + return -EINVAL; > + } Should we just put these in io_read_mshot_prep() instead? Ala the below. In general I think it'd be nice to have a core prep_rw, and then each variant will have its own prep. Then we can get away from random opcode checking in there. I do agree with the change in general, just think we can tweak it a bit to make it a bit cleaner. diff --git a/io_uring/rw.c b/io_uring/rw.c index 1c76de483ef6..635a1bf5df70 100644 --- a/io_uring/rw.c +++ b/io_uring/rw.c @@ -129,6 +129,7 @@ int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe) */ int io_read_mshot_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) { + struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw); int ret; /* must be used with provided buffers */ @@ -139,6 +140,9 @@ int io_read_mshot_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) if (unlikely(ret)) return ret; + if (rw->addr || rw->len) + return -EINVAL; + req->flags |= REQ_F_APOLL_MULTISHOT; return 0; } -- Jens Axboe ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 1/2] io_uring: do not allow multishot read to set addr or len 2023-11-06 14:32 ` Jens Axboe @ 2023-11-06 14:51 ` Jens Axboe 2023-11-06 15:31 ` Dylan Yudaken 0 siblings, 1 reply; 11+ messages in thread From: Jens Axboe @ 2023-11-06 14:51 UTC (permalink / raw) To: Dylan Yudaken, io-uring; +Cc: asml.silence On 11/6/23 7:32 AM, Jens Axboe wrote: > On 11/5/23 3:30 PM, Dylan Yudaken wrote: >> For addr: this field is not used, since buffer select is forced. But by forcing >> it to be zero it leaves open future uses of the field. >> >> len is actually usable, you could imagine that you want to receive >> multishot up to a certain length. >> However right now this is not how it is implemented, and it seems >> safer to force this to be zero. >> >> Fixes: fc68fcda0491 ("io_uring/rw: add support for IORING_OP_READ_MULTISHOT") >> Signed-off-by: Dylan Yudaken <[email protected]> >> --- >> io_uring/rw.c | 7 +++++++ >> 1 file changed, 7 insertions(+) >> >> diff --git a/io_uring/rw.c b/io_uring/rw.c >> index 1c76de483ef6..ea86498d8769 100644 >> --- a/io_uring/rw.c >> +++ b/io_uring/rw.c >> @@ -111,6 +111,13 @@ int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe) >> rw->len = READ_ONCE(sqe->len); >> rw->flags = READ_ONCE(sqe->rw_flags); >> >> + if (req->opcode == IORING_OP_READ_MULTISHOT) { >> + if (rw->addr) >> + return -EINVAL; >> + if (rw->len) >> + return -EINVAL; >> + } > > Should we just put these in io_read_mshot_prep() instead? Ala the below. > In general I think it'd be nice to have a core prep_rw, and then each > variant will have its own prep. Then we can get away from random opcode > checking in there. > > I do agree with the change in general, just think we can tweak it a bit > to make it a bit cleaner. Sent out two cleanups that take it in this direction in general, fwiw. -- Jens Axboe ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/2] io_uring: do not allow multishot read to set addr or len 2023-11-06 14:51 ` Jens Axboe @ 2023-11-06 15:31 ` Dylan Yudaken 0 siblings, 0 replies; 11+ messages in thread From: Dylan Yudaken @ 2023-11-06 15:31 UTC (permalink / raw) To: Jens Axboe; +Cc: io-uring, asml.silence On Mon, Nov 6, 2023 at 2:51 PM Jens Axboe <[email protected]> wrote: > > On 11/6/23 7:32 AM, Jens Axboe wrote: > > On 11/5/23 3:30 PM, Dylan Yudaken wrote: > >> For addr: this field is not used, since buffer select is forced. But by forcing > >> it to be zero it leaves open future uses of the field. > >> > >> len is actually usable, you could imagine that you want to receive > >> multishot up to a certain length. > >> However right now this is not how it is implemented, and it seems > >> safer to force this to be zero. > >> > >> Fixes: fc68fcda0491 ("io_uring/rw: add support for IORING_OP_READ_MULTISHOT") > >> Signed-off-by: Dylan Yudaken <[email protected]> > >> --- > >> io_uring/rw.c | 7 +++++++ > >> 1 file changed, 7 insertions(+) > >> > >> diff --git a/io_uring/rw.c b/io_uring/rw.c > >> index 1c76de483ef6..ea86498d8769 100644 > >> --- a/io_uring/rw.c > >> +++ b/io_uring/rw.c > >> @@ -111,6 +111,13 @@ int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe) > >> rw->len = READ_ONCE(sqe->len); > >> rw->flags = READ_ONCE(sqe->rw_flags); > >> > >> + if (req->opcode == IORING_OP_READ_MULTISHOT) { > >> + if (rw->addr) > >> + return -EINVAL; > >> + if (rw->len) > >> + return -EINVAL; > >> + } > > > > Should we just put these in io_read_mshot_prep() instead? Ala the below. > > In general I think it'd be nice to have a core prep_rw, and then each > > variant will have its own prep. Then we can get away from random opcode > > checking in there. > > > > I do agree with the change in general, just think we can tweak it a bit > > to make it a bit cleaner. > > Sent out two cleanups that take it in this direction in general, fwiw. Yes - I think this approach is better, will rebase on these ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 2/2] io_uring: do not clamp read length for multishot read 2023-11-05 22:30 [PATCH 0/2] io_uring: mshot read fix for buffer size changes Dylan Yudaken 2023-11-05 22:30 ` [PATCH 1/2] io_uring: do not allow multishot read to set addr or len Dylan Yudaken @ 2023-11-05 22:30 ` Dylan Yudaken 2023-11-06 14:46 ` Jens Axboe 2023-11-06 20:35 ` [PATCH 0/2] io_uring: mshot read fix for buffer size changes Jens Axboe 2 siblings, 1 reply; 11+ messages in thread From: Dylan Yudaken @ 2023-11-05 22:30 UTC (permalink / raw) To: io-uring; +Cc: axboe, asml.silence, Dylan Yudaken When doing a multishot read, the code path reuses the old read paths. However this breaks an assumption built into those paths, namely that struct io_rw::len is available for reuse by __io_import_iovec. For multishot this results in len being set for the first receive call, and then subsequent calls are clamped to that buffer length incorrectly. Fixes: fc68fcda0491 ("io_uring/rw: add support for IORING_OP_READ_MULTISHOT") Signed-off-by: Dylan Yudaken <[email protected]> --- io_uring/rw.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/io_uring/rw.c b/io_uring/rw.c index ea86498d8769..b7f7fbc28032 100644 --- a/io_uring/rw.c +++ b/io_uring/rw.c @@ -417,6 +417,8 @@ static struct iovec *__io_import_iovec(int ddir, struct io_kiocb *req, if (!io_issue_defs[opcode].vectored || req->flags & REQ_F_BUFFER_SELECT) { if (io_do_buffer_select(req)) { + if (opcode == IORING_OP_READ_MULTISHOT) + sqe_len = 0; buf = io_buffer_select(req, &sqe_len, issue_flags); if (!buf) return ERR_PTR(-ENOBUFS); -- 2.41.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] io_uring: do not clamp read length for multishot read 2023-11-05 22:30 ` [PATCH 2/2] io_uring: do not clamp read length for multishot read Dylan Yudaken @ 2023-11-06 14:46 ` Jens Axboe 2023-11-06 15:33 ` Dylan Yudaken 0 siblings, 1 reply; 11+ messages in thread From: Jens Axboe @ 2023-11-06 14:46 UTC (permalink / raw) To: Dylan Yudaken, io-uring; +Cc: asml.silence On 11/5/23 3:30 PM, Dylan Yudaken wrote: > When doing a multishot read, the code path reuses the old read > paths. However this breaks an assumption built into those paths, > namely that struct io_rw::len is available for reuse by __io_import_iovec. > > For multishot this results in len being set for the first receive > call, and then subsequent calls are clamped to that buffer length incorrectly. Should we just reset this to 0 always in io_read_mshot()? And preferably with a comment added as well as to why that is necessary to avoid repeated clamping. -- Jens Axboe ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] io_uring: do not clamp read length for multishot read 2023-11-06 14:46 ` Jens Axboe @ 2023-11-06 15:33 ` Dylan Yudaken 2023-11-06 15:46 ` Jens Axboe 0 siblings, 1 reply; 11+ messages in thread From: Dylan Yudaken @ 2023-11-06 15:33 UTC (permalink / raw) To: Jens Axboe; +Cc: io-uring, asml.silence On Mon, Nov 6, 2023 at 2:46 PM Jens Axboe <[email protected]> wrote: > > On 11/5/23 3:30 PM, Dylan Yudaken wrote: > > When doing a multishot read, the code path reuses the old read > > paths. However this breaks an assumption built into those paths, > > namely that struct io_rw::len is available for reuse by __io_import_iovec. > > > > For multishot this results in len being set for the first receive > > call, and then subsequent calls are clamped to that buffer length incorrectly. > > Should we just reset this to 0 always in io_read_mshot()? And preferably > with a comment added as well as to why that is necessary to avoid > repeated clamping. Unfortunately I don't think (without testing) that will work. Sometimes the request comes into io_read_mshot with the buffer already selected, and the length cannot be touched in that case. We could check if the buffer is set, and if not clear the length I guess. I'm a bit unsure which is better - both seem equally ugly to be honest. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] io_uring: do not clamp read length for multishot read 2023-11-06 15:33 ` Dylan Yudaken @ 2023-11-06 15:46 ` Jens Axboe 2023-11-06 17:56 ` Jens Axboe 0 siblings, 1 reply; 11+ messages in thread From: Jens Axboe @ 2023-11-06 15:46 UTC (permalink / raw) To: Dylan Yudaken; +Cc: io-uring, asml.silence On 11/6/23 8:33 AM, Dylan Yudaken wrote: > On Mon, Nov 6, 2023 at 2:46?PM Jens Axboe <[email protected]> wrote: >> >> On 11/5/23 3:30 PM, Dylan Yudaken wrote: >>> When doing a multishot read, the code path reuses the old read >>> paths. However this breaks an assumption built into those paths, >>> namely that struct io_rw::len is available for reuse by __io_import_iovec. >>> >>> For multishot this results in len being set for the first receive >>> call, and then subsequent calls are clamped to that buffer length incorrectly. >> >> Should we just reset this to 0 always in io_read_mshot()? And preferably >> with a comment added as well as to why that is necessary to avoid >> repeated clamping. > > Unfortunately I don't think (without testing) that will work. > Sometimes the request > comes into io_read_mshot with the buffer already selected, and the > length cannot > be touched in that case. > > We could check if the buffer is set, and if not clear the length I guess. > I'm a bit unsure which is better - both seem equally ugly to be honest. I mean do it at the end when we complete it, so it's reset for the next iteration. But yeah, I'd want to have the test case verify this first :-) -- Jens Axboe ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] io_uring: do not clamp read length for multishot read 2023-11-06 15:46 ` Jens Axboe @ 2023-11-06 17:56 ` Jens Axboe 0 siblings, 0 replies; 11+ messages in thread From: Jens Axboe @ 2023-11-06 17:56 UTC (permalink / raw) To: Dylan Yudaken; +Cc: io-uring, asml.silence On 11/6/23 8:46 AM, Jens Axboe wrote: > On 11/6/23 8:33 AM, Dylan Yudaken wrote: >> On Mon, Nov 6, 2023 at 2:46?PM Jens Axboe <[email protected]> wrote: >>> >>> On 11/5/23 3:30 PM, Dylan Yudaken wrote: >>>> When doing a multishot read, the code path reuses the old read >>>> paths. However this breaks an assumption built into those paths, >>>> namely that struct io_rw::len is available for reuse by __io_import_iovec. >>>> >>>> For multishot this results in len being set for the first receive >>>> call, and then subsequent calls are clamped to that buffer length incorrectly. >>> >>> Should we just reset this to 0 always in io_read_mshot()? And preferably >>> with a comment added as well as to why that is necessary to avoid >>> repeated clamping. >> >> Unfortunately I don't think (without testing) that will work. >> Sometimes the request >> comes into io_read_mshot with the buffer already selected, and the >> length cannot >> be touched in that case. >> >> We could check if the buffer is set, and if not clear the length I guess. >> I'm a bit unsure which is better - both seem equally ugly to be honest. > > I mean do it at the end when we complete it, so it's reset for the next > iteration. But yeah, I'd want to have the test case verify this first > :-) Something ala the below? diff --git a/io_uring/rw.c b/io_uring/rw.c index 9e3e56b74e35..9121832eadec 100644 --- a/io_uring/rw.c +++ b/io_uring/rw.c @@ -932,6 +932,12 @@ int io_read_mshot(struct io_kiocb *req, unsigned int issue_flags) * Any successful return value will keep the multishot read armed. */ if (ret > 0) { + /* + * Reset rw->len to 0 again to avoid clamping future mshot + * reads, in case the buffer size varies. + */ + io_kiocb_to_cmd(req, struct io_rw)->len = 0; + /* * Put our buffer and post a CQE. If we fail to post a CQE, then * jump to the termination path. This request is then done. -- Jens Axboe ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 0/2] io_uring: mshot read fix for buffer size changes 2023-11-05 22:30 [PATCH 0/2] io_uring: mshot read fix for buffer size changes Dylan Yudaken 2023-11-05 22:30 ` [PATCH 1/2] io_uring: do not allow multishot read to set addr or len Dylan Yudaken 2023-11-05 22:30 ` [PATCH 2/2] io_uring: do not clamp read length for multishot read Dylan Yudaken @ 2023-11-06 20:35 ` Jens Axboe 2 siblings, 0 replies; 11+ messages in thread From: Jens Axboe @ 2023-11-06 20:35 UTC (permalink / raw) To: Dylan Yudaken, io-uring; +Cc: asml.silence On 11/5/23 3:30 PM, Dylan Yudaken wrote: > Hi, > > This series fixes a bug (will send a liburing patch separately showing > it) where the used buffer size is clamped to the minimum of all the > previous buffers selected. Oh, if you have time and once we get v2 in, maybe send a patch for liburing as well to remove 'nbytes' from io_uring_prep_read_multishot() as well? -- Jens Axboe ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2023-11-06 20:35 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-11-05 22:30 [PATCH 0/2] io_uring: mshot read fix for buffer size changes Dylan Yudaken 2023-11-05 22:30 ` [PATCH 1/2] io_uring: do not allow multishot read to set addr or len Dylan Yudaken 2023-11-06 14:32 ` Jens Axboe 2023-11-06 14:51 ` Jens Axboe 2023-11-06 15:31 ` Dylan Yudaken 2023-11-05 22:30 ` [PATCH 2/2] io_uring: do not clamp read length for multishot read Dylan Yudaken 2023-11-06 14:46 ` Jens Axboe 2023-11-06 15:33 ` Dylan Yudaken 2023-11-06 15:46 ` Jens Axboe 2023-11-06 17:56 ` Jens Axboe 2023-11-06 20:35 ` [PATCH 0/2] io_uring: mshot read fix for buffer size changes Jens Axboe
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox