Skip to content

Add io_uring SSD-style benchmark with configurable workload#203

Open
LED-0102 wants to merge 2 commits into
novitalabs:masterfrom
LED-0102:feat/uring-io-benchmark
Open

Add io_uring SSD-style benchmark with configurable workload#203
LED-0102 wants to merge 2 commits into
novitalabs:masterfrom
LED-0102:feat/uring-io-benchmark

Conversation

@LED-0102

@LED-0102 LED-0102 commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Closes #100

This PR adds a custom io_uring benchmark using [[bench]] with harness = false, implementing a reproducible mixed read/write workload with configurable parameters.

The benchmark reports throughput (MB/s), IOPS, and latency percentiles (p50/p95/p99) using hdrhistogram. It also includes basic fio parameter mapping to allow easier comparison.

Please let me know if any additional scenarios, parameters, or improvements would be useful, or if there’s anything I may have overlooked.

Copilot AI review requested due to automatic review settings April 9, 2026 17:51

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a custom io_uring benchmark binary (harness = false) to measure SSD-style mixed read/write performance and latency percentiles, and exposes the uring backing engine so the benchmark can call into it.

Changes:

  • Introduces benches/uring_bench.rs implementing a configurable randrw-style workload with HDR histogram latency reporting.
  • Makes pegaflow_core::backing::uring and key uring types/functions public so the benchmark can access them.
  • Adds new dependencies (clap, hdrhistogram) and registers the new [[bench]] target.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
pegaflow-core/src/lib.rs Exposes backing publicly for bench access.
pegaflow-core/src/backing/mod.rs Exposes uring module publicly.
pegaflow-core/src/backing/uring.rs Makes UringConfig, UringIoEngine, and async read/write APIs public.
pegaflow-core/Cargo.toml Adds deps and registers uring_bench bench target.
pegaflow-core/benches/uring_bench.rs New custom benchmark implementation and fio parameter mapping docs.
Cargo.lock Locks new transitive dependencies.
Comments suppressed due to low confidence (3)

pegaflow-core/src/backing/uring.rs:260

  • readv_at_async/writev_at_async are now pub and take raw pointers, but they’re still safe functions with a documented safety precondition (“caller must ensure pointers remain valid”). With a public API, this should be enforced by types (e.g., accept pinned slices/IoSlice/IoSliceMut) or the functions should be marked unsafe fn to avoid exposing an unsound safe API that can trigger UB via invalid pointers.
    /// Vectorized read (readv) - reads into multiple buffers in a single syscall.
    ///
    /// # Arguments
    /// * `iovecs` - Array of (ptr, len) pairs to read into sequentially
    /// * `offset` - File offset to start reading
    ///
    /// # Safety
    /// Caller must ensure all buffer pointers remain valid until the returned receiver completes.
    pub fn readv_at_async(
        &self,
        iovecs: Vec<(*mut u8, usize)>,
        offset: u64,
    ) -> io::Result<oneshot::Receiver<io::Result<usize>>> {

pegaflow-core/src/backing/uring.rs:307

  • writev_at_async is now pub and accepts raw pointers under a safety precondition, but it’s still a safe function. If this remains publicly accessible, it should be unsafe fn or reworked to accept safe buffer types so callers can’t violate the invariants from safe Rust.
    /// Vectorized write (writev) - writes multiple buffers in a single syscall.
    ///
    /// # Arguments
    /// * `iovecs` - Array of (ptr, len) pairs to write sequentially
    /// * `offset` - File offset to start writing
    ///
    /// # Safety
    /// Caller must ensure all buffer pointers remain valid until the returned receiver completes.
    pub fn writev_at_async(
        &self,
        iovecs: Vec<(*const u8, usize)>,
        offset: u64,
    ) -> io::Result<oneshot::Receiver<io::Result<usize>>> {

pegaflow-core/src/backing/uring.rs:224

  • UringIoEngine::new validates threads > 0 but doesn’t validate io_depth > 0. With this now being a public constructor, it would be better to reject io_depth == 0 explicitly with a clear InvalidInput error rather than relying on io_uring builder failures / zero-capacity channels.
impl UringIoEngine {
    pub fn new(fd: RawFd, cfg: UringConfig) -> io::Result<Self> {
        if cfg.threads == 0 {
            return Err(io::Error::new(
                io::ErrorKind::InvalidInput,
                "threads must be > 0",
            ));
        }

        let mut txs = Vec::with_capacity(cfg.threads);
        let mut handles = Vec::with_capacity(cfg.threads);

        for _ in 0..cfg.threads {
            let (tx, rx) = mpsc::sync_channel(cfg.io_depth * 2);
            let mut builder = IoUring::builder();
            if cfg.sqpoll {
                builder.setup_sqpoll(cfg.sqpoll_idle);
            }
            let uring = builder.build(cfg.io_depth as u32)?;
            let shard = UringShard {

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pegaflow-core/Cargo.toml
Comment thread pegaflow-core/src/lib.rs
Comment thread pegaflow-core/benches/uring_bench.rs
Comment thread pegaflow-core/benches/uring_bench.rs Outdated
Comment thread pegaflow-core/benches/uring_bench.rs
Comment thread pegaflow-core/benches/uring_bench.rs Outdated
Comment thread pegaflow-core/benches/uring_bench.rs Outdated
@LED-0102

Copy link
Copy Markdown
Contributor Author

Hi @xiaguan!
Could you please have a look at this PR?

@xiaguan

xiaguan commented Apr 27, 2026

Copy link
Copy Markdown
Collaborator

Can you provide a running result and compare it with the fio test?

@xiaguan xiaguan self-assigned this Apr 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add custom io_uring benchmark (harness=false) and align with fio

3 participants