pci: Make the device ID allocation smarter

In order to handle the case where devices are very often plugged and
unplugged from a VM, we need to handle the PCI device ID allocation
better.

Any PCI device could be removed, which means we cannot simply rely on
the vector size to give the next available PCI device ID.

That's why this patch stores in memory the information about the 32
slots availability. Based on this information, whenever a new slot is
needed, the code can correctly provide an available ID, or simply return
an error because all slots are taken.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf
2020-03-09 16:09:11 +01:00
committed by Rob Bradford
parent e514b124ed
commit df71aaee3f
2 changed files with 28 additions and 4 deletions

View File

@@ -240,6 +240,10 @@ pub enum DeviceManagerError {
/// Failed to find VFIO device corresponding to the given identifier.
#[cfg(feature = "pci_support")]
UnknownVfioDeviceId(String),
/// Failed to find an available PCI device ID.
#[cfg(feature = "pci_support")]
NextPciDeviceId(pci::PciRootError),
}
pub type DeviceManagerResult<T> = result::Result<T, DeviceManagerError>;
@@ -1474,7 +1478,10 @@ impl DeviceManager {
// do multifunction. Also, because we only support one PCI
// bus, the bus 0, we don't need to add anything to the
// global device ID.
let pci_device_bdf = pci.next_device_id() << 3;
let pci_device_bdf = pci
.next_device_id()
.map_err(DeviceManagerError::NextPciDeviceId)?
<< 3;
let memory = self.memory_manager.lock().unwrap().guest_memory();
let vfio_device = VfioDevice::new(
@@ -1588,7 +1595,10 @@ impl DeviceManager {
// to the PCI function, and we know we don't do multifunction.
// Also, because we only support one PCI bus, the bus 0, we don't need
// to add anything to the global device ID.
let dev_id = pci.next_device_id() << 3;
let dev_id = pci
.next_device_id()
.map_err(DeviceManagerError::NextPciDeviceId)?
<< 3;
// Create the callback from the implementation of the DmaRemapping
// trait. The point with the callback is to simplify the code as we