Skip to content

Commit 9e4109a

Browse files
committed
devices/virtio_gpu: retry rutabaga initialization
So far, if the initialization of rutabaga fails, the GPU thread panics with an "expect()". Instead, let's retry the initialization with safe flags (NO_VIRGL). Fixes: #418 Suggested-by: Val Packett <[email protected]> Signed-off-by: Sergio Lopez <[email protected]>
1 parent 7bc99e4 commit 9e4109a

File tree

1 file changed

+57
-10
lines changed

1 file changed

+57
-10
lines changed

src/devices/src/virtio/gpu/virtio_gpu.rs

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -210,17 +210,14 @@ impl VirtioGpu {
210210
})
211211
}
212212

213-
#[allow(clippy::too_many_arguments)]
214-
pub fn new(
213+
pub fn create_rutabaga(
215214
mem: GuestMemoryMmap,
216215
queue_ctl: Arc<Mutex<VirtQueue>>,
217216
interrupt: InterruptTransport,
217+
fence_state: Arc<Mutex<FenceState>>,
218218
virgl_flags: u32,
219-
#[cfg(target_os = "macos")] map_sender: Sender<WorkerMessage>,
220219
export_table: Option<ExportTable>,
221-
displays: Box<[DisplayInfo]>,
222-
display_backend: DisplayBackend,
223-
) -> Self {
220+
) -> Option<Rutabaga> {
224221
let xdg_runtime_dir = match env::var("XDG_RUNTIME_DIR") {
225222
Ok(dir) => dir,
226223
Err(_) => "/run/user/1000".to_string(),
@@ -274,12 +271,62 @@ impl VirtioGpu {
274271
builder
275272
};
276273

277-
let fence_state = Arc::new(Mutex::new(Default::default()));
278274
let fence =
279275
Self::create_fence_handler(mem, queue_ctl.clone(), fence_state.clone(), interrupt);
280-
let rutabaga = builder
281-
.build(fence, None)
282-
.expect("Rutabaga initialization failed!");
276+
builder.clone().build(fence.clone(), None).ok()
277+
}
278+
279+
pub fn create_fallback_rutabaga(
280+
mem: GuestMemoryMmap,
281+
queue_ctl: Arc<Mutex<VirtQueue>>,
282+
interrupt: InterruptTransport,
283+
fence_state: Arc<Mutex<FenceState>>,
284+
) -> Option<Rutabaga> {
285+
const VIRGLRENDERER_NO_VIRGL: u32 = 1 << 7;
286+
let builder = RutabagaBuilder::new(
287+
rutabaga_gfx::RutabagaComponentType::VirglRenderer,
288+
VIRGLRENDERER_NO_VIRGL,
289+
0,
290+
);
291+
292+
let fence =
293+
Self::create_fence_handler(mem, queue_ctl.clone(), fence_state.clone(), interrupt);
294+
builder.clone().build(fence.clone(), None).ok()
295+
}
296+
297+
#[allow(clippy::too_many_arguments)]
298+
pub fn new(
299+
mem: GuestMemoryMmap,
300+
queue_ctl: Arc<Mutex<VirtQueue>>,
301+
interrupt: InterruptTransport,
302+
virgl_flags: u32,
303+
#[cfg(target_os = "macos")] map_sender: Sender<WorkerMessage>,
304+
export_table: Option<ExportTable>,
305+
displays: Box<[DisplayInfo]>,
306+
display_backend: DisplayBackend,
307+
) -> Self {
308+
let fence_state = Arc::new(Mutex::new(Default::default()));
309+
310+
let rutabaga = match Self::create_rutabaga(
311+
mem.clone(),
312+
queue_ctl.clone(),
313+
interrupt.clone(),
314+
fence_state.clone(),
315+
virgl_flags,
316+
export_table.clone(),
317+
) {
318+
Some(rutabaga) => rutabaga,
319+
None => {
320+
error!("Failed to create virtio_gpu backend with the requested parameters");
321+
Self::create_fallback_rutabaga(
322+
mem.clone(),
323+
queue_ctl.clone(),
324+
interrupt.clone(),
325+
fence_state.clone(),
326+
)
327+
.expect("Fallback rutabaga initialization failed")
328+
}
329+
};
283330

284331
let display_backend = display_backend
285332
.create_instance()

0 commit comments

Comments
 (0)