vmm: device_manager: Invert pci_id_list HashMap

In anticipation for further factorization, the pci_id_list is now a
hashmap of PCI b/d/f leading to each device name.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2021-03-17 14:14:41 +01:00
parent 62aaccee28
commit 305e095d15

View File

@ -894,8 +894,8 @@ pub struct DeviceManager {
// Bitmap of PCI devices to hotunplug. // Bitmap of PCI devices to hotunplug.
pci_devices_down: u32, pci_devices_down: u32,
// Hashmap of device's name to their corresponding PCI b/d/f. // Hashmap of PCI b/d/f to their corresponding device's name.
pci_id_list: HashMap<String, u32>, pci_id_list: HashMap<u32, String>,
// Hashmap of PCI b/d/f to their corresponding Arc<Mutex<dyn PciDevice>>. // Hashmap of PCI b/d/f to their corresponding Arc<Mutex<dyn PciDevice>>.
pci_devices: HashMap<u32, Arc<dyn Any + Send + Sync>>, pci_devices: HashMap<u32, Arc<dyn Any + Send + Sync>>,
@ -2955,7 +2955,7 @@ impl DeviceManager {
) )
.map_err(DeviceManagerError::AddPciDevice)?; .map_err(DeviceManagerError::AddPciDevice)?;
self.pci_id_list.insert(device_id, bdf); self.pci_id_list.insert(bdf, device_id);
Ok(bars) Ok(bars)
} }
@ -3247,48 +3247,50 @@ impl DeviceManager {
} }
pub fn remove_device(&mut self, id: String) -> DeviceManagerResult<()> { pub fn remove_device(&mut self, id: String) -> DeviceManagerResult<()> {
if let Some(pci_device_bdf) = self.pci_id_list.get(&id) { for (pci_device_bdf, pci_device_name) in self.pci_id_list.iter() {
if let Some(any_device) = self.pci_devices.get(&pci_device_bdf) { if *pci_device_name == id {
if let Ok(virtio_pci_device) = if let Some(any_device) = self.pci_devices.get(pci_device_bdf) {
Arc::clone(any_device).downcast::<Mutex<VirtioPciDevice>>() if let Ok(virtio_pci_device) =
{ Arc::clone(any_device).downcast::<Mutex<VirtioPciDevice>>()
let device_type = VirtioDeviceType::from( {
virtio_pci_device let device_type = VirtioDeviceType::from(
.lock() virtio_pci_device
.unwrap() .lock()
.virtio_device() .unwrap()
.lock() .virtio_device()
.unwrap() .lock()
.device_type(), .unwrap()
); .device_type(),
match device_type { );
VirtioDeviceType::TYPE_NET match device_type {
| VirtioDeviceType::TYPE_BLOCK VirtioDeviceType::TYPE_NET
| VirtioDeviceType::TYPE_PMEM | VirtioDeviceType::TYPE_BLOCK
| VirtioDeviceType::TYPE_FS | VirtioDeviceType::TYPE_PMEM
| VirtioDeviceType::TYPE_VSOCK => {} | VirtioDeviceType::TYPE_FS
_ => return Err(DeviceManagerError::RemovalNotAllowed(device_type)), | VirtioDeviceType::TYPE_VSOCK => {}
_ => return Err(DeviceManagerError::RemovalNotAllowed(device_type)),
}
}
} else {
return Err(DeviceManagerError::UnknownPciBdf(*pci_device_bdf));
}
// Update the PCID bitmap
self.pci_devices_down |= 1 << (*pci_device_bdf >> 3);
// Remove the device from the device tree along with its parent.
let mut device_tree = self.device_tree.lock().unwrap();
if let Some(node) = device_tree.remove(&id) {
if let Some(parent) = &node.parent {
device_tree.remove(parent);
} }
} }
} else {
return Err(DeviceManagerError::UnknownPciBdf(*pci_device_bdf)); return Ok(());
} }
// Update the PCID bitmap
self.pci_devices_down |= 1 << (*pci_device_bdf >> 3);
// Remove the device from the device tree along with its parent.
let mut device_tree = self.device_tree.lock().unwrap();
if let Some(node) = device_tree.remove(&id) {
if let Some(parent) = &node.parent {
device_tree.remove(parent);
}
}
Ok(())
} else {
Err(DeviceManagerError::UnknownDeviceId(id))
} }
Err(DeviceManagerError::UnknownDeviceId(id))
} }
pub fn eject_device(&mut self, device_id: u8) -> DeviceManagerResult<()> { pub fn eject_device(&mut self, device_id: u8) -> DeviceManagerResult<()> {
@ -3304,7 +3306,7 @@ impl DeviceManager {
// Find the device name corresponding to the PCI b/d/f while removing // Find the device name corresponding to the PCI b/d/f while removing
// the device entry. // the device entry.
self.pci_id_list.retain(|_, bdf| *bdf != pci_device_bdf); self.pci_id_list.remove(&pci_device_bdf);
// Give the PCI device ID back to the PCI bus. // Give the PCI device ID back to the PCI bus.
pci.lock() pci.lock()