Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/vmm/src/devices/virtio/block/virtio/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub enum FileEngineType {
#[derive(Debug)]
pub struct DiskProperties {
pub file_path: String,
pub file_engine: FileEngine<PendingRequest>,
pub file_engine: FileEngine,
pub nsectors: u64,
pub image_id: [u8; VIRTIO_BLK_ID_BYTES as usize],
}
Expand Down
82 changes: 41 additions & 41 deletions src/vmm/src/devices/virtio/block/virtio/io/async_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
use vm_memory::GuestMemoryError;
use vmm_sys_util::eventfd::EventFd;

use crate::devices::virtio::block::virtio::IO_URING_NUM_ENTRIES;
use crate::devices::virtio::block::virtio::io::UserDataError;
use crate::devices::virtio::block::virtio::io::RequestError;
use crate::devices::virtio::block::virtio::{IO_URING_NUM_ENTRIES, PendingRequest};
use crate::io_uring::operation::{Cqe, OpCode, Operation};
use crate::io_uring::restriction::Restriction;
use crate::io_uring::{self, IoUring, IoUringError};
use crate::io_uring::{IoUring, IoUringError};
use crate::logger::log_dev_preview_warning;
use crate::vstate::memory::{GuestAddress, GuestMemory, GuestMemoryExtension, GuestMemoryMmap};

Expand All @@ -34,47 +34,44 @@
}

#[derive(Debug)]
pub struct AsyncFileEngine<T> {
pub struct AsyncFileEngine {
file: File,
ring: IoUring<WrappedUserData<T>>,
ring: IoUring<WrappedRequest>,
completion_evt: EventFd,
}

#[derive(Debug)]
pub struct WrappedUserData<T> {
pub struct WrappedRequest {
addr: Option<GuestAddress>,
user_data: T,
req: PendingRequest,
}

impl<T: Debug> WrappedUserData<T> {
fn new(user_data: T) -> Self {
WrappedUserData {
addr: None,
user_data,
}
impl WrappedRequest {
fn new(req: PendingRequest) -> Self {
WrappedRequest { addr: None, req }
}

fn new_with_dirty_tracking(addr: GuestAddress, user_data: T) -> Self {
WrappedUserData {
fn new_with_dirty_tracking(addr: GuestAddress, req: PendingRequest) -> Self {
WrappedRequest {
addr: Some(addr),
user_data,
req,
}
}

fn mark_dirty_mem_and_unwrap(self, mem: &GuestMemoryMmap, count: u32) -> T {
fn mark_dirty_mem_and_unwrap(self, mem: &GuestMemoryMmap, count: u32) -> PendingRequest {
if let Some(addr) = self.addr {
mem.mark_dirty(addr, count as usize)
}

self.user_data
self.req
}
}

impl<T: Debug> AsyncFileEngine<T> {
impl AsyncFileEngine {
fn new_ring(
file: &File,
completion_fd: RawFd,
) -> Result<IoUring<WrappedUserData<T>>, io_uring::IoUringError> {
) -> Result<IoUring<WrappedRequest>, IoUringError> {
IoUring::new(
u32::from(IO_URING_NUM_ENTRIES),
vec![file],
Expand All @@ -90,7 +87,7 @@
)
}

pub fn from_file(file: File) -> Result<AsyncFileEngine<T>, AsyncIoError> {
pub fn from_file(file: File) -> Result<AsyncFileEngine, AsyncIoError> {
log_dev_preview_warning("Async file IO", Option::None);

let completion_evt = EventFd::new(libc::EFD_NONBLOCK).map_err(AsyncIoError::EventFd)?;
Expand Down Expand Up @@ -128,19 +125,19 @@
mem: &GuestMemoryMmap,
addr: GuestAddress,
count: u32,
user_data: T,
) -> Result<(), UserDataError<T, AsyncIoError>> {
req: PendingRequest,
) -> Result<(), RequestError<AsyncIoError>> {
let buf = match mem.get_slice(addr, count as usize) {
Ok(slice) => slice.ptr_guard_mut().as_ptr(),
Err(err) => {
return Err(UserDataError {
user_data,
return Err(RequestError {
req,
error: AsyncIoError::GuestMemory(err),
});
}
};

let wrapped_user_data = WrappedUserData::new_with_dirty_tracking(addr, user_data);
let wrapped_user_data = WrappedRequest::new_with_dirty_tracking(addr, req);

self.ring
.push(Operation::read(
Expand All @@ -150,8 +147,8 @@
offset,
wrapped_user_data,
))
.map_err(|(io_uring_error, data)| UserDataError {
user_data: data.user_data,
.map_err(|(io_uring_error, data)| RequestError {
req: data.req,

Check warning on line 151 in src/vmm/src/devices/virtio/block/virtio/io/async_io.rs

View check run for this annotation

Codecov / codecov/patch

src/vmm/src/devices/virtio/block/virtio/io/async_io.rs#L151

Added line #L151 was not covered by tests
error: AsyncIoError::IoUring(io_uring_error),
})
}
Expand All @@ -162,19 +159,19 @@
mem: &GuestMemoryMmap,
addr: GuestAddress,
count: u32,
user_data: T,
) -> Result<(), UserDataError<T, AsyncIoError>> {
req: PendingRequest,
) -> Result<(), RequestError<AsyncIoError>> {
let buf = match mem.get_slice(addr, count as usize) {
Ok(slice) => slice.ptr_guard_mut().as_ptr(),
Err(err) => {
return Err(UserDataError {
user_data,
return Err(RequestError {
req,
error: AsyncIoError::GuestMemory(err),
});
}
};

let wrapped_user_data = WrappedUserData::new(user_data);
let wrapped_user_data = WrappedRequest::new(req);

self.ring
.push(Operation::write(
Expand All @@ -184,19 +181,19 @@
offset,
wrapped_user_data,
))
.map_err(|(io_uring_error, data)| UserDataError {
user_data: data.user_data,
.map_err(|(io_uring_error, data)| RequestError {
req: data.req,

Check warning on line 185 in src/vmm/src/devices/virtio/block/virtio/io/async_io.rs

View check run for this annotation

Codecov / codecov/patch

src/vmm/src/devices/virtio/block/virtio/io/async_io.rs#L185

Added line #L185 was not covered by tests
error: AsyncIoError::IoUring(io_uring_error),
})
}

pub fn push_flush(&mut self, user_data: T) -> Result<(), UserDataError<T, AsyncIoError>> {
let wrapped_user_data = WrappedUserData::new(user_data);
pub fn push_flush(&mut self, req: PendingRequest) -> Result<(), RequestError<AsyncIoError>> {
let wrapped_user_data = WrappedRequest::new(req);

self.ring
.push(Operation::fsync(0, wrapped_user_data))
.map_err(|(io_uring_error, data)| UserDataError {
user_data: data.user_data,
.map_err(|(io_uring_error, data)| RequestError {
req: data.req,
error: AsyncIoError::IoUring(io_uring_error),
})
}
Expand Down Expand Up @@ -233,11 +230,14 @@
Ok(())
}

fn do_pop(&mut self) -> Result<Option<Cqe<WrappedUserData<T>>>, AsyncIoError> {
fn do_pop(&mut self) -> Result<Option<Cqe<WrappedRequest>>, AsyncIoError> {
self.ring.pop().map_err(AsyncIoError::IoUring)
}

pub fn pop(&mut self, mem: &GuestMemoryMmap) -> Result<Option<Cqe<T>>, AsyncIoError> {
pub fn pop(
&mut self,
mem: &GuestMemoryMmap,
) -> Result<Option<Cqe<PendingRequest>>, AsyncIoError> {
let cqe = self.do_pop()?.map(|cqe| {
let count = cqe.count();
cqe.map_user_data(|wrapped_user_data| {
Expand Down
Loading