[PATCH v5 0/4] Rust io_uring command abstraction for miscdevice
From: Sidong Yang
Date: Wed Apr 15 2026 - 05:14:33 EST
This series introduces Rust abstractions for io_uring commands
(`IORING_OP_URING_CMD`) and wires them up to the miscdevice framework,
allowing Rust drivers to handle io_uring passthrough commands.
The series is structured as follows:
1. Add io_uring C headers to Rust bindings.
2. Core io_uring Rust abstractions (IoUringCmd, QueuedIoUringCmd,
IoUringSqe, UringCmdAction type-state pattern, IoUringTaskWork trait).
3. MiscDevice trait extension with uring_cmd callback.
4. Sample demonstrating async uring_cmd handling via workqueue.
The sample completes asynchronously using a workqueue combined with
`complete_in_task()`, which schedules task_work in the submitter's task
context before calling `io_uring_cmd_done()`. This two-step approach
ensures that completion always runs in the correct context regardless
of where the driver decides to finish the operation.
Copy-based `read_pdu()`/`write_pdu()` are kept instead of returning
`&T`/`&mut T` references because the PDU is a `[u8; 32]` byte array
whose alignment may not satisfy `T`'s requirements.
Changes since v4:
- Dropped patch 2/5 (C-side zero-init of PDU in io_uring_cmd_prep);
zero-initialisation is handled in the Rust miscdevice vtable wrapper
instead. (Greg)
- Placed io_uring headers in alphabetical order in
bindings_helper.h. (Miguel)
- Used `.cast()` / `core::ptr::from_ref()` instead of `as` pointer
casts throughout. (Daniel)
- Fixed workqueue completion bug: calling `io_uring_cmd_done()` directly
from a workqueue is unsafe because the worker does not hold uring_lock.
Added `complete_in_task()` / `IoUringTaskWork` trait so drivers
schedule task_work first, then call `done()` with the correct
`TASK_WORK_ISSUE_FLAGS` from the submitter's context.
- Removed `issue_flags` forwarding from sample; the workqueue now calls
`complete_in_task()` instead of `done()` directly.
- Improved all commit messages.
Changes since v3:
- read_pdu(): replaced MaybeUninit + copy_nonoverlapping(c_void) with
read_unaligned (Caleb, Benno).
- write_pdu(): fixed c_void cast to u8 in copy_nonoverlapping (Benno).
- IoUringSqe::opcode(): use read_volatile for SQE field access (Caleb).
- IoUringSqe::cmd_data(): removed unnecessary runtime opcode check;
safety is guaranteed by construction since IoUringSqe can only be
obtained from IoUringCmd::sqe() inside a uring_cmd callback (Caleb).
- Removed unused mut in sample WorkItem::run() (compiler warning).
Changes since v2:
- Adopted type-state pattern for IoUringCmd (IoUringCmd -> QueuedIoUringCmd)
to enforce correct completion flow at compile time.
- UringCmdAction enum with Complete/Queued variants prevents returning
Queued without holding a QueuedIoUringCmd handle.
- Fixed error code handling (use proper kernel error types).
- Suppressed unused result warning with `let _ = ...enqueue(work)`.
Sidong Yang (4):
rust: bindings: add io_uring headers in bindings_helper.h
rust: io_uring: introduce rust abstraction for io-uring cmd
rust: miscdevice: Add `uring_cmd` support
samples: rust: Add `uring_cmd` example to `rust_misc_device`
rust/bindings/bindings_helper.h | 2 +
rust/helpers/helpers.c | 1 +
rust/helpers/io_uring.c | 15 +
rust/kernel/io_uring.rs | 522 +++++++++++++++++++++++++++++++
rust/kernel/lib.rs | 1 +
rust/kernel/miscdevice.rs | 81 +++++
samples/rust/rust_misc_device.rs | 62 +++-
7 files changed, 683 insertions(+), 1 deletion(-)
create mode 100644 rust/helpers/io_uring.c
create mode 100644 rust/kernel/io_uring.rs
--
2.43.0