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:
@@ -8,6 +8,13 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the THIRD-PARTY file.
|
||||
|
||||
use super::{VsockBackend, VsockPacket};
|
||||
use crate::Error as DeviceError;
|
||||
use crate::VirtioInterrupt;
|
||||
use crate::{
|
||||
ActivateError, ActivateResult, DeviceEventT, Queue, VirtioDevice, VirtioDeviceType,
|
||||
VirtioInterruptType, VIRTIO_F_IN_ORDER, VIRTIO_F_IOMMU_PLATFORM, VIRTIO_F_VERSION_1,
|
||||
};
|
||||
/// This is the `VirtioDevice` implementation for our vsock device. It handles the virtio-level
|
||||
/// device logic: feature negociation, device configuration, and device activation.
|
||||
/// The run-time device logic (i.e. event-driven data handling) is implemented by
|
||||
@@ -27,6 +34,8 @@
|
||||
/// - an event queue FD; and
|
||||
/// - a backend FD.
|
||||
///
|
||||
use arc_swap::ArcSwap;
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use epoll;
|
||||
use libc::EFD_NONBLOCK;
|
||||
use std;
|
||||
@@ -36,15 +45,6 @@ use std::result;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::thread;
|
||||
|
||||
use super::{VsockBackend, VsockPacket};
|
||||
use crate::Error as DeviceError;
|
||||
use crate::VirtioInterrupt;
|
||||
use crate::{
|
||||
ActivateError, ActivateResult, DeviceEventT, Queue, VirtioDevice, VirtioDeviceType,
|
||||
VirtioInterruptType, VIRTIO_F_IN_ORDER, VIRTIO_F_IOMMU_PLATFORM, VIRTIO_F_VERSION_1,
|
||||
};
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use vm_device::{Migratable, MigratableError, Pausable, Snapshotable};
|
||||
use vm_memory::GuestMemoryMmap;
|
||||
use vmm_sys_util::eventfd::EventFd;
|
||||
@@ -86,7 +86,7 @@ pub const EVENTS_LEN: usize = 6;
|
||||
/// - again, attempt to fetch any incoming packets queued by the backend into virtio RX buffers.
|
||||
///
|
||||
pub struct VsockEpollHandler<B: VsockBackend> {
|
||||
pub mem: Arc<RwLock<GuestMemoryMmap>>,
|
||||
pub mem: Arc<ArcSwap<GuestMemoryMmap>>,
|
||||
pub queues: Vec<Queue>,
|
||||
pub queue_evts: Vec<EventFd>,
|
||||
pub kill_evt: EventFd,
|
||||
@@ -119,7 +119,7 @@ where
|
||||
|
||||
let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize];
|
||||
let mut used_count = 0;
|
||||
let mem = self.mem.read().unwrap();
|
||||
let mem = self.mem.load();
|
||||
for avail_desc in self.queues[0].iter(&mem) {
|
||||
let used_len = match VsockPacket::from_rx_virtq_head(&avail_desc) {
|
||||
Ok(mut pkt) => {
|
||||
@@ -161,7 +161,7 @@ where
|
||||
|
||||
let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize];
|
||||
let mut used_count = 0;
|
||||
let mem = self.mem.read().unwrap();
|
||||
let mem = self.mem.load();
|
||||
for avail_desc in self.queues[1].iter(&mem) {
|
||||
let pkt = match VsockPacket::from_tx_virtq_head(&avail_desc) {
|
||||
Ok(pkt) => pkt,
|
||||
@@ -496,7 +496,7 @@ where
|
||||
|
||||
fn activate(
|
||||
&mut self,
|
||||
mem: Arc<RwLock<GuestMemoryMmap>>,
|
||||
mem: Arc<ArcSwap<GuestMemoryMmap>>,
|
||||
interrupt_cb: Arc<VirtioInterrupt>,
|
||||
queues: Vec<Queue>,
|
||||
queue_evts: Vec<EventFd>,
|
||||
@@ -664,7 +664,7 @@ mod tests {
|
||||
|
||||
// Test a bad activation.
|
||||
let bad_activate = ctx.device.activate(
|
||||
Arc::new(RwLock::new(ctx.mem.clone())),
|
||||
Arc::new(ArcSwap::from(Arc::new(ctx.mem.clone()))),
|
||||
Arc::new(
|
||||
Box::new(move |_: &VirtioInterruptType, _: Option<&Queue>| Ok(()))
|
||||
as VirtioInterrupt,
|
||||
@@ -680,7 +680,7 @@ mod tests {
|
||||
// Test a correct activation.
|
||||
ctx.device
|
||||
.activate(
|
||||
Arc::new(RwLock::new(ctx.mem.clone())),
|
||||
Arc::new(ArcSwap::new(Arc::new(ctx.mem.clone()))),
|
||||
Arc::new(
|
||||
Box::new(move |_: &VirtioInterruptType, _: Option<&Queue>| Ok(()))
|
||||
as VirtioInterrupt,
|
||||
|
||||
@@ -17,9 +17,8 @@ pub use self::device::Vsock;
|
||||
pub use self::unix::VsockUnixBackend;
|
||||
pub use self::unix::VsockUnixError;
|
||||
|
||||
use std::os::unix::io::RawFd;
|
||||
|
||||
use packet::VsockPacket;
|
||||
use std::os::unix::io::RawFd;
|
||||
|
||||
mod defs {
|
||||
|
||||
@@ -158,22 +157,20 @@ pub trait VsockBackend: VsockChannel + VsockEpollListener + Send {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use libc::EFD_NONBLOCK;
|
||||
|
||||
use super::device::{VsockEpollHandler, RX_QUEUE_EVENT, TX_QUEUE_EVENT};
|
||||
use super::packet::VSOCK_PKT_HDR_SIZE;
|
||||
use super::*;
|
||||
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use vmm_sys_util::eventfd::EventFd;
|
||||
|
||||
use crate::device::{VirtioInterrupt, VirtioInterruptType};
|
||||
use crate::queue::tests::VirtQueue as GuestQ;
|
||||
use crate::queue::Queue;
|
||||
use crate::{VIRTQ_DESC_F_NEXT, VIRTQ_DESC_F_WRITE};
|
||||
use arc_swap::ArcSwap;
|
||||
use libc::EFD_NONBLOCK;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use vm_memory::{GuestAddress, GuestMemoryMmap};
|
||||
use vmm_sys_util::eventfd::EventFd;
|
||||
|
||||
pub struct TestBackend {
|
||||
pub evfd: EventFd,
|
||||
@@ -303,7 +300,7 @@ mod tests {
|
||||
guest_txvq,
|
||||
guest_evvq,
|
||||
handler: VsockEpollHandler {
|
||||
mem: Arc::new(RwLock::new(self.mem.clone())),
|
||||
mem: Arc::new(ArcSwap::new(Arc::new(self.mem.clone()))),
|
||||
queues,
|
||||
queue_evts,
|
||||
kill_evt: EventFd::new(EFD_NONBLOCK).unwrap(),
|
||||
|
||||
Reference in New Issue
Block a user