mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-09-17 20:44:55 +00:00
0faa7afac2
Looking up devices on the port I/O bus is time consuming during the boot at there is an O(lg n) tree lookup and the overhead from taking a lock on the bus contents. Avoid this by adding a fast path uses the hardcoded port address and size and directs PCI config requests directly to the device. Command line: target/release/cloud-hypervisor --kernel ~/src/linux/vmlinux --cmdline "root=/dev/vda1 console=ttyS0" --serial tty --console off --disk path=~/workloads/focal-server-cloudimg-amd64-custom-20210609-0.raw --api-socket /tmp/api PIO exit: 17913 PCI fast path: 17871 Percentage on fast path: 99.8% perf before: marvin:~/src/cloud-hypervisor (main *)$ perf report -g | grep resolve 6.20% 6.20% vcpu0 cloud-hypervisor [.] vm_device:🚌:Bus::resolve perf after: marvin:~/src/cloud-hypervisor (2021-09-17-ioapic-fast-path *)$ perf report -g | grep resolve 0.08% 0.08% vcpu0 cloud-hypervisor [.] vm_device:🚌:Bus::resolve The compromise required to implement this fast path is bringing the creation of the PciConfigIo device into the DeviceManager::new() so that it can be used in the VmmOps struct which is created before DeviceManager::create_devices() is called. Signed-off-by: Rob Bradford <robert.bradford@intel.com>
50 lines
1.4 KiB
Rust
50 lines
1.4 KiB
Rust
// Copyright 2018 The Chromium OS Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE-BSD-3-Clause file.
|
|
|
|
//! Implements pci devices and busses.
|
|
#[macro_use]
|
|
extern crate log;
|
|
|
|
mod bus;
|
|
mod configuration;
|
|
mod device;
|
|
mod msi;
|
|
mod msix;
|
|
mod vfio;
|
|
mod vfio_user;
|
|
|
|
pub use self::bus::{PciBus, PciConfigIo, PciConfigMmio, PciRoot, PciRootError};
|
|
pub use self::configuration::{
|
|
PciBarConfiguration, PciBarPrefetchable, PciBarRegionType, PciCapability, PciCapabilityId,
|
|
PciClassCode, PciConfiguration, PciHeaderType, PciMassStorageSubclass,
|
|
PciNetworkControllerSubclass, PciProgrammingInterface, PciSerialBusSubClass, PciSubclass,
|
|
};
|
|
pub use self::device::{
|
|
BarReprogrammingParams, DeviceRelocation, Error as PciDeviceError, PciDevice,
|
|
};
|
|
pub use self::msi::{msi_num_enabled_vectors, MsiCap, MsiConfig};
|
|
pub use self::msix::{MsixCap, MsixConfig, MsixTableEntry, MSIX_TABLE_ENTRY_SIZE};
|
|
pub use self::vfio::{VfioPciDevice, VfioPciError};
|
|
pub use self::vfio_user::{VfioUserPciDevice, VfioUserPciDeviceError};
|
|
|
|
/// PCI has four interrupt pins A->D.
|
|
#[derive(Copy, Clone)]
|
|
pub enum PciInterruptPin {
|
|
IntA,
|
|
IntB,
|
|
IntC,
|
|
IntD,
|
|
}
|
|
|
|
impl PciInterruptPin {
|
|
pub fn to_mask(self) -> u32 {
|
|
self as u32
|
|
}
|
|
}
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
pub const PCI_CONFIG_IO_PORT: u64 = 0xcf8;
|
|
#[cfg(target_arch = "x86_64")]
|
|
pub const PCI_CONFIG_IO_PORT_SIZE: u64 = 0x8;
|