Io_uring ignoring the timeout set to the io_uring.enter method

⚓ rust    📅 2025-07-04    👤 surdeus    👁️ 3      

surdeus

I'm using io_uring v 0.7.8 (latest), and I'm not able to set a timeout to the 'enter' method on the 'ring.submitter()' (at the moment I prefer to use this method and not to push a timeout sqe).

  1. First I checked the extended arguments are supported ... and they are on my 6.12 kernel.
if !params.is_feature_ext_arg() {  
   panic(bla bla bla)
}
  1. I built the struct 'io_uring_getevents_arg':
#[repr(C)]
struct GeteventsArg {
    sigmask:    u64,              // always 0
    sigmask_sz: u32,              // always 0
    pad:        u32,              // always 0
    ts:         u64,              // pointer to Timespec
}
  1. I prepared my timeout:
use io_uring::types::Timespec;
let secs = write_timeout_ms / 1_000;
let nsec = (write_timeout_ms % 1_000) * 1_000_000;
let ts = Timespec::new().sec(secs as u64).nsec(nsec as u32);
  1. I instantiated that GeteventsArg:
let arg = GeteventsArg {
    sigmask:    0,
    sigmask_sz: 0,
    pad:        0,
    ts: (&ts as *const Timespec) as u64,
};
  1. I called io_uring enter with the required flags and using 3 for to_submit and min_complete parameters, because I always send these sqes: open->write->close, where open is linked to writeFixed and writeFixed is linked to close, and close does not link to anyone. I had to declare these flags on my own code because I did not find a way to use them from any public api.
const IORING_ENTER_SQ_WAIT:   u32 = 1 << 1;
const IORING_ENTER_GETEVENTS: u32 = 1 << 0;
const IORING_ENTER_EXT_ARG:   u32 = 1 << 2;

let flags = IORING_ENTER_SQ_WAIT | IORING_ENTER_GETEVENTS | IORING_ENTER_EXT_ARG;
let ret = unsafe {
    ring.submitter().enter(
        3,      // to_submit
        3,      // min_complete
        flags,
        Some(&arg),
    )
};
  1. And finally I processed the SQEs:
// Process all completions, if there is an error continue processing until completely drain the 'completion' queue.
let mut maybe_err = None;  
for cqe in ring.completion().take(3) {
    let res = cqe.result();
    if res < 0 && maybe_err.is_none() {
       maybe_err = Some(Error::from_raw_os_error(-res));
    }
}
maybe_err.map_or(Ok(()), Err)

This code works like a charm, and the 32MB files are successfully written to disk, but the timeout is absolutely ignored. I tried with a timeout of just 1 nanosecond, and continue writing to disk, which is impossible in just 1ns.

Can anyone give me some light about what I'm doing wrong?

3 posts - 2 participants

Read full topic

🏷️ rust_feed