Skip to content

Commit 5c0c5f8

Browse files
committed
vhost-device-gpu: Add support for specifying GPU path
Rutabaga_gfx, since v0.1.75, supports specifying a GPU path (e.g. /dev/dri/renderD128) for virglrenderer. This patch introduces a `--gpu-path` argument to allow users to use any GPU they want. Signed-off-by: Xuewei Niu <[email protected]>
1 parent 4bbe030 commit 5c0c5f8

File tree

5 files changed

+38
-7
lines changed

5 files changed

+38
-7
lines changed

vhost-device-gpu/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ A virtio-gpu device using the vhost-user protocol.
5656
[default: true]
5757
[possible values: true, false]
5858
59+
-p, --gpu-path <PATH>
60+
GPU path (e.g. /dev/dri/renderD128), only available for virglrenderer backend
61+
5962
-h, --help
6063
Print help (see a summary with '-h')
6164

vhost-device-gpu/src/device.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,7 @@ mod tests {
765765
GpuMode::VirglRenderer,
766766
Some(GpuCapset::VIRGL | GpuCapset::VIRGL2),
767767
GpuFlags::default(),
768+
None,
768769
)
769770
.unwrap();
770771
let backend = VhostUserGpuBackend::new(config).unwrap();
@@ -1353,7 +1354,7 @@ mod tests {
13531354
rusty_fork_test! {
13541355
#[test]
13551356
fn test_verify_backend() {
1356-
let gpu_config = GpuConfig::new(GpuMode::VirglRenderer, None, GpuFlags::default()).unwrap();
1357+
let gpu_config = GpuConfig::new(GpuMode::VirglRenderer, None, GpuFlags::default(), None).unwrap();
13571358
let backend = VhostUserGpuBackend::new(gpu_config).unwrap();
13581359

13591360
assert_eq!(backend.num_queues(), NUM_QUEUES);

vhost-device-gpu/src/lib.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ pub struct GpuConfig {
127127
gpu_mode: GpuMode,
128128
capset: GpuCapset,
129129
flags: GpuFlags,
130+
gpu_path: Option<String>,
130131
}
131132

132133
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -198,6 +199,7 @@ impl GpuConfig {
198199
gpu_mode: GpuMode,
199200
capset: Option<GpuCapset>,
200201
flags: GpuFlags,
202+
gpu_path: Option<String>,
201203
) -> Result<Self, GpuConfigError> {
202204
let capset = capset.unwrap_or_else(|| Self::get_default_capset_for_mode(gpu_mode));
203205
Self::validate_capset(gpu_mode, capset)?;
@@ -211,6 +213,7 @@ impl GpuConfig {
211213
gpu_mode,
212214
capset,
213215
flags,
216+
gpu_path,
214217
})
215218
}
216219

@@ -263,7 +266,8 @@ mod tests {
263266

264267
#[test]
265268
fn test_gpu_config_create_default_virglrenderer() {
266-
let config = GpuConfig::new(GpuMode::VirglRenderer, None, GpuFlags::new_default()).unwrap();
269+
let config =
270+
GpuConfig::new(GpuMode::VirglRenderer, None, GpuFlags::new_default(), None).unwrap();
267271
assert_eq!(config.gpu_mode(), GpuMode::VirglRenderer);
268272
assert_eq!(config.capsets(), GpuConfig::DEFAULT_VIRGLRENDER_CAPSET_MASK);
269273
}
@@ -294,6 +298,7 @@ mod tests {
294298
GpuMode::VirglRenderer,
295299
Some(GpuCapset::VIRGL2),
296300
GpuFlags::default(),
301+
None,
297302
)
298303
.unwrap();
299304
assert_eq!(config.gpu_mode(), GpuMode::VirglRenderer);
@@ -355,7 +360,8 @@ mod tests {
355360
fn test_fail_listener() {
356361
// This will fail the listeners and thread will panic.
357362
let socket_name = Path::new("/proc/-1/nonexistent");
358-
let config = GpuConfig::new(GpuMode::VirglRenderer, None, GpuFlags::default()).unwrap();
363+
let config =
364+
GpuConfig::new(GpuMode::VirglRenderer, None, GpuFlags::default(), None).unwrap();
359365

360366
assert_matches!(
361367
start_backend(socket_name, config).unwrap_err(),

vhost-device-gpu/src/main.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ pub struct GpuArgs {
6363

6464
#[clap(flatten)]
6565
pub flags: GpuFlagsArgs,
66+
67+
/// GPU path (e.g. /dev/dri/renderD128), only available for
68+
/// virglrenderer backend.
69+
#[clap(short = 'p', long, value_name = "PATH")]
70+
pub gpu_path: Option<String>,
6671
}
6772

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

@@ -186,6 +191,7 @@ mod tests {
186191
use_gles: false,
187192
use_surfaceless: false,
188193
},
194+
gpu_path: None,
189195
};
190196

191197
let (socket_path, config) = config_from_args(args).unwrap();

vhost-device-gpu/src/virtio_gpu.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ use std::{
77
collections::BTreeMap,
88
io::IoSliceMut,
99
os::fd::{AsFd, FromRawFd, RawFd},
10+
path::PathBuf,
1011
result::Result,
12+
str::FromStr,
1113
sync::{Arc, Mutex},
1214
};
1315

@@ -16,7 +18,8 @@ use log::{debug, error, trace, warn};
1618
use rutabaga_gfx::{
1719
Resource3DInfo, ResourceCreate3D, ResourceCreateBlob, Rutabaga, RutabagaBuilder,
1820
RutabagaComponentType, RutabagaFence, RutabagaFenceHandler, RutabagaHandle,
19-
RutabagaIntoRawDescriptor, RutabagaIovec, Transfer3D, RUTABAGA_HANDLE_TYPE_MEM_DMABUF,
21+
RutabagaIntoRawDescriptor, RutabagaIovec, RutabagaPath, Transfer3D,
22+
RUTABAGA_HANDLE_TYPE_MEM_DMABUF, RUTABAGA_PATH_TYPE_GPU,
2023
};
2124
#[cfg(feature = "gfxstream")]
2225
use vhost::vhost_user::gpu_message::VhostUserGpuScanout;
@@ -403,14 +406,26 @@ impl RutabagaVirtioGpu {
403406
GpuMode::Gfxstream => RutabagaComponentType::Gfxstream,
404407
};
405408

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

417+
let mut rutabaga_paths = Vec::new();
418+
if let Some(gpu_path) = gpu_config.gpu_path.as_ref() {
419+
rutabaga_paths.push(RutabagaPath {
420+
// PathBuf::from_str() never fails
421+
path: PathBuf::from_str(gpu_path).unwrap(),
422+
path_type: RUTABAGA_PATH_TYPE_GPU,
423+
});
424+
}
425+
if !rutabaga_paths.is_empty() {
426+
builder = builder.set_rutabaga_paths(Some(rutabaga_paths));
427+
}
428+
414429
(builder, component)
415430
}
416431

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

1158-
let config = GpuConfig::new(gpu_mode, capsets, GpuFlags::default()).unwrap();
1173+
let config = GpuConfig::new(gpu_mode, capsets, GpuFlags::default(), None).unwrap();
11591174

11601175
// Mock memory
11611176
let mem = GuestMemoryAtomic::new(

0 commit comments

Comments
 (0)