Skip to content

Commit bb6b867

Browse files
committed
std.os.linux.IoUring: IORING_ENTER_NO_IOWAIT flag support
1 parent 173f497 commit bb6b867

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

lib/std/os/linux.zig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6598,6 +6598,11 @@ pub const IORING_ENTER_SQ_WAKEUP = 1 << 1;
65986598
pub const IORING_ENTER_SQ_WAIT = 1 << 2;
65996599
pub const IORING_ENTER_EXT_ARG = 1 << 3;
66006600
pub const IORING_ENTER_REGISTERED_RING = 1 << 4;
6601+
pub const IORING_ENTER_NO_IOWAIT = 1 << 7;
6602+
6603+
pub const IORING_INT_FLAG_NO_IOWAIT = IORING_ENTER_NO_IOWAIT;
6604+
6605+
pub const IORING_INT_FLAGS_MASK = IORING_ENTER_NO_IOWAIT;
66016606

66026607
pub const io_uring_params = extern struct {
66036608
sq_entries: u32,
@@ -6627,6 +6632,7 @@ pub const IORING_FEAT_NATIVE_WORKERS = 1 << 9;
66276632
pub const IORING_FEAT_RSRC_TAGS = 1 << 10;
66286633
pub const IORING_FEAT_CQE_SKIP = 1 << 11;
66296634
pub const IORING_FEAT_LINKED_FILE = 1 << 12;
6635+
pub const IORING_FEAT_NO_IOWAIT = 1 << 17;
66306636

66316637
// io_uring_register opcodes and arguments
66326638
pub const IORING_REGISTER = enum(u32) {

lib/std/os/linux/IoUring.zig

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ fd: posix.fd_t = -1,
1414
sq: SubmissionQueue,
1515
cq: CompletionQueue,
1616
flags: u32,
17+
int_flags: u8,
1718
features: u32,
1819

1920
/// A friendly way to setup an io_uring, with default linux.io_uring_params.
@@ -113,6 +114,8 @@ pub fn init_params(entries: u16, p: *linux.io_uring_params) !IoUring {
113114
.sq = sq,
114115
.cq = cq,
115116
.flags = p.flags,
117+
// TODO set int_flags according to p.flags
118+
.int_flags = 0,
116119
.features = p.features,
117120
};
118121
}
@@ -126,6 +129,21 @@ pub fn deinit(self: *IoUring) void {
126129
self.fd = -1;
127130
}
128131

132+
pub fn io_uring_set_io_wait(self: *IoUring, enable_iowait: bool) !void {
133+
if ((self.features & linux.IORING_FEAT_NO_IOWAIT) == 0) {
134+
return error.SystemOutdated;
135+
}
136+
if (enable_iowait) {
137+
self.int_flags &= ~@as(u8, linux.IORING_INT_FLAG_NO_IOWAIT);
138+
} else {
139+
self.int_flags |= linux.IORING_INT_FLAG_NO_IOWAIT;
140+
}
141+
}
142+
143+
pub fn ring_enter_flags(self: *IoUring) u32 {
144+
return self.int_flags & linux.IORING_INT_FLAGS_MASK;
145+
}
146+
129147
/// Returns a pointer to a vacant SQE, or an error if the submission queue is full.
130148
/// We follow the implementation (and atomics) of liburing's `io_uring_get_sqe()` exactly.
131149
/// However, instead of a null we return an error to force safe handling.
@@ -160,7 +178,7 @@ pub fn submit(self: *IoUring) !u32 {
160178
/// Matches the implementation of io_uring_submit_and_wait() in liburing.
161179
pub fn submit_and_wait(self: *IoUring, wait_nr: u32) !u32 {
162180
const submitted = self.flush_sq();
163-
var flags: u32 = 0;
181+
var flags: u32 = self.ring_enter_flags();
164182
if (self.sq_ring_needs_enter(&flags) or wait_nr > 0) {
165183
if (wait_nr > 0 or (self.flags & linux.IORING_SETUP_IOPOLL) != 0) {
166184
flags |= linux.IORING_ENTER_GETEVENTS;
@@ -233,7 +251,7 @@ pub fn flush_sq(self: *IoUring) u32 {
233251
/// For the latter case, we set the SQ thread wakeup flag.
234252
/// Matches the implementation of sq_ring_needs_enter() in liburing.
235253
pub fn sq_ring_needs_enter(self: *IoUring, flags: *u32) bool {
236-
assert(flags.* == 0);
254+
assert(flags.* & (~@as(u8, linux.IORING_INT_FLAGS_MASK)) == 0);
237255
if ((self.flags & linux.IORING_SETUP_SQPOLL) == 0) return true;
238256
if ((@atomicLoad(u32, self.sq.flags, .unordered) & linux.IORING_SQ_NEED_WAKEUP) != 0) {
239257
flags.* |= linux.IORING_ENTER_SQ_WAKEUP;
@@ -273,7 +291,8 @@ pub fn copy_cqes(self: *IoUring, cqes: []linux.io_uring_cqe, wait_nr: u32) !u32
273291
const count = self.copy_cqes_ready(cqes);
274292
if (count > 0) return count;
275293
if (self.cq_ring_needs_flush() or wait_nr > 0) {
276-
_ = try self.enter(0, wait_nr, linux.IORING_ENTER_GETEVENTS);
294+
const flags = self.ring_enter_flags() | linux.IORING_ENTER_GETEVENTS;
295+
_ = try self.enter(0, wait_nr, flags);
277296
return self.copy_cqes_ready(cqes);
278297
}
279298
return 0;

0 commit comments

Comments
 (0)