[PATCH v4 5/5] samples: rust: Add `uring_cmd` example to `rust_misc_device`

Sidong Yang
2026-04-08T14:00:57Z

This patch extends the `rust_misc_device` sample to demonstrate how to
use the `uring_cmd` interface for asynchronous device operations.

The new implementation handles two `uring_cmd` operations:

* `RUST_MISC_DEV_URING_CMD_SET_VALUE`: Sets a value in the device.
* `RUST_MISC_DEV_URING_CMD_GET_VALUE`: Gets a value from the device.

To use this new functionality, users can submit `IORING_OP_URING_CMD`
operations to the `rust_misc_device` character device.

Signed-off-by: Sidong Yang <sidong.yang@furiosa.ai>
---
samples/rust/rust_misc_device.rs | 53 +++++++++++++++++++++++++++++++-
1 file changed, 52 insertions(+), 1 deletion(-)

diff --git a/samples/rust/rust_misc_device.rs b/samples/rust/rust_misc_device.rs
index 87a1fe63533a..ef506e8b26fe 100644
--- a/samples/rust/rust_misc_device.rs
+++ b/samples/rust/rust_misc_device.rs
@@ -98,13 +98,15 @@
use kernel::{
device::Device,
fs::{File, Kiocb},
+ io_uring::{IoUringCmd, QueuedIoUringCmd, UringCmdAction},
ioctl::{_IO, _IOC_SIZE, _IOR, _IOW},
iov::{IovIterDest, IovIterSource},
miscdevice::{MiscDevice, MiscDeviceOptions, MiscDeviceRegistration},
new_mutex,
prelude::*,
- sync::{aref::ARef, Mutex},
+ sync::{Arc, aref::ARef, Mutex},
uaccess::{UserSlice, UserSliceReader, UserSliceWriter},
+ workqueue::{impl_has_work, new_work, HasWork},
};

const RUST_MISC_DEV_HELLO: u32 = _IO('|' as u32, 0x80);
@@ -151,6 +153,42 @@ struct RustMiscDevice {
dev: ARef<Device>,
}

+#[pin_data]
+struct IoUringCmdWork {
+ #[pin]
+ ioucmd: Mutex<Option<(QueuedIoUringCmd, u32)>>,
+ #[pin]
+ work: kernel::workqueue::Work<IoUringCmdWork>,
+}
+
+impl_has_work! {
+ impl HasWork<Self> for IoUringCmdWork { self.work }
+}
+
+impl kernel::workqueue::WorkItem for IoUringCmdWork {
+ type Pointer = Arc<IoUringCmdWork>;
+
+ fn run(work: Arc<IoUringCmdWork>) {
+ pr_info!("IoUringCmdWork::run()");
+
+ if let Some((ioucmd, issue_flags)) = work.ioucmd.lock().take() {
+ ioucmd.done(Ok(0), 0, issue_flags);
+ }
+ }
+}
+
+impl IoUringCmdWork {
+ fn new(ioucmd: QueuedIoUringCmd, issue_flags: u32) -> Result<Arc<Self>> {
+ Arc::pin_init(
+ pin_init!(Self {
+ ioucmd <- new_mutex!(Some((ioucmd, issue_flags))),
+ work <- new_work!("IoUringCmdWork::work"),
+ }),
+ GFP_KERNEL,
+ )
+ }
+}
+
#[vtable]
impl MiscDevice for RustMiscDevice {
type Ptr = Pin<KBox<Self>>;
@@ -220,6 +258,19 @@ fn ioctl(me: Pin<&RustMiscDevice>, _file: &File, cmd: u32, arg: usize) -> Result

Ok(0)
}
+
+ fn uring_cmd(
+ me: Pin<&RustMiscDevice>,
+ ioucmd: IoUringCmd,
+ issue_flags: u32,
+ ) -> Result<UringCmdAction> {
+ dev_info!(me.dev, "UringCmd Rust Misc Device Sample\n");
+
+ let (action, queued_ioucmd) = ioucmd.queue();
+ let work = IoUringCmdWork::new(queued_ioucmd, issue_flags)?;
+ let _ = kernel::workqueue::system().enqueue(work);
+ Ok(action)
+ }
}

#[pinned_drop]
--
2.43.0