From 7b3e5ce0b3d3e6c8e24dd147d23eec3fe5088d74 Mon Sep 17 00:00:00 2001 From: Vincent Rischmann Date: Thu, 12 May 2022 13:28:34 +0200 Subject: [PATCH] io_uring: add provide_buffers and remove_buffers These functions are needed to implement automatic buffer selection. This maps to the IORING_OP_PROVIDE_BUFFERS and IORING_OP_PROVIDE_BUFFERS ops. --- lib/std/os/linux/io_uring.zig | 57 +++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/lib/std/os/linux/io_uring.zig b/lib/std/os/linux/io_uring.zig index be8b442611..9646a923d7 100644 --- a/lib/std/os/linux/io_uring.zig +++ b/lib/std/os/linux/io_uring.zig @@ -857,6 +857,41 @@ pub const IO_Uring = struct { return sqe; } + /// Queues (but does not submit) an SQE to provide a group of buffers used for commands that read/receive data. + /// Returns a pointer to the SQE. + /// + /// Provided buffers can be used in `read`, `recv` or `recvmsg` commands via .buffer_selection. + /// + /// The kernel expects a contiguous block of memory of size (buffers_count * buffer_size). + pub fn provide_buffers( + self: *IO_Uring, + user_data: u64, + buffers: [*]u8, + buffers_count: usize, + buffer_size: usize, + group_id: usize, + buffer_id: usize, + ) !*io_uring_sqe { + const sqe = try self.get_sqe(); + io_uring_prep_provide_buffers(sqe, buffers, buffers_count, buffer_size, group_id, buffer_id); + sqe.user_data = user_data; + return sqe; + } + + /// Queues (but does not submit) an SQE to remove a group of provided buffers. + /// Returns a pointer to the SQE. + pub fn remove_buffers( + self: *IO_Uring, + user_data: u64, + buffers_count: usize, + group_id: usize, + ) !*io_uring_sqe { + const sqe = try self.get_sqe(); + io_uring_prep_remove_buffers(sqe, buffers_count, group_id); + sqe.user_data = user_data; + return sqe; + } + /// Registers an array of file descriptors. /// Every time a file descriptor is put in an SQE and submitted to the kernel, the kernel must /// retrieve a reference to the file, and once I/O has completed the file reference must be @@ -1508,6 +1543,28 @@ pub fn io_uring_prep_linkat( sqe.rw_flags = flags; } +pub fn io_uring_prep_provide_buffers( + sqe: *io_uring_sqe, + buffers: [*]u8, + num: usize, + buffer_len: usize, + group_id: usize, + buffer_id: usize, +) void { + const ptr = @ptrToInt(buffers); + io_uring_prep_rw(.PROVIDE_BUFFERS, sqe, @intCast(i32, num), ptr, buffer_len, buffer_id); + sqe.buf_index = @intCast(u16, group_id); +} + +pub fn io_uring_prep_remove_buffers( + sqe: *io_uring_sqe, + num: usize, + group_id: usize, +) void { + io_uring_prep_rw(.REMOVE_BUFFERS, sqe, @intCast(i32, num), 0, 0, 0); + sqe.buf_index = @intCast(u16, group_id); +} + test "structs/offsets/entries" { if (builtin.os.tag != .linux) return error.SkipZigTest;