tokio-rs / tokio-uring

An io_uring backed runtime for Rust
MIT License
1.11k stars 117 forks source link

[BUG] Hangs when using iopoll without sqpoll #296

Open SidongYang opened 7 months ago

SidongYang commented 7 months ago

Hi, I found some bug that the code hang when using iopoll without sqpoll. This bug can be reproduced with example below.

    let mut builder = tokio_uring::builder();
    builder.uring_builder(&tokio_uring::uring_builder().setup_iopoll());
    let runtime = tokio_uring::Runtime::new(&builder)?;
    runtime.block_on(async {
        // tokio_uring::spawn(ThreadParker::new());                                                                                                   

        let file = std::fs::OpenOptions::new()
            .write(true)
            .custom_flags(libc::O_DIRECT)
            .open("test").unwrap();
        let file = tokio_uring::fs::File::from_std(file);

        let layout = std::alloc::Layout::from_size_align(512, 512).unwrap();
        let buf = unsafe {
            let raw = std::alloc::alloc(layout);
            std::ptr::copy("asdf".as_ptr(), raw, 4);
            std::slice::from_raw_parts(raw, 512)
        };

        let res = file.write_at(buf, 0).await;
        println!("{res:?}");

    });

I've tested this problem in Ubuntu 22.04 Linux 6.5.0-17-generic. The code hangs in calling File::write_at().await. In iopoll, tokio uring have to keep polling with submitting GETEVENTS but current tokio uring doesn't. I found currently tokio uring runtime submits in thread park. So I fix example code adding ThreadParker that force to submit continously . ThreadParker is just simple future impl for busy wake.

It seems that add new async task for iopoll in runtime that keep submitting until completion.

ollie-etl commented 6 months ago

Would you care to submit a PR?

SidongYang commented 6 months ago

@ollie-etl Sure, here is my PR #297