Skip to content

Commit c557101

Browse files
author
Dorinda Bassey
committed
vhost-device-gpu: Add support for GPU device path
Add a new --gpu-path CLI argument that allows users to specify which GPU device to use for rendering when using the virglrenderer backend. This is useful for systems with multiple GPUs where a specific device needs to be selected. Signed-off-by: Dorinda Bassey <[email protected]>
1 parent cf95bca commit c557101

File tree

5 files changed

+60
-2
lines changed

5 files changed

+60
-2
lines changed

vhost-device-gpu/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
### Added
55

6+
- [[#903]] (https://github.com/rust-vmm/vhost-device/pull/903) vhost-device-gpu: Add support for GPU device path
7+
68
### Changed
79

810
- [[#852]] (https://github.com/rust-vmm/vhost-device/pull/890) vhost-device-gpu: Refactor vhost-device-gpu

vhost-device-gpu/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ A virtio-gpu device using the vhost-user protocol.
5656
[default: true]
5757
[possible values: true, false]
5858
59+
--gpu-path <PATH>
60+
GPU device path (e.g., /dev/dri/renderD128)
61+
62+
[Optional] Specifies which GPU device to use for rendering. Only
63+
applicable when using the virglrenderer backend. If not specified,
64+
virglrenderer will automatically select the default GPU device.
65+
5966
-h, --help
6067
Print help (see a summary with '-h')
6168
@@ -134,6 +141,12 @@ First start the daemon on the host machine using one of the available gpu modes:
134141
host# vhost-device-gpu --socket-path /tmp/gpu.socket --gpu-mode virglrenderer
135142
```
136143

144+
To specify a particular GPU device (e.g., when you have multiple GPUs):
145+
146+
```shell
147+
host# vhost-device-gpu --socket-path /tmp/gpu.socket --gpu-mode virglrenderer --gpu-path /dev/dri/renderD128
148+
```
149+
137150
With QEMU, there are two device front-ends you can use with this device.
138151
You can either use `vhost-user-gpu-pci` or `vhost-user-vga`, which also
139152
implements VGA, that allows you to see boot messages before the guest

vhost-device-gpu/src/backend/virgl.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use std::{
88
collections::BTreeMap,
9+
fs::File,
910
io::{self, IoSliceMut},
1011
os::fd::{AsFd, FromRawFd, IntoRawFd, RawFd},
1112
sync::{Arc, Mutex},
@@ -163,8 +164,27 @@ impl VirglRendererAdapter {
163164
fence_state.clone(),
164165
));
165166

166-
let renderer = VirglRenderer::init(virglrenderer_flags, fence_handler, None)
167-
.expect("Failed to initialize virglrenderer");
167+
// Open the GPU device if a path was specified
168+
let render_server_fd = config.flags().gpu_path.as_ref().and_then(|path| {
169+
File::open(path)
170+
.map(|f| f.into())
171+
.map_err(|e| {
172+
warn!(
173+
"Failed to open GPU device at {}: {}. Virglrenderer will automatically select an available GPU.",
174+
path.display(),
175+
e
176+
);
177+
})
178+
.ok()
179+
});
180+
181+
let renderer = VirglRenderer::init(virglrenderer_flags, fence_handler, render_server_fd)
182+
.map_err(|e| {
183+
io::Error::new(
184+
io::ErrorKind::Other,
185+
format!("Failed to initialize virglrenderer: {:?}", e),
186+
)
187+
})?;
168188
Ok(Self {
169189
renderer,
170190
gpu_backend,

vhost-device-gpu/src/lib.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ pub struct GpuFlags {
131131
pub use_glx: bool,
132132
pub use_gles: bool,
133133
pub use_surfaceless: bool,
134+
#[cfg(feature = "backend-virgl")]
135+
pub gpu_path: Option<std::path::PathBuf>,
134136
}
135137

136138
impl GpuFlags {
@@ -141,6 +143,8 @@ impl GpuFlags {
141143
use_glx: false,
142144
use_gles: true,
143145
use_surfaceless: true,
146+
#[cfg(feature = "backend-virgl")]
147+
gpu_path: None,
144148
}
145149
}
146150
}
@@ -157,6 +161,8 @@ pub enum GpuConfigError {
157161
CapsetUnsupportedByMode(GpuMode, GpuCapset),
158162
#[error("Requested gfxstream-gles capset, but gles is disabled")]
159163
GlesRequiredByGfxstream,
164+
#[error("GPU path can only be specified when using virglrenderer mode")]
165+
GpuPathNotSupportedByMode,
160166
}
161167

162168
impl GpuConfig {
@@ -208,6 +214,12 @@ impl GpuConfig {
208214
return Err(GpuConfigError::GlesRequiredByGfxstream);
209215
}
210216

217+
// Validate that gpu_path is only used with virglrenderer
218+
#[cfg(feature = "backend-virgl")]
219+
if flags.gpu_path.is_some() && !matches!(gpu_mode, GpuMode::VirglRenderer) {
220+
return Err(GpuConfigError::GpuPathNotSupportedByMode);
221+
}
222+
211223
Ok(Self {
212224
gpu_mode,
213225
capset,

vhost-device-gpu/src/main.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ pub struct GpuFlagsArgs {
114114
default_value_t = GpuFlags::new_default().use_surfaceless
115115
)]
116116
pub use_surfaceless: bool,
117+
118+
/// GPU device path (e.g., /dev/dri/renderD128)
119+
#[clap(long, value_name = "PATH")]
120+
#[cfg(feature = "backend-virgl")]
121+
pub gpu_path: Option<PathBuf>,
117122
}
118123

119124
impl From<GpuFlagsArgs> for GpuFlags {
@@ -123,6 +128,8 @@ impl From<GpuFlagsArgs> for GpuFlags {
123128
use_glx: args.use_glx,
124129
use_gles: args.use_gles,
125130
use_surfaceless: args.use_surfaceless,
131+
#[cfg(feature = "backend-virgl")]
132+
gpu_path: args.gpu_path,
126133
}
127134
}
128135
}
@@ -200,6 +207,8 @@ mod tests {
200207
use_glx: true,
201208
use_gles: false,
202209
use_surfaceless: false,
210+
#[cfg(feature = "backend-virgl")]
211+
gpu_path: None,
203212
},
204213
};
205214

@@ -213,6 +222,8 @@ mod tests {
213222
use_glx: true,
214223
use_gles: false,
215224
use_surfaceless: false,
225+
#[cfg(feature = "backend-virgl")]
226+
gpu_path: None,
216227
}
217228
);
218229
assert_eq!(config.gpu_mode(), GpuMode::VirglRenderer);

0 commit comments

Comments
 (0)