From 943cbe37079d3e102cc5a0e7fecfe868d505d262 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 15 Mar 2025 16:27:04 +0100 Subject: [PATCH] graphics/fbbootlogd: Remove workaround that prevents blocking on the graphics driver Instead logd will no longer block on fbbootlogd to prevent the deadlock that this worked around. --- graphics/fbbootlogd/src/display.rs | 37 ++++-------------------------- graphics/fbbootlogd/src/main.rs | 10 ++++---- 2 files changed, 8 insertions(+), 39 deletions(-) diff --git a/graphics/fbbootlogd/src/display.rs b/graphics/fbbootlogd/src/display.rs index d276a24038..a26f0fc578 100644 --- a/graphics/fbbootlogd/src/display.rs +++ b/graphics/fbbootlogd/src/display.rs @@ -5,7 +5,6 @@ use libredox::errno::ESTALE; use orbclient::Event; use std::mem; use std::os::fd::BorrowedFd; -use std::sync::mpsc::{self, Receiver, Sender}; use std::sync::{Arc, Mutex}; use std::{io, os::unix::io::AsRawFd, slice}; @@ -35,12 +34,7 @@ pub struct DisplayMap { pub inner: graphics_ipc::v1::DisplayMap, } -enum DisplayCommand { - SyncRects(Vec), -} - pub struct Display { - cmd_tx: Sender, pub map: Arc>>, } @@ -67,13 +61,7 @@ impl Display { Self::handle_input_events(map_clone, input_handle); }); - let (cmd_tx, cmd_rx) = mpsc::channel(); - let map_clone = map.clone(); - std::thread::spawn(move || { - Self::handle_sync_rect(map_clone, cmd_rx); - }); - - Ok(Self { cmd_tx, map }) + Ok(Self { map }) } fn handle_input_events(map: Arc>>, input_handle: ConsumerHandle) { @@ -129,26 +117,9 @@ impl Display { } } - fn handle_sync_rect(map: Arc>>, cmd_rx: Receiver) { - while let Ok(cmd) = cmd_rx.recv() { - match cmd { - DisplayCommand::SyncRects(sync_rects) => { - // We may not hold this lock across the write call to avoid deadlocking if the - // graphics driver tries to write to the bootlog. - let display_handle = if let Some(map) = &*map.lock().unwrap() { - map.display_handle.clone() - } else { - continue; - }; - display_handle.sync_rects(&sync_rects).unwrap(); - } - } + pub fn sync_rects(&mut self, sync_rects: Vec) { + if let Some(map) = &*self.map.lock().unwrap() { + map.display_handle.sync_rects(&sync_rects).unwrap(); } } - - pub fn sync_rects(&mut self, sync_rects: Vec) { - self.cmd_tx - .send(DisplayCommand::SyncRects(sync_rects)) - .unwrap(); - } } diff --git a/graphics/fbbootlogd/src/main.rs b/graphics/fbbootlogd/src/main.rs index 1b0d941362..b566a76df4 100644 --- a/graphics/fbbootlogd/src/main.rs +++ b/graphics/fbbootlogd/src/main.rs @@ -1,13 +1,11 @@ //! Fbbootlogd renders the boot log and presents it on VT1. //! -//! While fbbootlogd is superficially similar to fbcond, there are two major differences: +//! While fbbootlogd is superficially similar to fbcond, the major difference is: //! //! * Fbbootlogd doesn't accept input coming from the keyboard. It only allows getting written to. -//! * Writing to fbbootlogd will never block. Not even on the graphics driver or inputd. This makes -//! it safe for graphics drivers and inputd to write to the boot log without risking deadlocks. -//! Fbcond will block on the graphics driver during handoff and will continously block on inputd -//! to get new input. Fbbootlogd does all blocking operations in background threads such that the -//! main thread will always keep accepting new input and writing it to the framebuffer. +//! +//! In the future fbbootlogd may also pull from logd as opposed to have logd push logs to it. And it +//! it could display a boot splash like plymouth instead of a boot log when booting in quiet mode. use redox_scheme::{RequestKind, SignalBehavior, Socket};