rutabaga_gfx: replace VolatileSlice with IoSliceMut

This removes the rutabaga_gfx dependency on data_model.

BUG=b:273555494
TEST=tools/dev_container tools/presubmit

Change-Id: I03be8c8f9f722d368d90e6d9b0d7aeac475f2b06
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/4785448
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
Commit-Queue: Gurchetan Singh <gurchetansingh@chromium.org>
Reviewed-by: Frederick Mayle <fmayle@google.com>
This commit is contained in:
Daniel Verkamp 2023-08-16 12:49:08 -07:00 committed by crosvm LUCI
parent f53421d904
commit 695d254bcd
13 changed files with 89 additions and 129 deletions

1
Cargo.lock generated
View file

@ -2312,7 +2312,6 @@ version = "0.1.1-alpha.1"
dependencies = [
"anyhow",
"cfg-if",
"data_model 0.1.1-alpha.1",
"libc",
"log",
"nix",

View file

@ -5,6 +5,7 @@
use std::cell::RefCell;
use std::collections::BTreeMap as Map;
use std::collections::BTreeSet as Set;
use std::io::IoSliceMut;
use std::num::NonZeroU32;
use std::rc::Rc;
use std::result::Result;
@ -242,12 +243,11 @@ impl VirtioGpuScanout {
let mut transfer = Transfer3D::new_2d(0, 0, self.width, self.height);
transfer.stride = fb.stride();
rutabaga.transfer_read(
0,
resource.resource_id,
transfer,
Some(fb.as_volatile_slice()),
)?;
let fb_slice = fb.as_volatile_slice();
let buf = IoSliceMut::new(unsafe {
std::slice::from_raw_parts_mut(fb_slice.as_mut_ptr(), fb_slice.size())
});
rutabaga.transfer_read(0, resource.resource_id, transfer, Some(buf))?;
display.flip(surface_id);
Ok(OkNoData)
@ -780,6 +780,9 @@ impl VirtioGpu {
transfer: Transfer3D,
buf: Option<VolatileSlice>,
) -> VirtioGpuResult {
let buf = buf.map(|vs| {
IoSliceMut::new(unsafe { std::slice::from_raw_parts_mut(vs.as_mut_ptr(), vs.size()) })
});
self.rutabaga
.transfer_read(ctx_id, resource_id, transfer, buf)?;
Ok(OkNoData)

View file

@ -19,7 +19,6 @@ x = []
[dependencies]
cfg-if = "1.0.0"
data_model = { path = "../common/data_model", version = "0.1.1-alpha.1"}
libc = "0.2.116"
remain = "0.2"
thiserror = "1.0.23"

View file

@ -11,7 +11,6 @@ crate-type = ["cdylib", "staticlib"]
[dependencies]
rutabaga_gfx = { path = "../", version = "0.1.1-alpha.1"}
data_model = {path = "../../common/data_model", version = "0.1.1-alpha.1"}
libc = "0.2.93"
log = "0.4"
once_cell = "1.7"

View file

@ -8,6 +8,7 @@ extern crate rutabaga_gfx;
use std::convert::TryInto;
use std::ffi::CStr;
use std::ffi::CString;
use std::io::IoSliceMut;
use std::os::raw::c_char;
use std::os::raw::c_void;
use std::panic::catch_unwind;
@ -20,7 +21,6 @@ use std::slice::from_raw_parts;
use std::slice::from_raw_parts_mut;
use std::sync::Mutex;
use data_model::VolatileSlice;
use libc::iovec;
use libc::EINVAL;
use libc::ESRCH;
@ -429,10 +429,10 @@ pub unsafe extern "C" fn rutabaga_resource_transfer_read(
catch_unwind(AssertUnwindSafe(|| {
let mut slice_opt = None;
if let Some(iovec) = buf {
slice_opt = Some(VolatileSlice::from_raw_parts(
slice_opt = Some(IoSliceMut::new(std::slice::from_raw_parts_mut(
iovec.iov_base as *mut u8,
iovec.iov_len,
));
)));
}
let result = ptr.transfer_read(ctx_id, resource_id, *transfer, slice_opt);

View file

@ -11,13 +11,11 @@ use std::collections::VecDeque;
use std::convert::TryInto;
use std::fs::File;
use std::mem::size_of;
use std::ptr::copy_nonoverlapping;
use std::sync::Arc;
use std::sync::Condvar;
use std::sync::Mutex;
use std::thread;
use data_model::VolatileSlice;
use log::error;
use zerocopy::AsBytes;
use zerocopy::FromBytes;
@ -234,32 +232,31 @@ impl CrossDomainState {
// Safe because we've verified the iovecs are attached and owned only by this context.
let slice =
unsafe { VolatileSlice::from_raw_parts(iovecs[0].base as *mut u8, iovecs[0].len) };
unsafe { std::slice::from_raw_parts_mut(iovecs[0].base as *mut u8, iovecs[0].len) };
match ring_write {
RingWrite::Write(cmd, opaque_data_opt) => {
slice.copy_from(&[cmd]);
if slice.len() < size_of::<T>() {
return Err(RutabagaError::InvalidIovec);
}
let (cmd_slice, opaque_data_slice) = slice.split_at_mut(size_of::<T>());
cmd_slice.copy_from_slice(cmd.as_bytes());
if let Some(opaque_data) = opaque_data_opt {
let offset = size_of::<T>();
let sub_slice = slice.sub_slice(offset, opaque_data.len())?;
let dst_ptr = sub_slice.as_mut_ptr();
let src_ptr = opaque_data.as_ptr();
// Safe because:
//
// (1) The volatile slice has atleast `opaque_data.len()' bytes.
// (2) The both the destination and source are non-overlapping.
unsafe {
copy_nonoverlapping(src_ptr, dst_ptr, opaque_data.len());
if opaque_data_slice.len() < opaque_data.len() {
return Err(RutabagaError::InvalidIovec);
}
opaque_data_slice[..opaque_data.len()].copy_from_slice(opaque_data);
}
}
RingWrite::WriteFromFile(mut cmd_read, ref mut file, readable) => {
let offset = size_of::<CrossDomainReadWrite>();
let sub_slice = slice.offset(offset)?;
if slice.len() < size_of::<CrossDomainReadWrite>() {
return Err(RutabagaError::InvalidIovec);
}
let (cmd_slice, opaque_data_slice) =
slice.split_at_mut(size_of::<CrossDomainReadWrite>());
if readable {
bytes_read = read_volatile(file, sub_slice)?;
bytes_read = read_volatile(file, opaque_data_slice)?;
}
if bytes_read == 0 {
@ -267,7 +264,7 @@ impl CrossDomainState {
}
cmd_read.opaque_data_size = bytes_read.try_into()?;
slice.copy_from(&[cmd_read]);
cmd_slice.copy_from_slice(cmd_read.as_bytes());
}
}
@ -601,11 +598,7 @@ impl CrossDomainContext {
}
}
fn write(
&self,
cmd_write: &CrossDomainReadWrite,
opaque_data: VolatileSlice,
) -> RutabagaResult<()> {
fn write(&self, cmd_write: &CrossDomainReadWrite, opaque_data: &[u8]) -> RutabagaResult<()> {
let mut items = self.item_state.lock().unwrap();
// Most of the time, hang-up and writing will be paired. In lieu of this, remove the
@ -804,16 +797,14 @@ impl RutabagaContext for CrossDomainContext {
let cmd_send = CrossDomainSendReceive::read_from_prefix(commands.as_bytes())
.ok_or(RutabagaError::InvalidCommandBuffer)?;
let opaque_data = VolatileSlice::new(
commands
.get_mut(
opaque_data_offset
..opaque_data_offset + cmd_send.opaque_data_size as usize,
)
.ok_or(RutabagaError::InvalidCommandSize(
cmd_send.opaque_data_size as usize,
))?,
);
let opaque_data = commands
.get_mut(
opaque_data_offset
..opaque_data_offset + cmd_send.opaque_data_size as usize,
)
.ok_or(RutabagaError::InvalidCommandSize(
cmd_send.opaque_data_size as usize,
))?;
self.send(&cmd_send, opaque_data)?;
}
@ -825,16 +816,14 @@ impl RutabagaContext for CrossDomainContext {
let cmd_write = CrossDomainReadWrite::read_from_prefix(commands.as_bytes())
.ok_or(RutabagaError::InvalidCommandBuffer)?;
let opaque_data = VolatileSlice::new(
commands
.get_mut(
opaque_data_offset
..opaque_data_offset + cmd_write.opaque_data_size as usize,
)
.ok_or(RutabagaError::InvalidCommandSize(
cmd_write.opaque_data_size as usize,
))?,
);
let opaque_data = commands
.get_mut(
opaque_data_offset
..opaque_data_offset + cmd_write.opaque_data_size as usize,
)
.ok_or(RutabagaError::InvalidCommandSize(
cmd_write.opaque_data_size as usize,
))?;
self.write(&cmd_write, opaque_data)?;
}

View file

@ -4,8 +4,6 @@
use std::fs::File;
use data_model::VolatileSlice;
use super::super::cross_domain_protocol::CrossDomainInit;
use super::super::cross_domain_protocol::CrossDomainSendReceive;
use super::super::CrossDomainContext;
@ -47,7 +45,7 @@ impl CrossDomainContext {
pub(crate) fn send(
&self,
_cmd_send: &CrossDomainSendReceive,
_opaque_data: VolatileSlice,
_opaque_data: &[u8],
) -> RutabagaResult<()> {
Err(RutabagaError::Unsupported)
}
@ -64,11 +62,11 @@ pub fn channel_wait(_receiver: &Receiver) -> RutabagaResult<()> {
Err(RutabagaError::Unsupported)
}
pub fn read_volatile(_file: &File, _opaque_data: VolatileSlice) -> RutabagaResult<usize> {
pub fn read_volatile(_file: &File, _opaque_data: &mut [u8]) -> RutabagaResult<usize> {
Err(RutabagaError::Unsupported)
}
pub fn write_volatile(_file: &File, _opaque_data: VolatileSlice) -> RutabagaResult<()> {
pub fn write_volatile(_file: &File, _opaque_data: &[u8]) -> RutabagaResult<()> {
Err(RutabagaError::Unsupported)
}

View file

@ -11,7 +11,6 @@ use std::os::unix::io::AsRawFd;
use std::os::unix::io::FromRawFd;
use std::os::unix::prelude::AsFd;
use data_model::VolatileSlice;
use libc::O_ACCMODE;
use libc::O_WRONLY;
use nix::cmsg_space;
@ -86,20 +85,12 @@ pub fn descriptor_analysis(
}
impl CrossDomainState {
fn send_msg(
&self,
opaque_data: VolatileSlice,
descriptors: &[RawDescriptor],
) -> RutabagaResult<usize> {
let mut vec = vec![0; opaque_data.size()];
opaque_data.copy_to(&mut vec);
let iovecs = IoSlice::new(&vec);
fn send_msg(&self, opaque_data: &[u8], descriptors: &[RawDescriptor]) -> RutabagaResult<usize> {
let cmsg = ControlMessage::ScmRights(descriptors);
if let Some(connection) = &self.connection {
let bytes_sent = sendmsg::<()>(
connection.as_raw_descriptor(),
&[iovecs],
&[IoSlice::new(opaque_data)],
&[cmsg],
MsgFlags::empty(),
None,
@ -177,7 +168,7 @@ impl CrossDomainContext {
pub(crate) fn send(
&self,
cmd_send: &CrossDomainSendReceive,
opaque_data: VolatileSlice,
opaque_data: &[u8],
) -> RutabagaResult<()> {
let mut descriptors = [0; CROSS_DOMAIN_MAX_IDENTIFIERS];
@ -275,22 +266,13 @@ pub fn channel_wait(receiver: &Receiver) -> RutabagaResult<()> {
Ok(())
}
pub fn read_volatile(file: &File, opaque_data: VolatileSlice) -> RutabagaResult<usize> {
let mut vec = vec![0; opaque_data.size()];
let byte_slice: &mut [u8] = &mut vec;
let bytes_read = read(file.as_raw_fd(), byte_slice)?;
opaque_data.copy_from(&vec);
pub fn read_volatile(file: &File, opaque_data: &mut [u8]) -> RutabagaResult<usize> {
let bytes_read = read(file.as_raw_fd(), opaque_data)?;
Ok(bytes_read)
}
pub fn write_volatile(file: &File, opaque_data: VolatileSlice) -> RutabagaResult<()> {
let mut vec = vec![0; opaque_data.size()];
opaque_data.copy_to(&mut vec);
let byte_slice: &mut [u8] = &mut vec;
write(file.as_raw_fd(), byte_slice)?;
pub fn write_volatile(file: &File, opaque_data: &[u8]) -> RutabagaResult<()> {
write(file.as_raw_fd(), opaque_data)?;
Ok(())
}

View file

@ -9,6 +9,7 @@
#![cfg(feature = "gfxstream")]
use std::convert::TryInto;
use std::io::IoSliceMut;
use std::mem::size_of;
use std::os::raw::c_char;
use std::os::raw::c_int;
@ -20,8 +21,6 @@ use std::ptr::null;
use std::ptr::null_mut;
use std::sync::Arc;
use data_model::VolatileSlice;
use crate::generated::virgl_renderer_bindings::iovec;
use crate::generated::virgl_renderer_bindings::virgl_box;
use crate::generated::virgl_renderer_bindings::virgl_renderer_resource_create_args;
@ -538,7 +537,7 @@ impl RutabagaComponent for Gfxstream {
ctx_id: u32,
resource: &mut RutabagaResource,
transfer: Transfer3D,
buf: Option<VolatileSlice>,
buf: Option<IoSliceMut>,
) -> RutabagaResult<()> {
if transfer.is_empty() {
return Ok(());
@ -559,9 +558,9 @@ impl RutabagaComponent for Gfxstream {
};
let (iovecs, num_iovecs) = match buf {
Some(buf) => {
iov.base = buf.as_ptr() as *mut c_void;
iov.len = buf.size();
Some(mut buf) => {
iov.base = buf.as_mut_ptr() as *mut c_void;
iov.len = buf.len();
(&mut iov as *mut RutabagaIovec as *mut iovec, 1)
}
None => (null_mut(), 0),

View file

@ -7,17 +7,15 @@
use std::cmp::max;
use std::cmp::min;
use std::cmp::Ordering;
use data_model::VolatileMemory;
use data_model::VolatileSlice;
use std::io::IoSliceMut;
use crate::rutabaga_core::Rutabaga2DInfo;
use crate::rutabaga_core::RutabagaComponent;
use crate::rutabaga_core::RutabagaResource;
use crate::rutabaga_utils::*;
/// Transfers a resource from potentially many chunked src VolatileSlices to a dst VolatileSlice.
pub fn transfer_2d<'a, S: Iterator<Item = VolatileSlice<'a>>>(
/// Transfers a resource from potentially many chunked src slices to a dst slice.
fn transfer_2d(
resource_w: u32,
resource_h: u32,
rect_x: u32,
@ -26,10 +24,10 @@ pub fn transfer_2d<'a, S: Iterator<Item = VolatileSlice<'a>>>(
rect_h: u32,
dst_stride: u32,
dst_offset: u64,
dst: VolatileSlice,
mut dst: IoSliceMut,
src_stride: u32,
src_offset: u64,
mut srcs: S,
srcs: &[&[u8]],
) -> RutabagaResult<()> {
if rect_w == 0 || rect_h == 0 {
return Ok(());
@ -56,6 +54,7 @@ pub fn transfer_2d<'a, S: Iterator<Item = VolatileSlice<'a>>>(
let mut next_src;
let mut next_line;
let mut current_height = 0u64;
let mut srcs = srcs.iter();
let mut src_opt = srcs.next();
// Cumulative start offset of the current src.
@ -65,7 +64,7 @@ pub fn transfer_2d<'a, S: Iterator<Item = VolatileSlice<'a>>>(
break;
}
let src_size = src.size() as u64;
let src_size = src.len() as u64;
// Cumulative end offset of the current src.
let src_end_offset = checked_arithmetic!(src_start_offset + src_size)?;
@ -104,7 +103,10 @@ pub fn transfer_2d<'a, S: Iterator<Item = VolatileSlice<'a>>>(
}
}
let src_subslice = src.get_slice(offset_within_src as usize, copyable_size as usize)?;
let src_end = offset_within_src + copyable_size;
let src_subslice = src
.get(offset_within_src as usize..src_end as usize)
.ok_or(RutabagaError::InvalidIovec)?;
let dst_line_vertical_offset = checked_arithmetic!(current_height * dst_stride)?;
let dst_line_horizontal_offset =
@ -113,9 +115,12 @@ pub fn transfer_2d<'a, S: Iterator<Item = VolatileSlice<'a>>>(
checked_arithmetic!(dst_line_vertical_offset + dst_line_horizontal_offset)?;
let dst_start_offset = checked_arithmetic!(dst_resource_offset + dst_line_offset)?;
let dst_subslice = dst.get_slice(dst_start_offset as usize, copyable_size as usize)?;
let dst_end_offset = dst_start_offset + copyable_size;
let dst_subslice = dst
.get_mut(dst_start_offset as usize..dst_end_offset as usize)
.ok_or(RutabagaError::InvalidIovec)?;
src_subslice.copy_to_volatile_slice(dst_subslice);
dst_subslice.copy_from_slice(src_subslice);
} else if src_line_start_offset >= src_start_offset {
next_src = true;
next_line = false;
@ -210,7 +215,7 @@ impl RutabagaComponent for Rutabaga2D {
let mut src_slices = Vec::with_capacity(iovecs.len());
for iovec in &iovecs {
// Safe because Rutabaga users should have already checked the iovecs.
let slice = unsafe { VolatileSlice::from_raw_parts(iovec.base as *mut u8, iovec.len) };
let slice = unsafe { std::slice::from_raw_parts(iovec.base as *mut u8, iovec.len) };
src_slices.push(slice);
}
@ -229,10 +234,10 @@ impl RutabagaComponent for Rutabaga2D {
transfer.h,
dst_stride,
dst_offset,
VolatileSlice::new(info_2d.host_mem.as_mut_slice()),
IoSliceMut::new(info_2d.host_mem.as_mut_slice()),
src_stride,
src_offset,
src_slices.iter().cloned(),
&src_slices,
)?;
resource.info_2d = Some(info_2d);
@ -245,7 +250,7 @@ impl RutabagaComponent for Rutabaga2D {
_ctx_id: u32,
resource: &mut RutabagaResource,
transfer: Transfer3D,
buf: Option<VolatileSlice>,
buf: Option<IoSliceMut>,
) -> RutabagaResult<()> {
let mut info_2d = resource
.info_2d
@ -274,9 +279,7 @@ impl RutabagaComponent for Rutabaga2D {
dst_slice,
src_stride,
src_offset,
[VolatileSlice::new(info_2d.host_mem.as_mut_slice())]
.iter()
.cloned(),
&[info_2d.host_mem.as_mut_slice()],
)?;
resource.info_2d = Some(info_2d);

View file

@ -5,10 +5,9 @@
//! rutabaga_core: Cross-platform, Rust-based, Wayland and Vulkan centric GPU virtualization.
use std::collections::BTreeMap as Map;
use std::convert::TryInto;
use std::io::IoSliceMut;
use std::sync::Arc;
use data_model::VolatileSlice;
use crate::cross_domain::CrossDomain;
#[cfg(feature = "gfxstream")]
@ -147,7 +146,7 @@ pub trait RutabagaComponent {
_ctx_id: u32,
_resource: &mut RutabagaResource,
_transfer: Transfer3D,
_buf: Option<VolatileSlice>,
_buf: Option<IoSliceMut>,
) -> RutabagaResult<()> {
Ok(())
}
@ -540,7 +539,7 @@ impl Rutabaga {
ctx_id: u32,
resource_id: u32,
transfer: Transfer3D,
buf: Option<VolatileSlice>,
buf: Option<IoSliceMut>,
) -> RutabagaResult<()> {
let component = self
.components

View file

@ -14,7 +14,6 @@ use std::path::PathBuf;
use std::str::Utf8Error;
use std::sync::Arc;
use data_model::VolatileMemoryError;
#[cfg(unix)]
use nix::Error as NixError;
use remain::sorted;
@ -311,9 +310,6 @@ pub enum RutabagaError {
#[cfg(feature = "vulkano")]
#[error("vulkano memory map failure {0}")]
VkMemoryMapError(MemoryMapError),
/// Volatile memory error
#[error("noticed a volatile memory error {0}")]
VolatileMemoryError(VolatileMemoryError),
}
#[cfg(unix)]
@ -347,12 +343,6 @@ impl From<Utf8Error> for RutabagaError {
}
}
impl From<VolatileMemoryError> for RutabagaError {
fn from(e: VolatileMemoryError) -> RutabagaError {
RutabagaError::VolatileMemoryError(e)
}
}
/// The result of an operation in this crate.
pub type RutabagaResult<T> = std::result::Result<T, RutabagaError>;

View file

@ -10,6 +10,7 @@
use std::cmp::min;
use std::convert::TryFrom;
use std::io::Error as SysError;
use std::io::IoSliceMut;
use std::mem::size_of;
use std::mem::transmute;
use std::os::raw::c_char;
@ -23,7 +24,6 @@ use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;
use std::sync::Arc;
use data_model::VolatileSlice;
use log::debug;
use log::error;
use log::warn;
@ -576,7 +576,7 @@ impl RutabagaComponent for VirglRenderer {
ctx_id: u32,
resource: &mut RutabagaResource,
transfer: Transfer3D,
buf: Option<VolatileSlice>,
buf: Option<IoSliceMut>,
) -> RutabagaResult<()> {
if transfer.is_empty() {
return Ok(());
@ -597,9 +597,9 @@ impl RutabagaComponent for VirglRenderer {
};
let (iovecs, num_iovecs) = match buf {
Some(buf) => {
iov.base = buf.as_ptr() as *mut c_void;
iov.len = buf.size();
Some(mut buf) => {
iov.base = buf.as_mut_ptr() as *mut c_void;
iov.len = buf.len();
(&mut iov as *mut RutabagaIovec as *mut iovec, 1)
}
None => (null_mut(), 0),