From 957878642e8e273a891e7153af6bf3200633448e Mon Sep 17 00:00:00 2001 From: Vasilito Date: Fri, 24 Apr 2026 20:44:53 +0100 Subject: [PATCH] Fix initfs hang: make hwd spawn pcid fire-and-forget instead of blocking Root cause: hwd used daemon::Daemon::spawn(pcid) which blocks waiting for pcid's readiness signal. But pcid only signals readiness after completing full PCI enumeration. On real Intel hardware with complex ACPI tables, enumeration can hang (unresponsive device, AML deadlock), causing pcid to never signal readiness, hwd to never signal its own readiness, and init to stall the entire initfs phase. Fix: replace blocking daemon::Daemon::spawn with std::process::Command::spawn (fire-and-forget). hwd signals its own readiness immediately, allowing init to continue the initfs phase regardless of pcid's enumeration progress. pcid runs independently and registers the pci scheme when ready. Also: promote pcid enumeration completion log from debug to info level. --- local/patches/base/redox.patch | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/local/patches/base/redox.patch b/local/patches/base/redox.patch index eb5a46ab..ab201571 100644 --- a/local/patches/base/redox.patch +++ b/local/patches/base/redox.patch @@ -8280,15 +8280,24 @@ index 3da41d63..12d26261 100644 + is_elan_touchpad_id(id) || is_cypress_touchpad_id(id) || is_synaptics_rmi_id(id) +} diff --git a/drivers/hwd/src/main.rs b/drivers/hwd/src/main.rs -index 79360e34..4a2b9469 100644 +index 79360e34..f58ec825 100644 --- a/drivers/hwd/src/main.rs +++ b/drivers/hwd/src/main.rs -@@ -38,7 +38,7 @@ fn daemon(daemon: daemon::Daemon) -> ! { +@@ -37,8 +37,15 @@ fn daemon(daemon: daemon::Daemon) -> ! { + //TODO: launch pcid based on backend information? // Must launch after acpid but before probe calls /scheme/acpi/symbols - #[allow(deprecated, reason = "we can't yet move this to init")] +- #[allow(deprecated, reason = "we can't yet move this to init")] - daemon::Daemon::spawn(process::Command::new("pcid")); -+ let _ = daemon::Daemon::spawn(process::Command::new("pcid")); ++ // Fire-and-forget: daemon::Daemon::spawn blocks until pcid signals readiness, ++ // but pcid only signals after full PCI enumeration. If enumeration hangs on ++ // real hardware (unresponsive device, complex AML), hwd deadlocks initfs. ++ match std::process::Command::new("pcid").spawn() { ++ Ok(_child) => {} ++ Err(err) => { ++ log::error!("hwd: failed to spawn pcid: {}", err); ++ } ++ } daemon.ready(); @@ -12257,7 +12266,7 @@ index 0ca68ec5..cd2fd701 100644 pub struct MsixTableEntry { pub addr_lo: Mmio, diff --git a/drivers/pcid/src/main.rs b/drivers/pcid/src/main.rs -index 61cd9a78..56ae816a 100644 +index 61cd9a78..8840e141 100644 --- a/drivers/pcid/src/main.rs +++ b/drivers/pcid/src/main.rs @@ -12,6 +12,7 @@ use pci_types::{ @@ -12334,9 +12343,16 @@ index 61cd9a78..56ae816a 100644 } Err(err) => { if err.errno() == libredox::errno::ENODEV { -@@ -304,14 +325,18 @@ fn daemon(daemon: daemon::Daemon) -> ! { +@@ -302,16 +323,24 @@ fn daemon(daemon: daemon::Daemon) -> ! { + ); + } } - debug!("Enumeration complete, now starting pci scheme"); +- debug!("Enumeration complete, now starting pci scheme"); ++ info!( ++ "PCI enumeration complete: {} devices, {} buses", ++ scheme.tree.len(), ++ bus_nums.len() ++ ); - register_sync_scheme(&socket, "pci", &mut scheme) - .expect("failed to register pci scheme to namespace"); @@ -12358,7 +12374,7 @@ index 61cd9a78..56ae816a 100644 } fn scan_device( -@@ -350,16 +375,16 @@ fn scan_device( +@@ -350,16 +379,16 @@ fn scan_device( match header.header_type(pcie) { HeaderType::Endpoint => {