pcid: read REDBEAR_DRIVER_PCI_IRQ_MODE / DISABLE_ACCEL env vars

The pcid_interface crate now reads the two env vars emitted by
driver-manager's SpawnDecision committee:
- REDBEAR_DRIVER_PCI_IRQ_MODE: lets the spawned child know
  whether to fall back to MSI / INTx instead of MSI-X
- REDBEAR_DRIVER_DISABLE_ACCEL: lets the spawned child suppress
  hardware acceleration (matches PciQuirkFlags::DISABLE_ACCEL)

Both values are stored on PciFunctionHandle and exposed via
accessors (irq_mode_hint / disable_accel_hint) so the driver
daemons can read them at startup. 6 new unit tests cover the
env-var parsing.

Refs: local/docs/DRIVER-MANAGER-MIGRATION-PLAN.md § 5.2 D2.7.
This commit is contained in:
Red Bear OS
2026-07-21 12:07:49 +09:00
parent 6db0f48170
commit ddcd08709f
+96
View File
@@ -302,6 +302,23 @@ pub struct PciFunctionHandle {
channel: File,
config: SubdriverArguments,
mapped_bars: [Option<MappedBar>; 6],
irq_mode_hint: Option<String>,
disable_accel_hint: bool,
}
fn read_irq_mode_hint() -> Option<String> {
match env::var("REDBEAR_DRIVER_PCI_IRQ_MODE") {
Ok(v) if !v.is_empty() => Some(v),
Ok(_) => None,
Err(_) => None,
}
}
fn read_disable_accel_hint() -> bool {
match env::var("REDBEAR_DRIVER_DISABLE_ACCEL") {
Ok(v) if v == "1" || v.eq_ignore_ascii_case("true") || v == "yes" => true,
_ => false,
}
}
fn send<T: Serialize>(w: &mut File, message: &T) {
@@ -378,9 +395,26 @@ impl PciFunctionHandle {
channel,
config,
mapped_bars: [const { None }; 6],
irq_mode_hint: read_irq_mode_hint(),
disable_accel_hint: read_disable_accel_hint(),
}
}
/// Returns the IRQ-mode hint read from `REDBEAR_DRIVER_PCI_IRQ_MODE` at
/// connect time, or `None` if the env var was unset. Drivers should
/// honour this hint when allocating interrupt vectors.
pub fn irq_mode_hint(&self) -> Option<&str> {
self.irq_mode_hint.as_deref()
}
/// Returns the disable-acceleration hint read from
/// `REDBEAR_DRIVER_DISABLE_ACCEL` at connect time. Drivers (notably
/// GPU drivers) should suppress hardware acceleration paths when this
/// returns `true`.
pub fn disable_accel_hint(&self) -> bool {
self.disable_accel_hint
}
pub fn into_inner_fd(self) -> RawFd {
self.channel.into_raw_fd()
}
@@ -544,3 +578,65 @@ pub fn pci_daemon<F: FnOnce(Daemon, PciFunctionHandle) -> !>(f: F) -> ! {
f(daemon, pcid_handle)
})
}
#[cfg(test)]
mod hint_tests {
use super::{read_disable_accel_hint, read_irq_mode_hint};
use std::sync::Mutex;
static ENV_LOCK: Mutex<()> = Mutex::new(());
#[test]
fn irq_mode_hint_returns_none_when_unset() {
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
unsafe { std::env::remove_var("REDBEAR_DRIVER_PCI_IRQ_MODE") };
assert!(read_irq_mode_hint().is_none());
}
#[test]
fn irq_mode_hint_returns_some_when_set() {
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
unsafe { std::env::set_var("REDBEAR_DRIVER_PCI_IRQ_MODE", "intx_or_msi") };
let v = read_irq_mode_hint();
unsafe { std::env::remove_var("REDBEAR_DRIVER_PCI_IRQ_MODE") };
assert_eq!(v.as_deref(), Some("intx_or_msi"));
}
#[test]
fn irq_mode_hint_returns_none_for_empty_value() {
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
unsafe { std::env::set_var("REDBEAR_DRIVER_PCI_IRQ_MODE", "") };
let v = read_irq_mode_hint();
unsafe { std::env::remove_var("REDBEAR_DRIVER_PCI_IRQ_MODE") };
assert!(v.is_none());
}
#[test]
fn disable_accel_hint_defaults_false() {
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
unsafe { std::env::remove_var("REDBEAR_DRIVER_DISABLE_ACCEL") };
assert!(!read_disable_accel_hint());
}
#[test]
fn disable_accel_hint_accepts_truthy_values() {
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
for truthy in &["1", "true", "TRUE", "yes"] {
unsafe { std::env::set_var("REDBEAR_DRIVER_DISABLE_ACCEL", truthy) };
let v = read_disable_accel_hint();
unsafe { std::env::remove_var("REDBEAR_DRIVER_DISABLE_ACCEL") };
assert!(v, "value {:?} should be truthy", truthy);
}
}
#[test]
fn disable_accel_hint_rejects_falsy_values() {
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
for falsy in &["0", "false", "no", ""] {
unsafe { std::env::set_var("REDBEAR_DRIVER_DISABLE_ACCEL", falsy) };
let v = read_disable_accel_hint();
unsafe { std::env::remove_var("REDBEAR_DRIVER_DISABLE_ACCEL") };
assert!(!v, "value {:?} should be falsy", falsy);
}
}
}