io_uring/kbuf: switch to storing struct io_buffer_list locally
authorJens Axboe <axboe@kernel.dk>
Wed, 20 Aug 2025 17:21:08 +0000 (11:21 -0600)
committerJens Axboe <axboe@kernel.dk>
Thu, 21 Aug 2025 00:46:05 +0000 (18:46 -0600)
commit31771f6ca8f69c23a2e5ccfc6f61cea24deef842
treea1d5e250a3df013eb2455247c48b14f922920127
parentcb95450b2927365ad6ed4f0fee54f870ed72be6c
io_uring/kbuf: switch to storing struct io_buffer_list locally

Currently the buffer list is stored in struct io_kiocb. The buffer list
can be of two types:

1) Classic/legacy buffer list. These don't need to get referenced after
   a buffer pick, and hence storing them in struct io_kiocb is perfectly
   fine.

2) Ring provided buffer lists. These DO need to be referenced after the
   initial buffer pick, as they need to get consumed later on. This can
   be either just incrementing the head of the ring, or it can be
   consuming parts of a buffer if incremental buffer consumptions has
   been configured.

For case 2, io_uring needs to be careful not to access the buffer list
after the initial pick-and-execute context. The core does recycling of
these, but it's easy to make a mistake, because it's stored in the
io_kiocb which does persist across multiple execution contexts. Either
because it's a multishot request, or simply because it needed some kind
of async trigger (eg poll) for retry purposes.

Add a struct io_buffer_list to struct io_br_sel, which is always on
stack for the various users of it. This prevents the buffer list from
leaking outside of that execution context, and additionally it enables
kbuf to not even pass back the struct io_buffer_list if the given
context isn't appropriately locked already.

This doesn't fix any bugs, it's simply a defensive measure to prevent
any issues with reuse of a buffer list.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
include/linux/io_uring_types.h
io_uring/io_uring.c
io_uring/kbuf.c
io_uring/kbuf.h
io_uring/net.c
io_uring/poll.c
io_uring/rw.c