authorgravatar for igor.anic@gmail.comIgor Anić <igor.anic@gmail.com> 2025-03-05 13:32:52+01:00
committergravatar for igor.anic@gmail.comIgor Anić <igor.anic@gmail.com> 2025-03-05 13:35:52+01:00
log94b36dbe50a90172a57e0ab828079fcb2b7cfcfc
tree8db964bf659a093463fff93370fac624d9b5232b
parentc133171567fe3a81f817d0ea159bd9229d75291c

io_uring: refactor buf_reg flags

Use packed struct instead of or-ed integers. Thanks to @linsug for pr comments: https://github.com/ziglang/zig/pull/23062

2 files changed, 28 insertions(+), 12 deletions(-)

lib/std/os/linux.zig+12-7
......@@ -6141,7 +6141,8 @@ pub const IO_URING_OP_SUPPORTED = 1 << 0;
61416141pub const io_uring_probe_op = extern struct {
61426142 op: IORING_OP,
61436143 resv: u8,
6144 flags: u16, // IO_URING_OP_* flags
6144 /// IO_URING_OP_* flags
6145 flags: u16,
61456146 resv2: u32,
61466147
61476148 pub fn is_supported(self: @This()) bool {
......@@ -6150,8 +6151,10 @@ pub const io_uring_probe_op = extern struct {
61506151};
61516152
61526153pub const io_uring_probe = extern struct {
6153 last_op: IORING_OP, // last opcode supported
6154 ops_len: u8, // length of ops[] array below
6154 /// Last opcode supported
6155 last_op: IORING_OP,
6156 /// Length of ops[] array below
6157 ops_len: u8,
61556158 resv: u16,
61566159 resv2: [3]u32,
61576160 ops: [256]io_uring_probe_op,
......@@ -6224,12 +6227,14 @@ pub const io_uring_buf_reg = extern struct {
62246227 ring_addr: u64,
62256228 ring_entries: u32,
62266229 bgid: u16,
6227 flags: u16,
6230 flags: Flags,
62286231 resv: [3]u64,
62296232
6230 pub const FLAG = struct {
6231 // Incremental buffer consummation.
6232 pub const INC: u16 = 2;
6233 pub const Flags = packed struct {
6234 _0: u1 = 0,
6235 /// Incremental buffer consumption.
6236 inc: bool,
6237 _: u14 = 0,
62336238 };
62346239};
62356240
lib/std/os/linux/IoUring.zig+16-5
......@@ -1613,7 +1613,7 @@ pub const BufferGroup = struct {
16131613 const heads = try allocator.alloc(u32, buffers_count);
16141614 errdefer allocator.free(heads);
16151615
1616 const br = try setup_buf_ring(ring.fd, buffers_count, group_id, linux.io_uring_buf_reg.FLAG.INC);
1616 const br = try setup_buf_ring(ring.fd, buffers_count, group_id, .{ .inc = true });
16171617 buf_ring_init(br);
16181618
16191619 const mask = buf_ring_mask(buffers_count);
......@@ -1698,7 +1698,12 @@ pub const BufferGroup = struct {
16981698/// `fd` is IO_Uring.fd for which the provided buffer ring is being registered.
16991699/// `entries` is the number of entries requested in the buffer ring, must be power of 2.
17001700/// `group_id` is the chosen buffer group ID, unique in IO_Uring.
1701pub fn setup_buf_ring(fd: posix.fd_t, entries: u16, group_id: u16, flags: u16) !*align(page_size_min) linux.io_uring_buf_ring {
1701pub fn setup_buf_ring(
1702 fd: posix.fd_t,
1703 entries: u16,
1704 group_id: u16,
1705 flags: linux.io_uring_buf_reg.Flags,
1706) !*align(page_size_min) linux.io_uring_buf_ring {
17021707 if (entries == 0 or entries > 1 << 15) return error.EntriesNotInRange;
17031708 if (!std.math.isPowerOfTwo(entries)) return error.EntriesNotPowerOfTwo;
17041709
......@@ -1719,7 +1724,13 @@ pub fn setup_buf_ring(fd: posix.fd_t, entries: u16, group_id: u16, flags: u16) !
17191724 return br;
17201725}
17211726
1722fn register_buf_ring(fd: posix.fd_t, addr: u64, entries: u32, group_id: u16, flags: u16) !void {
1727fn register_buf_ring(
1728 fd: posix.fd_t,
1729 addr: u64,
1730 entries: u32,
1731 group_id: u16,
1732 flags: linux.io_uring_buf_reg.Flags,
1733) !void {
17231734 var reg = mem.zeroInit(linux.io_uring_buf_reg, .{
17241735 .ring_addr = addr,
17251736 .ring_entries = entries,
......@@ -1727,10 +1738,10 @@ fn register_buf_ring(fd: posix.fd_t, addr: u64, entries: u32, group_id: u16, fla
17271738 .flags = flags,
17281739 });
17291740 var res = linux.io_uring_register(fd, .REGISTER_PBUF_RING, @as(*const anyopaque, @ptrCast(&reg)), 1);
1730 if (linux.E.init(res) == .INVAL and reg.flags & linux.io_uring_buf_reg.FLAG.INC > 0) {
1741 if (linux.E.init(res) == .INVAL and reg.flags.inc) {
17311742 // Retry without incremental buffer consumption.
17321743 // It is available since kernel 6.12. returns INVAL on older.
1733 reg.flags &= ~linux.io_uring_buf_reg.FLAG.INC;
1744 reg.flags.inc = false;
17341745 res = linux.io_uring_register(fd, .REGISTER_PBUF_RING, @as(*const anyopaque, @ptrCast(&reg)), 1);
17351746 }
17361747 try handle_register_buf_ring_result(res);