From aded72b6b175e977f8ebadd9aba23c4aca3ae703 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Sat, 21 Oct 2023 15:41:55 +0000 Subject: [PATCH] tests: basic: cover data sharing in async test Signed-off-by: Ming Lei --- README.md | 8 ++++++++ tests/basic.rs | 23 +++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/README.md b/README.md index 4fb1d28..fb66bbf 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,14 @@ be nested inside handle_io_cmd(). }; ``` +Device wide data can be shared in each queue/io handler by +Arc::new(Mutex::new(Data)) and the queue handler closure supports Clone(), +see [`test_ublk_null_async():tests/basic.rs`](tests/basic.rs) + +Queue wide data is per-thread and can be shared in io handler by +Rc() & RefCell(). + + ## unprivileged ublk support In unprivileged mode(`UBLK_F_UNPRIVILEGED_DEV`), ublk device can be created diff --git a/tests/basic.rs b/tests/basic.rs index f03cc6f..759c2f2 100644 --- a/tests/basic.rs +++ b/tests/basic.rs @@ -10,6 +10,7 @@ mod integration { use std::path::Path; use std::process::{Command, Stdio}; use std::rc::Rc; + use std::sync::{Arc, Mutex}; fn run_ublk_disk_sanity_test(ctrl: &mut UblkCtrl, dev_flags: u32) { use std::os::unix::fs::PermissionsExt; @@ -151,6 +152,11 @@ mod integration { bytes + null_submit_nop(&q, data).await } + //Device wide data shared among all queue context + struct DevData { + done: u64, + } + // submit one io_uring Nop via io-uring crate and UringOpFuture, and // user_data has to unique among io tasks, also has to encode tag // info, so please build user_data by UblkIOCtx::build_user_data_async() @@ -169,6 +175,9 @@ mod integration { dev.set_default_params(250_u64 << 30); Ok(serde_json::json!({})) }; + // device data is shared among all queue contexts + let dev_data = Arc::new(Mutex::new(DevData { done: 0 })); + let wh_dev_data = dev_data.clone(); let (mut ctrl, dev) = sess.create_devices(tgt_init).unwrap(); // queue handler supports Clone(), so will be cloned in each @@ -177,8 +186,13 @@ mod integration { let q_rc = Rc::new(UblkQueue::new(qid as u16, &dev, false).unwrap()); let exe = Executor::new(dev.get_nr_ios()); + // `q_fn` closure implements Clone() Trait, so the captured + // `dev_data` is cloned to `q_fn` context. + let _dev_data = Rc::new(dev_data); + for tag in 0..depth { let q = q_rc.clone(); + let __dev_data = _dev_data.clone(); exe.spawn(tag as u16, async move { let buf_addr = q.get_io_buf_addr(tag) as u64; @@ -192,6 +206,10 @@ mod integration { res = handle_io_cmd(&q, tag).await; cmd_op = sys::UBLK_IO_COMMIT_AND_FETCH_REQ; + { + let mut guard = __dev_data.lock().unwrap(); + (*guard).done += 1; + } } }); } @@ -206,6 +224,11 @@ mod integration { run_ublk_disk_sanity_test(&mut ctrl, dev_flags); read_ublk_disk(dev_id); + { + let guard = wh_dev_data.lock().unwrap(); + assert!((*guard).done > 0); + } + ctrl.del().unwrap(); }) .unwrap();