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: 6768ddcc56
Refs: https://github.com/axboe/liburing/issues/219
This commit is contained in:
Joran Dirk Greef
2020-10-03 14:34:42 +02:00
parent 95def89c23
commit a9b107045f

View File

@@ -247,7 +247,7 @@ pub const IO_Uring = struct {
pub fn sq_ring_needs_enter(self: *IO_Uring, submitted: u32, flags: *u32) bool {
assert(flags.* == 0);
if ((self.flags & linux.IORING_SETUP_SQPOLL) == 0 and submitted > 0) return true;
if ((@atomicLoad(u32, self.sq.flags, .Unordered) & linux.IORING_SQ_NEED_WAKEUP) != 0) {
if ((@atomicLoad(u32, self.sq.flags, .Acquire) & linux.IORING_SQ_NEED_WAKEUP) != 0) {
flags.* |= linux.IORING_ENTER_SQ_WAKEUP;
return true;
}