diff mbox series

[v2] io_uring: commit non-pollable provided mapped buffers upfront

Message ID 43b88754-a171-e871-5418-1ce53055c715@kernel.dk (mailing list archive)
State New
Headers show
Series [v2] io_uring: commit non-pollable provided mapped buffers upfront | expand

Commit Message

Jens Axboe June 16, 2022, 12:34 p.m. UTC
For recv/recvmsg, IO either completes immediately or gets queued for a
retry. This isn't the case for read/readv, if eg a normal file or a block
device is used. Here, an operation can get queued with the block layer.
If this happens, ring mapped buffers must get committed immediately to
avoid that the next read can consume the same buffer.

Check if we're dealing with pollable file, when getting a new ring mapped
provided buffer. If it's not, commit it immediately rather than wait post
issue. If we don't wait, we can race with completions coming in, or just
plain buffer reuse by committing after a retry where others could have
grabbed the same buffer.

Fixes: c7fb19428d67 ("io_uring: add support for ring mapped supplied buffers")
Signed-off-by: Jens Axboe <axboe@kernel.dk>

---

Comments

Hao Xu June 16, 2022, 1:13 p.m. UTC | #1
On 6/16/22 20:34, Jens Axboe wrote:
> For recv/recvmsg, IO either completes immediately or gets queued for a
> retry. This isn't the case for read/readv, if eg a normal file or a block
> device is used. Here, an operation can get queued with the block layer.
> If this happens, ring mapped buffers must get committed immediately to
> avoid that the next read can consume the same buffer.
> 
> Check if we're dealing with pollable file, when getting a new ring mapped
> provided buffer. If it's not, commit it immediately rather than wait post
> issue. If we don't wait, we can race with completions coming in, or just
> plain buffer reuse by committing after a retry where others could have
> grabbed the same buffer.
> 
> Fixes: c7fb19428d67 ("io_uring: add support for ring mapped supplied buffers")
> Signed-off-by: Jens Axboe <axboe@kernel.dk>
> 
> ---
> 
> diff --git a/fs/io_uring.c b/fs/io_uring.c
> index 5d479428d8e5..b6e75f69c6b1 100644
> --- a/fs/io_uring.c
> +++ b/fs/io_uring.c
> @@ -3836,7 +3836,7 @@ static void __user *io_ring_buffer_select(struct io_kiocb *req, size_t *len,
>   	req->buf_list = bl;
>   	req->buf_index = buf->bid;
>   
> -	if (issue_flags & IO_URING_F_UNLOCKED) {
> +	if (issue_flags & IO_URING_F_UNLOCKED || !file_can_poll(req->file)) {
>   		/*
>   		 * If we came in unlocked, we have no choice but to consume the
>   		 * buffer here. This does mean it'll be pinned until the IO
> 

Looks good,
Reviewed-by: Hao Xu <howeyxu@tencent.com>
diff mbox series

Patch

diff --git a/fs/io_uring.c b/fs/io_uring.c
index 5d479428d8e5..b6e75f69c6b1 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -3836,7 +3836,7 @@  static void __user *io_ring_buffer_select(struct io_kiocb *req, size_t *len,
 	req->buf_list = bl;
 	req->buf_index = buf->bid;
 
-	if (issue_flags & IO_URING_F_UNLOCKED) {
+	if (issue_flags & IO_URING_F_UNLOCKED || !file_can_poll(req->file)) {
 		/*
 		 * If we came in unlocked, we have no choice but to consume the
 		 * buffer here. This does mean it'll be pinned until the IO