io_uring/register: add support for ring -> ring channels
Add support for a unidirectional communication channel from one ring to
another. While IORING_OP_MSG_RING already supports some notion of
communicating between rings, it works by submitting task_work between
rings. This isn't very efficient, and is also a bit wonky in how
io_kiocb requests need to be faked to accomplish that goal.
An io_uring channel is a single unidirectional ring, with a specific
single producer (the source ring) and a specific single consumer (the
target ring). Messages added to the target ring will treated like
task_work in that it'll be checked for like local task_work, and flushed
like local task_work. Anything added to the channel will be turned into
CQEs posted on the target ring CQ ring.
If IORING_CHAN_REG_BIDI is set in the registration flags, then two
channels will be setup - one in each direction. This allows for
responses from one channel to be posted on the other channel.
IORING_REGISTER_ADD_CHAN adds a new channel (or pair of channels),
and takes a pointer to the following structure as the argument:
struct io_uring_chan_reg {
__u32 flags;
__u32 dst_fd;
__u32 nentries;
__u32 resv[7];
};
where 'flags' must be 0 or set to IORING_CHAN_REG_BIDI, 'dst_fd' is the
file descriptor for the target ring, and 'nentries' is the number of
entries that the channel should be able to hold. Channel messages are
flushed like task_work, and hence generally a lot won't be required.
'nentries' must be a power-of-2 value.
Signed-off-by: Jens Axboe <axboe@kernel.dk>