Skip to content
Closed
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: 2 additions & 0 deletions vhost-device-gpu/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

### Added

- [https://github.com/rust-vmm/vhost-device/pull/900] vhost-device-gpu: Add support for specifying GPU path

### Changed

### Fixed
Expand Down
3 changes: 3 additions & 0 deletions vhost-device-gpu/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ A virtio-gpu device using the vhost-user protocol.
[default: true]
[possible values: true, false]

-p, --gpu-path <PATH>
GPU path (e.g. /dev/dri/renderD128), only available for virglrenderer backend

-h, --help
Print help (see a summary with '-h')

Expand Down
3 changes: 2 additions & 1 deletion vhost-device-gpu/src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,7 @@ mod tests {
GpuMode::VirglRenderer,
Some(GpuCapset::VIRGL | GpuCapset::VIRGL2),
GpuFlags::default(),
None,
)
.unwrap();
let backend = VhostUserGpuBackend::new(config).unwrap();
Expand Down Expand Up @@ -1353,7 +1354,7 @@ mod tests {
rusty_fork_test! {
#[test]
fn test_verify_backend() {
let gpu_config = GpuConfig::new(GpuMode::VirglRenderer, None, GpuFlags::default()).unwrap();
let gpu_config = GpuConfig::new(GpuMode::VirglRenderer, None, GpuFlags::default(), None).unwrap();
let backend = VhostUserGpuBackend::new(gpu_config).unwrap();

assert_eq!(backend.num_queues(), NUM_QUEUES);
Expand Down
16 changes: 11 additions & 5 deletions vhost-device-gpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ pub struct GpuConfig {
gpu_mode: GpuMode,
capset: GpuCapset,
flags: GpuFlags,
gpu_path: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Eq)]
Expand Down Expand Up @@ -198,6 +199,7 @@ impl GpuConfig {
gpu_mode: GpuMode,
capset: Option<GpuCapset>,
flags: GpuFlags,
gpu_path: Option<String>,
) -> Result<Self, GpuConfigError> {
let capset = capset.unwrap_or_else(|| Self::get_default_capset_for_mode(gpu_mode));
Self::validate_capset(gpu_mode, capset)?;
Expand All @@ -211,6 +213,7 @@ impl GpuConfig {
gpu_mode,
capset,
flags,
gpu_path,
})
}

Expand Down Expand Up @@ -263,22 +266,23 @@ mod tests {

#[test]
fn test_gpu_config_create_default_virglrenderer() {
let config = GpuConfig::new(GpuMode::VirglRenderer, None, GpuFlags::new_default()).unwrap();
let config =
GpuConfig::new(GpuMode::VirglRenderer, None, GpuFlags::new_default(), None).unwrap();
assert_eq!(config.gpu_mode(), GpuMode::VirglRenderer);
assert_eq!(config.capsets(), GpuConfig::DEFAULT_VIRGLRENDER_CAPSET_MASK);
}

#[test]
#[cfg(feature = "gfxstream")]
fn test_gpu_config_create_default_gfxstream() {
let config = GpuConfig::new(GpuMode::Gfxstream, None, GpuFlags::default()).unwrap();
let config = GpuConfig::new(GpuMode::Gfxstream, None, GpuFlags::default(), None).unwrap();
assert_eq!(config.gpu_mode(), GpuMode::Gfxstream);
assert_eq!(config.capsets(), GpuConfig::DEFAULT_GFXSTREAM_CAPSET_MASK);
}

#[cfg(feature = "gfxstream")]
fn assert_invalid_gpu_config(mode: GpuMode, capset: GpuCapset, expected_capset: GpuCapset) {
let result = GpuConfig::new(mode, Some(capset), GpuFlags::new_default());
let result = GpuConfig::new(mode, Some(capset), GpuFlags::new_default(), None);
assert_matches!(
result,
Err(GpuConfigError::CapsetUnsupportedByMode(
Expand All @@ -294,6 +298,7 @@ mod tests {
GpuMode::VirglRenderer,
Some(GpuCapset::VIRGL2),
GpuFlags::default(),
None,
)
.unwrap();
assert_eq!(config.gpu_mode(), GpuMode::VirglRenderer);
Expand Down Expand Up @@ -323,7 +328,7 @@ mod tests {
use_gles: false,
..GpuFlags::new_default()
};
let result = GpuConfig::new(GpuMode::Gfxstream, Some(capset), flags);
let result = GpuConfig::new(GpuMode::Gfxstream, Some(capset), flags, None);
assert_matches!(result, Err(GpuConfigError::GlesRequiredByGfxstream));
}

Expand Down Expand Up @@ -355,7 +360,8 @@ mod tests {
fn test_fail_listener() {
// This will fail the listeners and thread will panic.
let socket_name = Path::new("/proc/-1/nonexistent");
let config = GpuConfig::new(GpuMode::VirglRenderer, None, GpuFlags::default()).unwrap();
let config =
GpuConfig::new(GpuMode::VirglRenderer, None, GpuFlags::default(), None).unwrap();

assert_matches!(
start_backend(socket_name, config).unwrap_err(),
Expand Down
8 changes: 7 additions & 1 deletion vhost-device-gpu/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ pub struct GpuArgs {

#[clap(flatten)]
pub flags: GpuFlagsArgs,

/// GPU path (e.g. /dev/dri/renderD128), only available for
/// virglrenderer backend.
#[clap(short = 'p', long, value_name = "PATH")]
pub gpu_path: Option<String>,
}

#[derive(Parser, Debug)]
Expand Down Expand Up @@ -115,7 +120,7 @@ impl From<GpuFlagsArgs> for GpuFlags {
pub fn config_from_args(args: GpuArgs) -> Result<(PathBuf, GpuConfig), GpuConfigError> {
let flags = GpuFlags::from(args.flags);
let capset = args.capset.map(capset_names_into_capset);
let config = GpuConfig::new(args.gpu_mode, capset, flags)?;
let config = GpuConfig::new(args.gpu_mode, capset, flags, args.gpu_path)?;
Ok((args.socket_path, config))
}

Expand Down Expand Up @@ -186,6 +191,7 @@ mod tests {
use_gles: false,
use_surfaceless: false,
},
gpu_path: None,
};

let (socket_path, config) = config_from_args(args).unwrap();
Expand Down
21 changes: 18 additions & 3 deletions vhost-device-gpu/src/virtio_gpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use std::{
collections::BTreeMap,
io::IoSliceMut,
os::fd::{AsFd, FromRawFd, RawFd},
path::PathBuf,
result::Result,
str::FromStr,
sync::{Arc, Mutex},
};

Expand All @@ -16,7 +18,8 @@ use log::{debug, error, trace, warn};
use rutabaga_gfx::{
Resource3DInfo, ResourceCreate3D, ResourceCreateBlob, Rutabaga, RutabagaBuilder,
RutabagaComponentType, RutabagaFence, RutabagaFenceHandler, RutabagaHandle,
RutabagaIntoRawDescriptor, RutabagaIovec, Transfer3D, RUTABAGA_HANDLE_TYPE_MEM_DMABUF,
RutabagaIntoRawDescriptor, RutabagaIovec, RutabagaPath, Transfer3D,
RUTABAGA_HANDLE_TYPE_MEM_DMABUF, RUTABAGA_PATH_TYPE_GPU,
};
#[cfg(feature = "gfxstream")]
use vhost::vhost_user::gpu_message::VhostUserGpuScanout;
Expand Down Expand Up @@ -403,14 +406,26 @@ impl RutabagaVirtioGpu {
GpuMode::Gfxstream => RutabagaComponentType::Gfxstream,
};

let builder = RutabagaBuilder::new(gpu_config.capsets().bits(), fence)
let mut builder = RutabagaBuilder::new(gpu_config.capsets().bits(), fence)
.set_use_egl(gpu_config.flags().use_egl)
.set_use_gles(gpu_config.flags().use_gles)
.set_use_surfaceless(gpu_config.flags().use_surfaceless)
// Since vhost-user-gpu is out-of-process this is the only type of blob resource that
// could work, so this is always enabled
.set_use_external_blob(true);

let mut rutabaga_paths = Vec::new();
if let Some(gpu_path) = gpu_config.gpu_path.as_ref() {
rutabaga_paths.push(RutabagaPath {
// PathBuf::from_str() never fails
path: PathBuf::from_str(gpu_path).unwrap(),
path_type: RUTABAGA_PATH_TYPE_GPU,
});
}
if !rutabaga_paths.is_empty() {
builder = builder.set_rutabaga_paths(Some(rutabaga_paths));
}

(builder, component)
}

Expand Down Expand Up @@ -1155,7 +1170,7 @@ mod tests {
_ => panic!("Unsupported component type for test"),
};

let config = GpuConfig::new(gpu_mode, capsets, GpuFlags::default()).unwrap();
let config = GpuConfig::new(gpu_mode, capsets, GpuFlags::default(), None).unwrap();

// Mock memory
let mem = GuestMemoryAtomic::new(
Expand Down