fbcond: retry handoff while display driver is not ready
The handoff is one-shot: inputd signals it the moment the real display driver registers its path, but the driver's scheme may not serve the v2 open / capability query for a few more milliseconds. Without a retry, a transient not-ready driver leaves the framebuffer permanently blank — the login prompt is drawn to the framebuffer VT, so the console appears dead even though boot continues on the serial mirror (observed as the 2026-07-20 '-vga std' boot freeze at 'Performing handoff'). Retry the reopen for up to 250 x 10ms; the driver becomes ready well within this bound in practice. On success after retries, log the retry count at info level. If the driver is still not ready after the bound, emit a single explicit warning instead of per-attempt warn spam (the per-attempt message in display.rs is demoted to debug). Serial mirror remains unaffected in the failure case.
This commit is contained in:
@@ -45,7 +45,9 @@ impl Display {
|
||||
let new_display_handle = match V2GraphicsHandle::from_file(display_file) {
|
||||
Ok(handle) => handle,
|
||||
Err(err) => {
|
||||
log::warn!("fbcond: display not ready at handoff (from_file: {err}); will retry");
|
||||
// Transient during the handoff race; handle_handoff retries and
|
||||
// emits a single warning if it ultimately gives up.
|
||||
log::debug!("fbcond: display not ready at handoff (from_file: {err}); will retry");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -53,10 +53,28 @@ impl TextScreen {
|
||||
|
||||
pub fn handle_handoff(&mut self) {
|
||||
log::info!("fbcond: Performing handoff");
|
||||
self.display.reopen_for_handoff();
|
||||
if self.display.map.is_some() {
|
||||
self.flush_pending_writes();
|
||||
// The handoff is one-shot: inputd signals it the moment the real display
|
||||
// driver registers its path, but the driver's scheme may not serve the
|
||||
// v2 open / capability query for a few more milliseconds. Without a
|
||||
// retry, a transient not-ready driver leaves the framebuffer permanently
|
||||
// blank (the login prompt is drawn to the framebuffer VT, so the console
|
||||
// appears dead even though boot continues on the serial mirror). Retry
|
||||
// briefly — the driver becomes ready well within this bound in practice.
|
||||
for attempt in 0..250u32 {
|
||||
self.display.reopen_for_handoff();
|
||||
if self.display.map.is_some() {
|
||||
if attempt > 0 {
|
||||
log::info!("fbcond: handoff completed after {attempt} retries");
|
||||
}
|
||||
self.flush_pending_writes();
|
||||
return;
|
||||
}
|
||||
std::thread::sleep(std::time::Duration::from_millis(10));
|
||||
}
|
||||
log::warn!(
|
||||
"fbcond: display still not ready after handoff retries; \
|
||||
framebuffer console will remain blank (serial mirror unaffected)"
|
||||
);
|
||||
}
|
||||
|
||||
pub fn input(&mut self, event: &Event) {
|
||||
|
||||
Reference in New Issue
Block a user