Skip to content

Commit 51814f0

Browse files
jbreitbartclaude
andcommitted
Skip remaining PCI devices when device 0 is absent on a bus
Standard PCI enumeration optimization: if device 0 function 0 on a bus returns 0xFFFF, no devices exist on that bus. This reduces the scan from 32 buses × 32 devices = 1024 probes to ~63 probes on uhyve (which has a single device at bus 0 device 0). PCI legacy scan drops from ~13 ms to ~0.8 ms, cutting total boot time from ~18 ms to ~5.5 ms. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 4912505 commit 51814f0

1 file changed

Lines changed: 11 additions & 3 deletions

File tree

src/arch/x86_64/kernel/pci.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,14 @@ pub(crate) fn init() {
9292
return;
9393
}
9494

95+
boot_timestamp!("pci: legacy scan start");
9596
// For Hermit, we currently limit scanning to the first 32 buses.
9697
const PCI_MAX_BUS_NUMBER: u8 = 32;
9798
scan_bus(
9899
0..PCI_MAX_BUS_NUMBER,
99100
PciConfigRegion::Pci(LegacyPciConfigRegion::new()),
100101
);
102+
boot_timestamp!("pci: legacy scan end");
101103
info!("Initialized PCI");
102104
}
103105

@@ -114,10 +116,16 @@ fn scan_bus(bus_range: impl IntoIterator<Item = u8> + Debug, pci_config: PciConf
114116
let header = PciHeader::new(pci_address);
115117

116118
let (device_id, vendor_id) = header.id(pci_config);
117-
if device_id != u16::MAX && vendor_id != u16::MAX {
118-
let device = PciDevice::new(pci_address, pci_config);
119-
PCI_DEVICES.with(|pci_devices| pci_devices.unwrap().push(device));
119+
if device_id == u16::MAX || vendor_id == u16::MAX {
120+
// If device 0 on this bus is absent, no devices exist on
121+
// this bus — skip the remaining device slots.
122+
if device == 0 {
123+
break;
124+
}
125+
continue;
120126
}
127+
let device = PciDevice::new(pci_address, pci_config);
128+
PCI_DEVICES.with(|pci_devices| pci_devices.unwrap().push(device));
121129
}
122130
}
123131
}

0 commit comments

Comments
 (0)