mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vm-virtio, vmm, vfio: Store GuestMemoryMmap in an Arc<ArcSwap<T>>
This allows us to change the memory map that is being used by the devices via an atomic swap (by replacing the map with another one). The ArcSwap provides the mechanism for atomically swapping from to another whilst still giving good read performace. It is inside an Arc so that we can use a single ArcSwap for all users. Not covered by this change is replacing the GuestMemoryMmap itself. This change also removes some vertical whitespace from use blocks in the files that this commit also changed. Vertical whitespace was being used inconsistently and broke rustfmt's behaviour of ordering the imports as it would only do it within the block. Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
@@ -2,20 +2,19 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
use std::result;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use libc::EFD_NONBLOCK;
|
||||
|
||||
use crate::transport::{VirtioTransport, NOTIFY_REG_OFFSET};
|
||||
use crate::{
|
||||
Queue, VirtioDevice, VirtioInterrupt, VirtioInterruptType, DEVICE_ACKNOWLEDGE, DEVICE_DRIVER,
|
||||
DEVICE_DRIVER_OK, DEVICE_FAILED, DEVICE_FEATURES_OK, DEVICE_INIT,
|
||||
INTERRUPT_STATUS_CONFIG_CHANGED, INTERRUPT_STATUS_USED_RING,
|
||||
};
|
||||
use arc_swap::ArcSwap;
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use devices::{BusDevice, Interrupt};
|
||||
use libc::EFD_NONBLOCK;
|
||||
use std::result;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use vm_device::{Migratable, MigratableError, Pausable, Snapshotable};
|
||||
use vm_memory::{GuestAddress, GuestMemoryMmap};
|
||||
use vmm_sys_util::{errno::Result, eventfd::EventFd};
|
||||
@@ -52,13 +51,13 @@ pub struct MmioDevice {
|
||||
config_generation: u32,
|
||||
queues: Vec<Queue>,
|
||||
queue_evts: Vec<EventFd>,
|
||||
mem: Option<Arc<RwLock<GuestMemoryMmap>>>,
|
||||
mem: Option<Arc<ArcSwap<GuestMemoryMmap>>>,
|
||||
}
|
||||
|
||||
impl MmioDevice {
|
||||
/// Constructs a new MMIO transport for the given virtio device.
|
||||
pub fn new(
|
||||
mem: Arc<RwLock<GuestMemoryMmap>>,
|
||||
mem: Arc<ArcSwap<GuestMemoryMmap>>,
|
||||
device: Arc<Mutex<dyn VirtioDevice>>,
|
||||
) -> Result<MmioDevice> {
|
||||
let device_clone = device.clone();
|
||||
@@ -102,7 +101,7 @@ impl MmioDevice {
|
||||
|
||||
fn are_queues_valid(&self) -> bool {
|
||||
if let Some(mem) = self.mem.as_ref() {
|
||||
self.queues.iter().all(|q| q.is_valid(&mem.read().unwrap()))
|
||||
self.queues.iter().all(|q| q.is_valid(mem.load().as_ref()))
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
@@ -7,13 +7,12 @@
|
||||
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
|
||||
extern crate byteorder;
|
||||
|
||||
use crate::{Queue, VirtioDevice};
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use std::sync::atomic::{AtomicU16, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use vm_memory::GuestAddress;
|
||||
|
||||
use crate::{Queue, VirtioDevice};
|
||||
|
||||
/// Contains the data for reading and writing the common configuration structure of a virtio PCI
|
||||
/// device.
|
||||
///
|
||||
@@ -255,8 +254,8 @@ impl VirtioPciCommonConfig {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{ActivateResult, VirtioInterrupt};
|
||||
|
||||
use std::sync::{Arc, RwLock};
|
||||
use arc_swap::ArcSwap;
|
||||
use std::sync::Arc;
|
||||
use vm_memory::GuestMemoryMmap;
|
||||
use vmm_sys_util::eventfd::EventFd;
|
||||
|
||||
@@ -273,7 +272,7 @@ mod tests {
|
||||
}
|
||||
fn activate(
|
||||
&mut self,
|
||||
_mem: Arc<RwLock<GuestMemoryMmap>>,
|
||||
_mem: Arc<ArcSwap<GuestMemoryMmap>>,
|
||||
_interrupt_evt: Arc<VirtioInterrupt>,
|
||||
_queues: Vec<Queue>,
|
||||
_queue_evts: Vec<EventFd>,
|
||||
|
||||
@@ -13,19 +13,19 @@ extern crate vm_allocator;
|
||||
extern crate vm_memory;
|
||||
extern crate vmm_sys_util;
|
||||
|
||||
use libc::EFD_NONBLOCK;
|
||||
use std::any::Any;
|
||||
use std::result;
|
||||
use std::sync::atomic::{AtomicU16, AtomicUsize, Ordering};
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
|
||||
use arc_swap::ArcSwap;
|
||||
use devices::BusDevice;
|
||||
use libc::EFD_NONBLOCK;
|
||||
use pci::{
|
||||
BarReprogrammingParams, InterruptDelivery, InterruptParameters, MsixCap, MsixConfig,
|
||||
PciBarConfiguration, PciBarRegionType, PciCapability, PciCapabilityID, PciClassCode,
|
||||
PciConfiguration, PciDevice, PciDeviceError, PciHeaderType, PciInterruptPin,
|
||||
PciMassStorageSubclass, PciNetworkControllerSubclass, PciSubclass,
|
||||
};
|
||||
use std::any::Any;
|
||||
use std::result;
|
||||
use std::sync::atomic::{AtomicU16, AtomicUsize, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use vm_allocator::SystemAllocator;
|
||||
use vm_device::{Migratable, MigratableError, Pausable, Snapshotable};
|
||||
use vm_memory::{Address, ByteValued, GuestAddress, GuestMemoryMmap, GuestUsize, Le32};
|
||||
@@ -239,7 +239,7 @@ pub struct VirtioPciDevice {
|
||||
queue_evts: Vec<EventFd>,
|
||||
|
||||
// Guest memory
|
||||
memory: Option<Arc<RwLock<GuestMemoryMmap>>>,
|
||||
memory: Option<Arc<ArcSwap<GuestMemoryMmap>>>,
|
||||
|
||||
// Setting PCI BAR
|
||||
settings_bar: u8,
|
||||
@@ -251,7 +251,7 @@ pub struct VirtioPciDevice {
|
||||
impl VirtioPciDevice {
|
||||
/// Constructs a new PCI transport for the given virtio device.
|
||||
pub fn new(
|
||||
memory: Arc<RwLock<GuestMemoryMmap>>,
|
||||
memory: Arc<ArcSwap<GuestMemoryMmap>>,
|
||||
device: Arc<Mutex<dyn VirtioDevice>>,
|
||||
msix_num: u16,
|
||||
iommu_mapping_cb: Option<Arc<VirtioIommuRemapping>>,
|
||||
@@ -361,7 +361,7 @@ impl VirtioPciDevice {
|
||||
|
||||
fn are_queues_valid(&self) -> bool {
|
||||
if let Some(mem) = self.memory.as_ref() {
|
||||
self.queues.iter().all(|q| q.is_valid(&mem.read().unwrap()))
|
||||
self.queues.iter().all(|q| q.is_valid(mem.load().as_ref()))
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user