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;...@@ -6141,7 +6141,8 @@ pub const IO_URING_OP_SUPPORTED = 1 << 0;
6141pub const io_uring_probe_op = extern struct {6141pub const io_uring_probe_op = extern struct {
6142 op: IORING_OP,6142 op: IORING_OP,
6143 resv: u8,6143 resv: u8,
6144 flags: u16, // IO_URING_OP_* flags6144 /// IO_URING_OP_* flags
6145 flags: u16,
6145 resv2: u32,6146 resv2: u32,
61466147
6147 pub fn is_supported(self: @This()) bool {6148 pub fn is_supported(self: @This()) bool {
...@@ -6150,8 +6151,10 @@ pub const io_uring_probe_op = extern struct {...@@ -6150,8 +6151,10 @@ pub const io_uring_probe_op = extern struct {
6150};6151};
61516152
6152pub const io_uring_probe = extern struct {6153pub const io_uring_probe = extern struct {
6153 last_op: IORING_OP, // last opcode supported6154 /// Last opcode supported
6154 ops_len: u8, // length of ops[] array below6155 last_op: IORING_OP,
6156 /// Length of ops[] array below
6157 ops_len: u8,
6155 resv: u16,6158 resv: u16,
6156 resv2: [3]u32,6159 resv2: [3]u32,
6157 ops: [256]io_uring_probe_op,6160 ops: [256]io_uring_probe_op,
...@@ -6224,12 +6227,14 @@ pub const io_uring_buf_reg = extern struct {...@@ -6224,12 +6227,14 @@ pub const io_uring_buf_reg = extern struct {
6224 ring_addr: u64,6227 ring_addr: u64,
6225 ring_entries: u32,6228 ring_entries: u32,
6226 bgid: u16,6229 bgid: u16,
6227 flags: u16,6230 flags: Flags,
6228 resv: [3]u64,6231 resv: [3]u64,
62296232
6230 pub const FLAG = struct {6233 pub const Flags = packed struct {
6231 // Incremental buffer consummation.6234 _0: u1 = 0,
6232 pub const INC: u16 = 2;6235 /// Incremental buffer consumption.
6236 inc: bool,
6237 _: u14 = 0,
6233 };6238 };
6234};6239};
62356240
lib/std/os/linux/IoUring.zig+16-5
...@@ -1613,7 +1613,7 @@ pub const BufferGroup = struct {...@@ -1613,7 +1613,7 @@ pub const BufferGroup = struct {
1613 const heads = try allocator.alloc(u32, buffers_count);1613 const heads = try allocator.alloc(u32, buffers_count);
1614 errdefer allocator.free(heads);1614 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 });
1617 buf_ring_init(br);1617 buf_ring_init(br);
16181618
1619 const mask = buf_ring_mask(buffers_count);1619 const mask = buf_ring_mask(buffers_count);
...@@ -1698,7 +1698,12 @@ pub const BufferGroup = struct {...@@ -1698,7 +1698,12 @@ pub const BufferGroup = struct {
1698/// `fd` is IO_Uring.fd for which the provided buffer ring is being registered.1698/// `fd` is IO_Uring.fd for which the provided buffer ring is being registered.
1699/// `entries` is the number of entries requested in the buffer ring, must be power of 2.1699/// `entries` is the number of entries requested in the buffer ring, must be power of 2.
1700/// `group_id` is the chosen buffer group ID, unique in IO_Uring.1700/// `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 {
1702 if (entries == 0 or entries > 1 << 15) return error.EntriesNotInRange;1707 if (entries == 0 or entries > 1 << 15) return error.EntriesNotInRange;
1703 if (!std.math.isPowerOfTwo(entries)) return error.EntriesNotPowerOfTwo;1708 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) !...@@ -1719,7 +1724,13 @@ pub fn setup_buf_ring(fd: posix.fd_t, entries: u16, group_id: u16, flags: u16) !
1719 return br;1724 return br;
1720}1725}
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 {
1723 var reg = mem.zeroInit(linux.io_uring_buf_reg, .{1734 var reg = mem.zeroInit(linux.io_uring_buf_reg, .{
1724 .ring_addr = addr,1735 .ring_addr = addr,
1725 .ring_entries = entries,1736 .ring_entries = entries,
...@@ -1727,10 +1738,10 @@ fn register_buf_ring(fd: posix.fd_t, addr: u64, entries: u32, group_id: u16, fla...@@ -1727,10 +1738,10 @@ fn register_buf_ring(fd: posix.fd_t, addr: u64, entries: u32, group_id: u16, fla
1727 .flags = flags,1738 .flags = flags,
1728 });1739 });
1729 var res = linux.io_uring_register(fd, .REGISTER_PBUF_RING, @as(*const anyopaque, @ptrCast(&reg)), 1);1740 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) {
1731 // Retry without incremental buffer consumption.1742 // Retry without incremental buffer consumption.
1732 // It is available since kernel 6.12. returns INVAL on older.1743 // 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;
1734 res = linux.io_uring_register(fd, .REGISTER_PBUF_RING, @as(*const anyopaque, @ptrCast(&reg)), 1);1745 res = linux.io_uring_register(fd, .REGISTER_PBUF_RING, @as(*const anyopaque, @ptrCast(&reg)), 1);
1735 }1746 }
1736 try handle_register_buf_ring_result(res);1747 try handle_register_buf_ring_result(res);