Skip to content

Commit

Permalink
io_uring: refactor buf_reg flags
Browse files Browse the repository at this point in the history
Use packed struct instead of or-ed integers.

Thanks to @linsug for pr comments: #23062
  • Loading branch information
ianic committed Mar 5, 2025
1 parent c133171 commit 94b36db
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 12 deletions.
19 changes: 12 additions & 7 deletions lib/std/os/linux.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6141,7 +6141,8 @@ pub const IO_URING_OP_SUPPORTED = 1 << 0;
pub const io_uring_probe_op = extern struct {
op: IORING_OP,
resv: u8,
flags: u16, // IO_URING_OP_* flags
/// IO_URING_OP_* flags
flags: u16,
resv2: u32,

pub fn is_supported(self: @This()) bool {
Expand All @@ -6150,8 +6151,10 @@ pub const io_uring_probe_op = extern struct {
};

pub const io_uring_probe = extern struct {
last_op: IORING_OP, // last opcode supported
ops_len: u8, // length of ops[] array below
/// Last opcode supported
last_op: IORING_OP,
/// Length of ops[] array below
ops_len: u8,
resv: u16,
resv2: [3]u32,
ops: [256]io_uring_probe_op,
Expand Down Expand Up @@ -6224,12 +6227,14 @@ pub const io_uring_buf_reg = extern struct {
ring_addr: u64,
ring_entries: u32,
bgid: u16,
flags: u16,
flags: Flags,
resv: [3]u64,

pub const FLAG = struct {
// Incremental buffer consummation.
pub const INC: u16 = 2;
pub const Flags = packed struct {
_0: u1 = 0,
/// Incremental buffer consumption.
inc: bool,
_: u14 = 0,
};
};

Expand Down
21 changes: 16 additions & 5 deletions lib/std/os/linux/IoUring.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1613,7 +1613,7 @@ pub const BufferGroup = struct {
const heads = try allocator.alloc(u32, buffers_count);
errdefer allocator.free(heads);

const br = try setup_buf_ring(ring.fd, buffers_count, group_id, linux.io_uring_buf_reg.FLAG.INC);
const br = try setup_buf_ring(ring.fd, buffers_count, group_id, .{ .inc = true });
buf_ring_init(br);

const mask = buf_ring_mask(buffers_count);
Expand Down Expand Up @@ -1698,7 +1698,12 @@ pub const BufferGroup = struct {
/// `fd` is IO_Uring.fd for which the provided buffer ring is being registered.
/// `entries` is the number of entries requested in the buffer ring, must be power of 2.
/// `group_id` is the chosen buffer group ID, unique in IO_Uring.
pub fn setup_buf_ring(fd: posix.fd_t, entries: u16, group_id: u16, flags: u16) !*align(page_size_min) linux.io_uring_buf_ring {
pub fn setup_buf_ring(
fd: posix.fd_t,
entries: u16,
group_id: u16,
flags: linux.io_uring_buf_reg.Flags,
) !*align(page_size_min) linux.io_uring_buf_ring {
if (entries == 0 or entries > 1 << 15) return error.EntriesNotInRange;
if (!std.math.isPowerOfTwo(entries)) return error.EntriesNotPowerOfTwo;

Expand All @@ -1719,18 +1724,24 @@ pub fn setup_buf_ring(fd: posix.fd_t, entries: u16, group_id: u16, flags: u16) !
return br;
}

fn register_buf_ring(fd: posix.fd_t, addr: u64, entries: u32, group_id: u16, flags: u16) !void {
fn register_buf_ring(
fd: posix.fd_t,
addr: u64,
entries: u32,
group_id: u16,
flags: linux.io_uring_buf_reg.Flags,
) !void {
var reg = mem.zeroInit(linux.io_uring_buf_reg, .{
.ring_addr = addr,
.ring_entries = entries,
.bgid = group_id,
.flags = flags,
});
var res = linux.io_uring_register(fd, .REGISTER_PBUF_RING, @as(*const anyopaque, @ptrCast(&reg)), 1);
if (linux.E.init(res) == .INVAL and reg.flags & linux.io_uring_buf_reg.FLAG.INC > 0) {
if (linux.E.init(res) == .INVAL and reg.flags.inc) {
// Retry without incremental buffer consumption.
// It is available since kernel 6.12. returns INVAL on older.
reg.flags &= ~linux.io_uring_buf_reg.FLAG.INC;
reg.flags.inc = false;
res = linux.io_uring_register(fd, .REGISTER_PBUF_RING, @as(*const anyopaque, @ptrCast(&reg)), 1);
}
try handle_register_buf_ring_result(res);
Expand Down

0 comments on commit 94b36db

Please sign in to comment.