Skip to content

Commit

Permalink
libublk: add UBLK_DEV_F_DONT_ALLOC_BUF
Browse files Browse the repository at this point in the history
Add UBLK_DEV_F_DONT_ALLOC_BUF for UBLK_DEV_F_ASYNC use, in which
user can allocate its own IO buffer, and provide it to ublk driver
if USER_COPY isn't enabled.

Also apply this flag on examples/ramdisk.c

Signed-off-by: Ming Lei <tom.leiming@gmail.com>
  • Loading branch information
ming1 committed Oct 28, 2023
1 parent 1f18127 commit 07ac33d
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 14 deletions.
10 changes: 9 additions & 1 deletion examples/null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,15 @@ fn __test_add(id: i32, nr_queues: u32, depth: u32, ctrl_flags: u64, buf_size: u3
.nr_queues(nr_queues)
.io_buf_bytes(buf_size)
.ctrl_flags(ctrl_flags)
.dev_flags(UBLK_DEV_F_ADD_DEV | if aio { UBLK_DEV_F_ASYNC } else { 0 })
.dev_flags(
UBLK_DEV_F_ADD_DEV
| if aio { UBLK_DEV_F_ASYNC } else { 0 }
| if (ctrl_flags & libublk::sys::UBLK_F_USER_COPY as u64) != 0 {
UBLK_DEV_F_DONT_ALLOC_BUF
} else {
0
},
)
.build()
.unwrap();
let tgt_init = |dev: &mut UblkDev| {
Expand Down
14 changes: 9 additions & 5 deletions examples/ramdisk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@ use libublk::io::{UblkDev, UblkQueue};
use libublk::{ctrl::UblkCtrl, exe::Executor, UblkError};
use std::rc::Rc;

fn handle_io(q: &UblkQueue, tag: u16, start: u64) -> i32 {
fn handle_io(q: &UblkQueue, tag: u16, buf_addr: *mut u8, start: u64) -> i32 {
let iod = q.get_iod(tag);
let off = (iod.start_sector << 9) as u64;
let bytes = (iod.nr_sectors << 9) as i32;
let op = iod.op_flags & 0xff;
let buf_addr = q.get_io_buf_addr(tag);

match op {
libublk::sys::UBLK_IO_OP_READ => unsafe {
Expand Down Expand Up @@ -45,7 +44,8 @@ fn rd_add_dev(dev_id: i32, buf_addr: u64, size: u64, for_add: bool) {
UBLK_DEV_F_ADD_DEV
} else {
UBLK_DEV_F_RECOVER_DEV
} | UBLK_DEV_F_ASYNC;
} | UBLK_DEV_F_ASYNC
| UBLK_DEV_F_DONT_ALLOC_BUF;

let depth = 128_u16;
let sess = libublk::UblkSessionBuilder::default()
Expand All @@ -66,20 +66,24 @@ fn rd_add_dev(dev_id: i32, buf_addr: u64, size: u64, for_add: bool) {

let exe = Executor::new(dev.get_nr_ios());
let q_rc = Rc::new(UblkQueue::new(0, &dev).unwrap());
let buf_size = dev.dev_info.max_io_buf_bytes as usize;

for tag in 0..depth as u16 {
let q = q_rc.clone();
assert!(q.get_io_buf_addr(tag) == std::ptr::null_mut());
exe.spawn(tag as u16, async move {
let addr = q.get_io_buf_addr(tag);
let mut buffer: Vec<u8> = vec![0; buf_size];
let addr = buffer.as_mut_ptr();
let mut cmd_op = libublk::sys::UBLK_IO_FETCH_REQ;
let mut res = 0;

loop {
let cmd_res = q.submit_io_cmd(tag, cmd_op, addr as u64, res).await;
if cmd_res == libublk::sys::UBLK_IO_RES_ABORT {
break;
}

res = handle_io(&q, tag, buf_addr);
res = handle_io(&q, tag, addr, buf_addr);
cmd_op = libublk::sys::UBLK_IO_COMMIT_AND_FETCH_REQ;
}
});
Expand Down
8 changes: 7 additions & 1 deletion src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,12 @@ impl UblkQueue<'_> {
let sq_depth = tgt.sq_depth;
let cq_depth = tgt.cq_depth;

if ((dev.flags & UBLK_DEV_F_ASYNC) == 0)
&& ((dev.dev_info.flags & (sys::UBLK_F_USER_COPY as u64)) == 0)
&& ((dev.flags & UBLK_DEV_F_DONT_ALLOC_BUF) != 0)
{
return Err(UblkError::OtherError(-libc::EINVAL));
}
let ring = IoUring::<squeue::Entry, cqueue::Entry>::builder()
.setup_cqsize(cq_depth as u32)
.setup_coop_taskrun()
Expand Down Expand Up @@ -521,7 +527,7 @@ impl UblkQueue<'_> {
// extra io slot needn't to allocate buffer
let addr = {
if i < depth {
if (dev.dev_info.flags & (super::sys::UBLK_F_USER_COPY as u64)) == 0 {
if (dev.flags & UBLK_DEV_F_DONT_ALLOC_BUF) == 0 {
super::ublk_alloc_buf(dev.dev_info.max_io_buf_bytes as usize, unsafe {
libc::sysconf(libc::_SC_PAGESIZE).try_into().unwrap()
})
Expand Down
10 changes: 8 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,14 @@ pub mod dev_flags {
/// use async/.await
pub const UBLK_DEV_F_ASYNC: u32 = 1u32 << 3;

pub const UBLK_DEV_F_ALL: u32 =
UBLK_DEV_F_COMP_BATCH | UBLK_DEV_F_ADD_DEV | UBLK_DEV_F_RECOVER_DEV | UBLK_DEV_F_ASYNC;
/// need to preallocate io buffer
pub const UBLK_DEV_F_DONT_ALLOC_BUF: u32 = 1u32 << 4;

pub const UBLK_DEV_F_ALL: u32 = UBLK_DEV_F_COMP_BATCH
| UBLK_DEV_F_ADD_DEV
| UBLK_DEV_F_RECOVER_DEV
| UBLK_DEV_F_ASYNC
| UBLK_DEV_F_DONT_ALLOC_BUF;
}

/// Ublk Fat completion result
Expand Down
16 changes: 11 additions & 5 deletions tests/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,10 @@ mod integration {
.wait_and_handle_io(io_handler);
}

__test_ublk_null(UBLK_DEV_F_ADD_DEV, null_handle_queue);
__test_ublk_null(
UBLK_DEV_F_ADD_DEV | UBLK_DEV_F_DONT_ALLOC_BUF,
null_handle_queue,
);
}

/// make one ublk-null and test if /dev/ublkbN can be created successfully
Expand All @@ -119,7 +122,7 @@ mod integration {
}

__test_ublk_null(
UBLK_DEV_F_ADD_DEV | UBLK_DEV_F_COMP_BATCH,
UBLK_DEV_F_ADD_DEV | UBLK_DEV_F_DONT_ALLOC_BUF | UBLK_DEV_F_COMP_BATCH,
null_handle_queue_batch,
);
}
Expand Down Expand Up @@ -192,11 +195,11 @@ mod integration {
let __dev_data = _dev_data.clone();

exe.spawn(tag as u16, async move {
let buf_addr = q.get_io_buf_addr(tag) as u64;
let mut cmd_op = sys::UBLK_IO_FETCH_REQ;
let buf = q.get_io_buf_addr(tag);
let mut res = 0;
loop {
let cmd_res = q.submit_io_cmd(tag, cmd_op, buf_addr, res).await;
let cmd_res = q.submit_io_cmd(tag, cmd_op, buf as u64, res).await;
if cmd_res == sys::UBLK_IO_RES_ABORT {
break;
}
Expand Down Expand Up @@ -353,7 +356,10 @@ mod integration {
.wait_and_handle_io(io_handler);
}

__test_ublk_null(UBLK_DEV_F_ADD_DEV, null_queue_mut_io);
__test_ublk_null(
UBLK_DEV_F_ADD_DEV | UBLK_DEV_F_DONT_ALLOC_BUF,
null_queue_mut_io,
);
}

/// run examples/ramdisk recovery test
Expand Down

0 comments on commit 07ac33d

Please sign in to comment.