Merged
Conversation
Collaborator
ming1
commented
Sep 24, 2025
- switch to ublk executor way for uring async support
Add --use_readable, one big usage is for using spawn_block(), such as smol::unblock(), for supporting easy offload. Add --use_readable for evaluating performance effect from smol::Async<>. Simple test shows that there is still a little obvious iops drop(~5%) when running `fio/t/io_uring -p0 /dev/ublkb0`. However, for offload case, it shouldn't be one thing. Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Align with smol::Async().readable() by using one dedicated task for executing tasks. One big thing is that we can't handle uring timeout handle any more, and queue idle/busy can't be dealt with now. Signed-off-by: Ming Lei <tom.leiming@gmail.com>
This commit implements major improvements to the run_uring_tasks API: 1. Changed run_ops parameter from FnMut to Fn for better usability 2. Added waker_ops parameter to separate CQE handling from polling logic 3. Integrated ublk_reap_events_with_handler call within run_uring_tasks 4. Removed public ublk_reap_events function and made ublk_reap_events_with_handler internal 5. Updated examples/null.rs to use the new API with proper separation of concerns Key API changes: - run_uring_tasks now takes 5 parameters including waker_ops: W where W: Fn(&io_uring::cqueue::Entry) - CQE handling is automatically performed after poll_uring() returns - Simplified the API surface by only exporting run_uring_tasks Benefits: - Better separation of polling and CQE handling responsibilities - More flexible and customizable waker behavior - Cleaner executor-agnostic design - Reduced API surface area for easier maintenance Signed-off-by: Ming Lei <tom.leiming@gmail.com>
- Add new function that combines ublk_reap_io_events() functionality with queue state management via update_state_batch() - Includes builtin closure for counting IO commands and detecting aborts - Calls provided waker_ops closure for each completion queue entry - Make UblkIOCtx::is_io_command() and UblkQueue::update_state_batch() accessible as pub(crate) for internal use Signed-off-by: Ming Lei <tom.leiming@gmail.com>
- Change enter_queue_idle() from fn() to pub(crate) fn() -> bool - Change exit_queue_idle() from fn() to pub(crate) fn() -> bool - Both functions now return bool indicating state change occurred - Make functions accessible as pub(crate) for internal use Signed-off-by: Ming Lei <tom.leiming@gmail.com>
- Modify run_uring_tasks() to support poll timeout detection:
- poll_uring closure now returns Result<bool, UblkError>
- reap_event_ops now receives bool parameter for timeout indication
- Enhance ublk_reap_io_events_with_update_queue() with idle management:
- Add poll_timeout parameter to indicate polling timeout
- Call q.enter_queue_idle() when poll timeout occurs
- Call q.exit_queue_idle() when no timeout or IO commands processed
- Only this function supports idle queue management
- Both q.enter_queue_idle() and q.exit_queue_idle() depends on queue
state, so this feature is only available from ublk_reap_io_events_with_update_queue
- Update examples/null.rs to demonstrate timeout handling:
- poll_events() now returns bool and implements 20s timeout
- Uses submit_with_args() to detect ETIME timeout condition
- Updates reap_event closure to pass timeout parameter
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
- Add new uring_poll_fn() function in src/uring_async.rs: - Takes io_uring ring and timeout_secs parameter - Uses submit_with_args() with timespec for timeout detection - Returns bool indicating if timeout occurred (ETIME error) - Generic over EntryMarker for ring compatibility - Update examples/null.rs to use new API: - Import uring_poll_fn in use statement - Replace inline timeout logic with uring_poll_fn(r, 20) call - Simplifies timeout handling and makes it reusable Signed-off-by: Ming Lei <tom.leiming@gmail.com>
- Add handle_uring_events_default() for default uring polling: - Uses uring_poll_fn() with 20-second timeout via with_queue_ring_mut() - No smol::Async wrapper, direct uring polling - Returns timeout status for queue idle management - Add handle_uring_events_smol_readable() for smol::Async polling: - Wraps uring fd in smol::Async for event-driven polling - Uses readable() for async-aware polling without timeout - Proper fd lifecycle management to prevent double-close - Refactor handle_uring_events() as dispatcher: - Chooses appropriate implementation based on smol_readable flag - Maintains backward compatibility with existing code - Clean separation of polling strategies - Remove unused poll_events() function to eliminate build warnings Signed-off-by: Ming Lei <tom.leiming@gmail.com>
- Add UblkUringData enum with Target variant defined as 1_u64 << 63 - Replace all hardcoded bit 63 usage with UblkUringData::TARGET - Centralize target bit handling for better maintainability - Use #[repr(u64)] to ensure proper enum discriminant type - Improves type safety and code readability for uring user_data bit manipulation Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Add timeout-based queue idle management for smol readable() polling: - Add UblkUringData enum with Target and NonAsync constants for user_data - Update ublk_reap_io_events_with_update_queue() to accept timeout_data parameter - Implement timeout CQE detection and queue idle state management - Add timeout SQE submission in handle_uring_events_smol_readable() - Update io-uring dependency from 0.7.6 to 0.7.9 - Modify queue idle functions to check submission queue emptiness UblkUringData::NonAsync can't be used for async/.await uring OP, so this bit is used for submitting uring OP with sync way in async/.await environment, and the main use case is for target to submit timeout SQE. Signed-off-by: Ming Lei <tom.leiming@gmail.com>
- Replace timeout_secs: usize with Option<io_uring::types::Timespec> - Add to_wait: usize parameter for submit_with_args() - Don't set timeout if Option is None, use submit_and_wait() instead - Update caller in examples/null.rs to use new signature This allows callers to optionally specify timeout and control the wait behavior more precisely while maintaining backward compatibility through Option type. Signed-off-by: Ming Lei <tom.leiming@gmail.com>
…_with_handler() and uring_poll_fn() Replace the previous loop-based implementation with the unified uring task management framework: - Use run_uring_tasks() for centralized task polling and event handling - Replace direct control ring polling with uring_poll_fn() calls - Maintain ublk_reap_events_with_handler() for CQE processing - Add control ring initialization for test environments - Preserve async executor task management functionality This refactoring provides consistency with other uring event handling patterns in the codebase while maintaining the same external interface. Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Mark queue as stopping in case of any command failure. Signed-off-by: Ming Lei <tom.leiming@gmail.com>
- Add wait_and_handle_io_events() function to uring_async module with queue, idle_secs, run_ops, and is_done parameters - Refactor handle_uring_events_default() in null.rs example to use the new API, reducing code complexity from ~25 to 4 lines - Export new API in lib.rs for public use - Fix documentation example imports for proper compilation Signed-off-by: Ming Lei <tom.leiming@gmail.com>
…o_events() Signed-off-by: Ming Lei <tom.leiming@gmail.com>
…ents() Following the pattern from commit dc4faac, replace all remaining instances of ublk_wait_and_handle_ios with the new wait_and_handle_io_events() API. Changes include: - examples/ramdisk.rs: Updated async executor pattern - src/test_helpers.rs: Applied new API in test helpers - tests/basic.rs: Updated test functions and removed old import - README.md: Updated example code to show new pattern - CLAUDE.md: Updated documentation reference Signed-off-by: Ming Lei <tom.leiming@gmail.com>
yield() is just for providing chance to handle prepare io command, which can be done by running oneshot `run_ops` in run_uring_tasks(). Signed-off-by: Ming Lei <tom.leiming@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.