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:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user