FAST_POLL support and switch to rustix
Howdy!
2 things are proposed in this issue:
- Support IORING_FEAT_FAST_POLL, as it allows for performance gains (up to 20%) compared to both standard io_uring and epoll
- Switch to rustix, as the rustix-uring crate isn't as frequently updated as this one, and it'd be beneficial to switch over (cleaner and POTENTIALLY more performant code, with direct syscalls)
Thanks, Alex <3 PS: FAST_POLL is monoio's secret sauce for performance
- IORING_FEAT_FAST_POLL is a feature flag, not a setup flag. if you think it needs "support", you may have misunderstood. see https://docs.rs/io-uring/latest/io_uring/struct.Parameters.html#method.is_feature_fast_poll
- We do support direct syscalls, and syscalls through libc are a feature. did you run into any issues, or do you think there's anything that's not "clean" or slow?
One benefit of the rustix-uring crate is that if a feature isn't added yet, there are still ways to use the raw API to get around it. For example, neither this crate nor the rustix-uring have a proper API for IORING_REGISTER_NAPI (even though it released with 6.9, one year ago). But with the rustix-uring crate, I can still do this:
use std::os::fd::AsFd;
use rustix::io_uring as sys;
const fn cast_ptr<T>(n: &T) -> *const T {
n
}
fn execute<Fd: AsFd>(
fd: Fd, opcode: sys::IoringRegisterOp, arg: *const core::ffi::c_void, len: u32,
) -> io::Result<()> {
unsafe {
sys::io_uring_register(fd.as_fd(), opcode, arg, len)?;
}
Ok(())
}
let mut arg = sys::io_uring_napi::default();
arg.busy_poll_to = 1 << 20;
arg.prefer_busy_poll = 1;
#[allow(clippy::expect_used)]
execute(
&self.io_uring,
sys::IoringRegisterOp::RegisterNapi,
cast_ptr::<sys::io_uring_napi>(&arg).cast(),
1,
)
.expect("failed to register napi");
This is because the bindings themselves are a separate public API of the rustix crate, which are updated more frequently. I was just trying to switch to this crate as well, since it seems to be much more up to date (& more used), but I can't do that because of this. I guess this crate could also expose the raw sys API.
@utkarshgupta137 You can use this crate with rustix or any of your own linux api crates.
I thought rustix::io_uring::io_uring_register could accept an io_uring::IoUring fd, couldn't it?
let io_uring: io_uring::IoUring = ...;
rustix::io_uring::io_uring_register(
io_uring.as_fd(),
sys::IoringRegisterOp::RegisterNapi,
&arg,
1
).unwrap();
And, it would be even better if you are willing to open a PR for napi.
@utkarshgupta137 You can use this crate with rustix or any of your own linux api crates.
I thought
rustix::io_uring::io_uring_registercould accept anio_uring::IoUringfd, couldn't it?let io_uring: io_uring::IoUring = ...;
rustix::io_uring::io_uring_register( io_uring.as_fd(), sys::IoringRegisterOp::RegisterNapi, &arg, 1 ).unwrap();
And, it would be even better if you are willing to open a PR for napi.
Yeah, I was planning to add a PR for missing features. But I'm still iterating over the setup I want to use for my application, so it is better for me to do things manually now, before I try to write a proper API in the library.
@quininer 1. I've misunderstood. 2. It'd make code much cleaner.