Fixes for the provided buffers for not allowing kbufs to cross a single execution section. Upstream had most of it already fixed by chance, which is why all 3 patches refer to a single upstream commit.
Pavel Begunkov (3): io_uring: fix multishots with selected buffers io_uring: fix io_req_prep_async with provided buffers io_uring/rw: commit provided buffer state on async
io_uring/io_uring.c | 5 ++++- io_uring/poll.c | 2 ++ io_uring/rw.c | 10 ++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-)
[ upstream commit d63b0e8a628e62ca85a0f7915230186bb92f8bb4 ]
We do io_kbuf_recycle() when arming a poll but every iteration of a multishot can grab more buffers, which is why we need to flush the kbuf ring state before continuing with waiting.
Cc: stable@vger.kernel.org Fixes: b3fdea6ecb55c ("io_uring: multishot recv") Reported-by: Muhammad Ramdhan ramdhan@starlabs.sg Reported-by: Bing-Jhong Billy Jheng billy@starlabs.sg Reported-by: Jacob Soo jacob.soo@starlabs.sg Signed-off-by: Pavel Begunkov asml.silence@gmail.com Link: https://lore.kernel.org/r/1bfc9990fe435f1fc6152ca9efeba5eb3e68339c.173802557... Signed-off-by: Jens Axboe axboe@kernel.dk --- io_uring/poll.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/io_uring/poll.c b/io_uring/poll.c index 5cf4fffe8b6c..2824a3560245 100644 --- a/io_uring/poll.c +++ b/io_uring/poll.c @@ -350,8 +350,10 @@ void io_poll_task_func(struct io_kiocb *req, struct io_tw_state *ts)
ret = io_poll_check_events(req, ts); if (ret == IOU_POLL_NO_ACTION) { + io_kbuf_recycle(req, 0); return; } else if (ret == IOU_POLL_REQUEUE) { + io_kbuf_recycle(req, 0); __io_poll_execute(req, 0); return; }
On Mon, Feb 10, 2025 at 03:21:36PM +0000, Pavel Begunkov wrote:
[ upstream commit d63b0e8a628e62ca85a0f7915230186bb92f8bb4 ]
We do io_kbuf_recycle() when arming a poll but every iteration of a multishot can grab more buffers, which is why we need to flush the kbuf ring state before continuing with waiting.
Cc: stable@vger.kernel.org Fixes: b3fdea6ecb55c ("io_uring: multishot recv") Reported-by: Muhammad Ramdhan ramdhan@starlabs.sg Reported-by: Bing-Jhong Billy Jheng billy@starlabs.sg Reported-by: Jacob Soo jacob.soo@starlabs.sg Signed-off-by: Pavel Begunkov asml.silence@gmail.com Link: https://lore.kernel.org/r/1bfc9990fe435f1fc6152ca9efeba5eb3e68339c.173802557... Signed-off-by: Jens Axboe axboe@kernel.dk
io_uring/poll.c | 2 ++ 1 file changed, 2 insertions(+)
This is already in our 6.6.y queue, thanks!
greg k-h
[ upstream commit d63b0e8a628e62ca85a0f7915230186bb92f8bb4 ]
io_req_prep_async() can import provided buffers, commit the ring state by giving up on that before, it'll be reimported later if needed.
Reported-by: Muhammad Ramdhan ramdhan@starlabs.sg Reported-by: Bing-Jhong Billy Jheng billy@starlabs.sg Reported-by: Jacob Soo jacob.soo@starlabs.sg Fixes: c7fb19428d67d ("io_uring: add support for ring mapped supplied buffers") Signed-off-by: Pavel Begunkov asml.silence@gmail.com --- io_uring/io_uring.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index c7198fbcf734..b61637dad442 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -1779,6 +1779,7 @@ int io_req_prep_async(struct io_kiocb *req) { const struct io_cold_def *cdef = &io_cold_defs[req->opcode]; const struct io_issue_def *def = &io_issue_defs[req->opcode]; + int ret;
/* assign early for deferred execution for non-fixed file */ if (def->needs_file && !(req->flags & REQ_F_FIXED_FILE) && !req->file) @@ -1791,7 +1792,9 @@ int io_req_prep_async(struct io_kiocb *req) if (io_alloc_async_data(req)) return -EAGAIN; } - return cdef->prep_async(req); + ret = cdef->prep_async(req); + io_kbuf_recycle(req, 0); + return ret; }
static u32 io_get_sequence(struct io_kiocb *req)
On Mon, Feb 10, 2025 at 03:21:37PM +0000, Pavel Begunkov wrote:
[ upstream commit d63b0e8a628e62ca85a0f7915230186bb92f8bb4 ]
Nope, wrong git id :(
Can you redo this series with the right one?
thanks,
greg k-h
[ upstream commit d63b0e8a628e62ca85a0f7915230186bb92f8bb4 ]
When we get -EIOCBQUEUED, we need to ensure that the buffer is consumed from the provided buffer ring, which can be done with io_kbuf_recycle() + REQ_F_PARTIAL_IO.
Reported-by: Muhammad Ramdhan ramdhan@starlabs.sg Reported-by: Bing-Jhong Billy Jheng billy@starlabs.sg Reported-by: Jacob Soo jacob.soo@starlabs.sg Fixes: c7fb19428d67d ("io_uring: add support for ring mapped supplied buffers") Signed-off-by: Pavel Begunkov asml.silence@gmail.com --- io_uring/rw.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/io_uring/rw.c b/io_uring/rw.c index a62f84e28bac..75b001febb4d 100644 --- a/io_uring/rw.c +++ b/io_uring/rw.c @@ -793,6 +793,8 @@ static int __io_read(struct io_kiocb *req, unsigned int issue_flags) goto done; ret = 0; } else if (ret == -EIOCBQUEUED) { + req->flags |= REQ_F_PARTIAL_IO; + io_kbuf_recycle(req, issue_flags); if (iovec) kfree(iovec); return IOU_ISSUE_SKIP_COMPLETE; @@ -816,6 +818,9 @@ static int __io_read(struct io_kiocb *req, unsigned int issue_flags) goto done; }
+ req->flags |= REQ_F_PARTIAL_IO; + io_kbuf_recycle(req, issue_flags); + io = req->async_data; s = &io->s; /* @@ -956,6 +961,11 @@ int io_write(struct io_kiocb *req, unsigned int issue_flags) else ret2 = -EINVAL;
+ if (ret2 == -EIOCBQUEUED) { + req->flags |= REQ_F_PARTIAL_IO; + io_kbuf_recycle(req, issue_flags); + } + if (req->flags & REQ_F_REISSUE) { req->flags &= ~REQ_F_REISSUE; ret2 = -EAGAIN;
On Mon, Feb 10, 2025 at 03:21:38PM +0000, Pavel Begunkov wrote:
[ upstream commit d63b0e8a628e62ca85a0f7915230186bb92f8bb4 ]
Wrong commit id :(
Let me figure out what went wrong here...
On Mon, Feb 10, 2025 at 03:21:35PM +0000, Pavel Begunkov wrote:
Fixes for the provided buffers for not allowing kbufs to cross a single execution section. Upstream had most of it already fixed by chance, which is why all 3 patches refer to a single upstream commit.
Ah. Ok, that makes more sense, nevermind, I should have read patch 0/X first...
I'll drop the upstream commit reference here as it's just confusing.
thanks,
greg k-h
linux-stable-mirror@lists.linaro.org