io_uring: support SQE group io_uring-group
authorMing Lei <ming.lei@redhat.com>
Fri, 25 Oct 2024 12:22:41 +0000 (20:22 +0800)
committerJens Axboe <axboe@kernel.dk>
Fri, 1 Nov 2024 15:11:49 +0000 (09:11 -0600)
commita2a81f77e792828fb8e8888c201f2ff1448ecf06
tree23b16605e1e55086d2427b9848c0ad2e99beb505
parent62db18ef7237fef8c03edb11965d083d439c1a2b
io_uring: support SQE group

SQE group is defined as one chain of SQEs starting with the first SQE
that has IOSQE2_GROUP set, and ending with the first subsequent SQE
that doesn't have it set, and it is similar with chain of linked SQEs.

Not like linked SQEs, each sqe is issued after the previous one is
completed. All SQEs in one group can be submitted in parallel. To
simplify the implementation from beginning, all members are queued after
the leader is completed, however, this way may be changed and leader and
members may be issued concurrently in future.

The 1st SQE is group leader, and the other SQEs are group member. The
whole group share single IOSQE_IO_LINK and IOSQE_IO_DRAIN from group
leader, and the two flags can't be set for group members. For the sake
of simplicity, IORING_OP_LINK_TIMEOUT is disallowed for SQE group now.

When the group is in one link chain, this group isn't submitted until
the previous SQE or group is completed. And the following SQE or group
can't be started if this group isn't completed. Failure from any group
member will fail the group leader, then the link chain can be
terminated.

When IOSQE_IO_DRAIN is set for group leader, all requests in this group
and previous requests submitted are drained. Given IOSQE_IO_DRAIN can be
set for group leader only, we respect IO_DRAIN by always completing
group leader as the last one in the group. Meantime it is natural to
post leader's CQE as the last one from application viewpoint.

Working together with IOSQE_IO_LINK, SQE group provides flexible way to
support N:M dependency, such as:

- group A is chained with group B together
- group A has N SQEs
- group B has M SQEs

then M SQEs in group B depend on N SQEs in group A.

N:M dependency can support some interesting use cases in efficient way:

1) read from multiple files, then write the read data into single file

2) read from single file, and write the read data into multiple files

3) write same data into multiple files, and read data from multiple
   files and compare if correct data is written

IOSQE2_GROUP is the first flags2 bit. To use it, IOSQE_FLAGS2 must be
set in the sqe->flags member, and IOSQE2_GROUP set in the sqe->flags2
field.

Suggested-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Link: https://lore.kernel.org/r/20241025122247.3709133-5-ming.lei@redhat.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
include/linux/io_uring_types.h
include/uapi/linux/io_uring.h
io_uring/io_uring.c
io_uring/io_uring.h
io_uring/timeout.c