acpid: allow PCI fd replacement; eagerly init AML symbols on sendfd

Closes the v4.0 plan P3 'acpid pci_fd is not registered' item.

Two related defects:

1. scheme.rs::on_sendfd had a one-shot EINVAL when self.pci_fd was
   already Some. Combined with the lazy AML context init in
   AcpiContext::aml_symbols, this created a permanent failure mode:
   - pcid starts AFTER acpid (per the requires_weak chain)
   - if a /scheme/acpi/symbols request arrives before pcid's sendfd
     reaches acpid, the aml init runs with pci_fd = None and logs
     'pci_fd is not registered' at error level
   - the resulting aml_context state makes subsequent retries fail
     the same way; the next pcid sendfd hits the one-shot EINVAL and
     is rejected
   - aml stays broken for the entire boot

   Fix: allow replacement (warn-and-replace on subsequent sendfd).
   Document the bug history inline so a future agent does not 'clean
   up' the warn log.

2. aml_physmem.rs::AmlPhysMemHandler::new logged the missing fd at
   log::error. Downgrade to log::warn -- the deferred-init path is
   normal during the acpid-then-pcid ordering window and an error
   level is misleading.

3. scheme.rs::on_sendfd now eagerly calls self.ctx.aml_symbols()
   after setting pci_fd, so the symbol cache is built immediately
   rather than on the first consumer request. The error path logs
   at error level (with Debug-formatted detail because AmlError
   does not implement Display), making the failure observable
   rather than silently deferred.

Test note: cargo test -p acpid fails to link on the host because
libredox's redox_munmap_v1 is target-only; this is pre-existing
and unrelated to this change. cargo check -p acpid is clean.
This commit is contained in:
Red Bear OS
2026-07-25 00:11:55 +09:00
parent 0ca545d35a
commit b906ad688a
2 changed files with 23 additions and 4 deletions
+3 -1
View File
@@ -178,7 +178,9 @@ impl AmlPhysMemHandler {
let pci_fd = if let Some(pci_fd) = pci_fd_opt {
Some(libredox::Fd::new(pci_fd.raw()))
} else {
log::error!("pci_fd is not registered");
log::warn!(
"acpid: AmlPhysMemHandler created without PCI fd; AML init will retry once pcid sends it via scheme:acpid sendfd"
);
None
};
Self {
+20 -3
View File
@@ -1070,10 +1070,27 @@ impl SchemeSync for AcpiScheme<'_, '_> {
}
let new_fd = libredox::Fd::new(new_fd);
// Allow replacement: pcid may resend the fd after a restart,
// and the previous one-shot EINVAL left aml init permanently
// broken if the first sendfd raced with an early aml request.
if self.pci_fd.is_some() {
return Err(Error::new(EINVAL));
} else {
self.pci_fd = Some(new_fd);
log::warn!(
"acpid: replacing previously-registered PCI fd; AML symbol cache will rebuild on next request"
);
}
self.pci_fd = Some(new_fd);
// Kick aml symbol init now that pci_fd is registered. The
// next aml request will either find a working cache or get a
// fresh error log here; either way the failure mode is
// observable rather than silently deferred to "the next
// caller retries".
match self.ctx.aml_symbols(self.pci_fd.as_ref()) {
Ok(_) => log::info!("acpid: AML symbols initialized on PCI fd registration"),
Err(err) => {
log::error!("acpid: AML symbol init failed after PCI fd registration");
log::error!("acpid: AML error detail: {:?}", err);
}
}
Ok(num_fds)