From b2b11c32e53cd705b27f2e5d3f3411bbbbcde3c0 Mon Sep 17 00:00:00 2001 From: David Stevens Date: Thu, 8 Sep 2022 14:51:44 +0900 Subject: [PATCH] io_uring: handle EINTR Handle EINTR returned from io_uring_enter. This fixes an issue where trying to strace an io_uring enabled device would cause the device to exit. BUG=None TEST=attach strace to io_uring enabled crosvm Change-Id: I2e808a51c3274b98f1caa18dbedd3164f2bd6aef Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3881686 Commit-Queue: David Stevens Reviewed-by: Keiichi Watanabe Reviewed-by: Takaya Saeki --- io_uring/src/uring.rs | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/io_uring/src/uring.rs b/io_uring/src/uring.rs index 175157be1e..3add1b082f 100644 --- a/io_uring/src/uring.rs +++ b/io_uring/src/uring.rs @@ -636,18 +636,28 @@ impl URingContext { self.in_flight.fetch_add(added, Ordering::Release); } Err(e) => { - self.submit_ring.lock().fail_submit(added); + // An EBUSY return means that some completed events must be processed before + // submitting more, so wait for some to finish without pushing the new sqes in + // that case. + // An EINTR means we successfully submitted the events but were interrupted while + // waiting, so just wait again. + // Any other error should be propagated up. - if wait_nr == 0 || e != libc::EBUSY { + if e != libc::EINTR { + self.submit_ring.lock().fail_submit(added); + } + + if wait_nr == 0 || (e != libc::EBUSY && e != libc::EINTR) { return Err(Error::RingEnter(e)); } - // An ebusy return means that some completed events must be processed before - // submitting more, wait for some to finish without pushing the new sqes in - // that case. - unsafe { - io_uring_enter(self.ring_file.as_raw_fd(), 0, wait_nr, flags) - .map_err(Error::RingEnter)?; + loop { + // Safe because the only memory modified is in the completion queue. + let res = + unsafe { io_uring_enter(self.ring_file.as_raw_fd(), 0, wait_nr, flags) }; + if res != Err(libc::EINTR) { + return res.map_err(Error::RingEnter); + } } } }