io_uring: ring mapped buffers (#17806)
* io_uring: ring mapped buffers Ring mapped buffers are newer implementation of ring provided buffers, supported since kernel 5.19. Best described in Jens Axboe [post](https://github.com/axboe/liburing/wiki/io_uring-and-networking-in-2023#provided-buffers) This commit implements low level io_uring_*_buf_ring_* functions as mostly direct translation from liburing. It also adds BufferGroup abstraction over those low level functions. * io_uring: add multishot recv to BufferGroup Once we have ring mapped provided buffers functionality it is possible to use multishot recv operation. Multishot receive is submitted once, and completions are posted whenever data arrives on the socket. Received data are placed in a new buffer from buffer group. Reference: [io_uring and networking in 2023](https://github.com/axboe/liburing/wiki/io_uring-and-networking-in-2023#multi-shot) Getting NOENT for cancel completion result, meaning: -ENOENT The request identified by user_data could not be located. This could be because it completed before the cancelation request was issued, or if an invalid identifier is used. https://man7.org/linux/man-pages/man3/io_uring_prep_cancel.3.html https://github.com/ziglang/zig/actions/runs/6801394000/job/18492139893?pr=17806 Result in cancel/recv cqes are different depending on the kernel. on older kernel (tested with v6.0.16, v6.1.57, v6.2.12, v6.4.16) cqe_cancel.err() == .NOENT cqe_crecv.err() == .NOBUFS on kernel (tested with v6.5.0, v6.5.7) cqe_cancel.err() == .SUCCESS cqe_crecv.err() == .CANCELED
This commit is contained in:
@@ -4387,6 +4387,16 @@ pub const io_uring_cqe = extern struct {
|
||||
}
|
||||
return .SUCCESS;
|
||||
}
|
||||
|
||||
// On successful completion of the provided buffers IO request, the CQE flags field
|
||||
// will have IORING_CQE_F_BUFFER set and the selected buffer ID will be indicated by
|
||||
// the upper 16-bits of the flags field.
|
||||
pub fn buffer_id(self: io_uring_cqe) !u16 {
|
||||
if (self.flags & IORING_CQE_F_BUFFER != IORING_CQE_F_BUFFER) {
|
||||
return error.NoBufferSelected;
|
||||
}
|
||||
return @as(u16, @intCast(self.flags >> IORING_CQE_BUFFER_SHIFT));
|
||||
}
|
||||
};
|
||||
|
||||
// io_uring_cqe.flags
|
||||
@@ -4667,8 +4677,12 @@ pub const io_uring_buf = extern struct {
|
||||
resv: u16,
|
||||
};
|
||||
|
||||
// io_uring_buf_ring struct omitted
|
||||
// it's a io_uring_buf array with the resv of the first item used as a "tail" field.
|
||||
pub const io_uring_buf_ring = extern struct {
|
||||
resv1: u64,
|
||||
resv2: u32,
|
||||
resv3: u16,
|
||||
tail: u16,
|
||||
};
|
||||
|
||||
/// argument for IORING_(UN)REGISTER_PBUF_RING
|
||||
pub const io_uring_buf_reg = extern struct {
|
||||
|
||||
Reference in New Issue
Block a user