authorgravatar for joran@ronomon.comJoran Dirk Greef <joran@ronomon.com> 2020-10-03 14:34:42+02:00
committergravatar for joran@ronomon.comJoran Dirk Greef <joran@ronomon.com> 2020-10-03 14:34:42+02:00
loga9b107045fb0592f813ffd9f5fef3e2cbfd2ac89
treea64941738500abf627977ba586acd95e75e63918
parent95def89c232acc53c926731fe5143ea093128d73

Use load acquire semantics when reading the SQPOLL wakeup flag

Ensures that the wakeup flag is read after the tail pointer has been written. It's important to use memory load acquire semantics for the flags read, otherwise the application and the kernel might not agree on the consistency of the wakeup flag, leading to I/O starvation. Refs: https://github.com/axboe/liburing/commit/6768ddcc562adb6ea141cf508bccecb6be8ce666 Refs: https://github.com/axboe/liburing/issues/219

1 files changed, 1 insertions(+), 1 deletions(-)

lib/std/os/linux/io_uring.zig+1-1
...@@ -247,7 +247,7 @@ pub const IO_Uring = struct {...@@ -247,7 +247,7 @@ pub const IO_Uring = struct {
247 pub fn sq_ring_needs_enter(self: *IO_Uring, submitted: u32, flags: *u32) bool {247 pub fn sq_ring_needs_enter(self: *IO_Uring, submitted: u32, flags: *u32) bool {
248 assert(flags.* == 0);248 assert(flags.* == 0);
249 if ((self.flags & linux.IORING_SETUP_SQPOLL) == 0 and submitted > 0) return true;249 if ((self.flags & linux.IORING_SETUP_SQPOLL) == 0 and submitted > 0) return true;
250 if ((@atomicLoad(u32, self.sq.flags, .Unordered) & linux.IORING_SQ_NEED_WAKEUP) != 0) {250 if ((@atomicLoad(u32, self.sq.flags, .Acquire) & linux.IORING_SQ_NEED_WAKEUP) != 0) {
251 flags.* |= linux.IORING_ENTER_SQ_WAKEUP;251 flags.* |= linux.IORING_ENTER_SQ_WAKEUP;
252 return true;252 return true;
253 }253 }