Skip to content

Commit

Permalink
tests: basic: cover data sharing in async test
Browse files Browse the repository at this point in the history
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
  • Loading branch information
ming1 committed Oct 22, 2023
1 parent bd783c5 commit aded72b
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
23 changes: 23 additions & 0 deletions tests/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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()
Expand All @@ -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
Expand All @@ -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;
Expand All @@ -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;
}
}
});
}
Expand All @@ -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();
Expand Down

0 comments on commit aded72b

Please sign in to comment.