vmm: remove lock for VmState

The lock doesn't make any sense. There is no shared ownership. All
accesses are already synchronized by accesses on a higher level.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
This commit is contained in:
Philipp Schuster
2026-02-12 19:03:07 +01:00
committed by Rob Bradford
parent 9babad0114
commit 03ef7d1991
2 changed files with 22 additions and 44 deletions
+2 -2
View File
@@ -1875,7 +1875,7 @@ impl RequestHandler for Vmm {
match &self.vm_config { match &self.vm_config {
Some(vm_config) => { Some(vm_config) => {
let state = match &self.vm { let state = match &self.vm {
Some(vm) => vm.get_state()?, Some(vm) => vm.get_state(),
None => VmState::Created, None => VmState::Created,
}; };
let config = vm_config.lock().unwrap().clone(); let config = vm_config.lock().unwrap().clone();
@@ -2347,7 +2347,7 @@ impl RequestHandler for Vmm {
return e; return e;
} }
if vm.get_state().unwrap() == VmState::Paused if vm.get_state() == VmState::Paused
&& let Err(e) = vm.resume() && let Err(e) = vm.resume()
{ {
return e; return e;
+20 -42
View File
@@ -19,7 +19,7 @@ use std::mem::size_of;
use std::num::Wrapping; use std::num::Wrapping;
use std::ops::Deref; use std::ops::Deref;
use std::os::unix::net::UnixStream; use std::os::unix::net::UnixStream;
use std::sync::{Arc, Mutex, RwLock}; use std::sync::{Arc, Mutex};
#[cfg(not(target_arch = "riscv64"))] #[cfg(not(target_arch = "riscv64"))]
use std::time::Instant; use std::time::Instant;
use std::{cmp, result, str, thread}; use std::{cmp, result, str, thread};
@@ -150,9 +150,6 @@ pub enum Error {
#[error("Cannot enable interrupt controller")] #[error("Cannot enable interrupt controller")]
EnableInterruptController(#[source] interrupt_controller::Error), EnableInterruptController(#[source] interrupt_controller::Error),
#[error("VM state is poisoned")]
PoisonedState,
#[error("Error from device manager")] #[error("Error from device manager")]
DeviceManager(#[source] DeviceManagerError), DeviceManager(#[source] DeviceManagerError),
@@ -511,7 +508,7 @@ pub struct Vm {
threads: Vec<thread::JoinHandle<()>>, threads: Vec<thread::JoinHandle<()>>,
device_manager: Arc<Mutex<DeviceManager>>, device_manager: Arc<Mutex<DeviceManager>>,
config: Arc<Mutex<VmConfig>>, config: Arc<Mutex<VmConfig>>,
state: RwLock<VmState>, state: VmState,
cpu_manager: Arc<Mutex<cpu::CpuManager>>, cpu_manager: Arc<Mutex<cpu::CpuManager>>,
memory_manager: Arc<Mutex<MemoryManager>>, memory_manager: Arc<Mutex<MemoryManager>>,
#[cfg_attr(any(not(feature = "kvm"), target_arch = "aarch64"), allow(dead_code))] #[cfg_attr(any(not(feature = "kvm"), target_arch = "aarch64"), allow(dead_code))]
@@ -875,7 +872,7 @@ impl Vm {
None None
}; };
let vm_state = if snapshot.is_some() { let state = if snapshot.is_some() {
VmState::Paused VmState::Paused
} else { } else {
VmState::Created VmState::Created
@@ -888,7 +885,7 @@ impl Vm {
device_manager, device_manager,
config, config,
threads: Vec::with_capacity(1), threads: Vec::with_capacity(1),
state: RwLock::new(vm_state), state,
cpu_manager, cpu_manager,
memory_manager, memory_manager,
vm, vm,
@@ -1669,10 +1666,9 @@ impl Vm {
} }
pub fn shutdown(&mut self) -> Result<()> { pub fn shutdown(&mut self) -> Result<()> {
let mut state = self.state.try_write().map_err(|_| Error::PoisonedState)?;
let new_state = VmState::Shutdown; let new_state = VmState::Shutdown;
state.valid_transition(new_state)?; self.state.valid_transition(new_state)?;
// Wake up the DeviceManager threads so they will get terminated cleanly // Wake up the DeviceManager threads so they will get terminated cleanly
self.device_manager self.device_manager
@@ -1691,7 +1687,7 @@ impl Vm {
for thread in self.threads.drain(..) { for thread in self.threads.drain(..) {
thread.join().map_err(Error::ThreadCleanup)?; thread.join().map_err(Error::ThreadCleanup)?;
} }
*state = new_state; self.state = new_state;
Ok(()) Ok(())
} }
@@ -2378,7 +2374,7 @@ impl Vm {
pub fn boot(&mut self) -> Result<()> { pub fn boot(&mut self) -> Result<()> {
trace_scoped!("Vm::boot"); trace_scoped!("Vm::boot");
let current_state = self.get_state()?; let current_state = self.state;
if current_state == VmState::Paused { if current_state == VmState::Paused {
return self.resume().map_err(Error::Resume); return self.resume().map_err(Error::Resume);
} }
@@ -2562,8 +2558,7 @@ impl Vm {
.start_boot_vcpus(new_state == VmState::BreakPoint) .start_boot_vcpus(new_state == VmState::BreakPoint)
.map_err(Error::CpuManager)?; .map_err(Error::CpuManager)?;
let mut state = self.state.try_write().map_err(|_| Error::PoisonedState)?; self.state = new_state;
*state = new_state;
Ok(()) Ok(())
} }
@@ -2593,12 +2588,9 @@ impl Vm {
Arc::clone(&self.config) Arc::clone(&self.config)
} }
/// Get the VM state. Returns an error if the state is poisoned. /// Get the VM state.
pub fn get_state(&self) -> Result<VmState> { pub fn get_state(&self) -> VmState {
self.state self.state
.try_read()
.map_err(|_| Error::PoisonedState)
.map(|state| *state)
} }
/// Gets the actual size of the balloon. /// Gets the actual size of the balloon.
@@ -2850,13 +2842,8 @@ impl Vm {
impl Pausable for Vm { impl Pausable for Vm {
fn pause(&mut self) -> std::result::Result<(), MigratableError> { fn pause(&mut self) -> std::result::Result<(), MigratableError> {
event!("vm", "pausing"); event!("vm", "pausing");
let mut state = self
.state
.try_write()
.map_err(|e| MigratableError::Pause(anyhow!("Could not get VM state: {e}")))?;
let new_state = VmState::Paused; let new_state = VmState::Paused;
self.state
state
.valid_transition(new_state) .valid_transition(new_state)
.map_err(|e| MigratableError::Pause(anyhow!("Invalid transition: {e:?}")))?; .map_err(|e| MigratableError::Pause(anyhow!("Invalid transition: {e:?}")))?;
@@ -2883,7 +2870,7 @@ impl Pausable for Vm {
.pause() .pause()
.map_err(|e| MigratableError::Pause(anyhow!("Could not pause the VM: {e}")))?; .map_err(|e| MigratableError::Pause(anyhow!("Could not pause the VM: {e}")))?;
*state = new_state; self.state = new_state;
event!("vm", "paused"); event!("vm", "paused");
Ok(()) Ok(())
@@ -2891,14 +2878,10 @@ impl Pausable for Vm {
fn resume(&mut self) -> std::result::Result<(), MigratableError> { fn resume(&mut self) -> std::result::Result<(), MigratableError> {
event!("vm", "resuming"); event!("vm", "resuming");
let current_state = self.get_state().unwrap(); let current_state = self.get_state();
let mut state = self
.state
.try_write()
.map_err(|e| MigratableError::Resume(anyhow!("Could not get VM state: {e}")))?;
let new_state = VmState::Running; let new_state = VmState::Running;
state self.state
.valid_transition(new_state) .valid_transition(new_state)
.map_err(|e| MigratableError::Resume(anyhow!("Invalid transition: {e:?}")))?; .map_err(|e| MigratableError::Resume(anyhow!("Invalid transition: {e:?}")))?;
@@ -2921,7 +2904,7 @@ impl Pausable for Vm {
self.device_manager.lock().unwrap().resume()?; self.device_manager.lock().unwrap().resume()?;
// And we're back to the Running state. // And we're back to the Running state.
*state = new_state; self.state = new_state;
event!("vm", "resumed"); event!("vm", "resumed");
Ok(()) Ok(())
} }
@@ -2953,8 +2936,7 @@ impl Snapshottable for Vm {
} }
} }
let current_state = self.get_state().unwrap(); if self.get_state() != VmState::Paused {
if current_state != VmState::Paused {
return Err(MigratableError::Snapshot(anyhow!( return Err(MigratableError::Snapshot(anyhow!(
"Trying to snapshot while VM is running" "Trying to snapshot while VM is running"
))); )));
@@ -3116,20 +3098,16 @@ impl Debuggable for Vm {
} }
fn debug_pause(&mut self) -> std::result::Result<(), DebuggableError> { fn debug_pause(&mut self) -> std::result::Result<(), DebuggableError> {
if *self.state.read().unwrap() == VmState::Running { if self.state == VmState::Running {
self.pause().map_err(DebuggableError::Pause)?; self.pause().map_err(DebuggableError::Pause)?;
} }
let mut state = self self.state = VmState::BreakPoint;
.state
.try_write()
.map_err(|_| DebuggableError::PoisonedState)?;
*state = VmState::BreakPoint;
Ok(()) Ok(())
} }
fn debug_resume(&mut self) -> std::result::Result<(), DebuggableError> { fn debug_resume(&mut self) -> std::result::Result<(), DebuggableError> {
if *self.state.read().unwrap() == VmState::BreakPoint { if self.state == VmState::BreakPoint {
self.resume().map_err(DebuggableError::Pause)?; self.resume().map_err(DebuggableError::Pause)?;
} }
@@ -3209,7 +3187,7 @@ impl GuestDebuggable for Vm {
} }
} }
match self.get_state().unwrap() { match self.get_state() {
VmState::Running => { VmState::Running => {
self.pause().map_err(GuestDebuggableError::Pause)?; self.pause().map_err(GuestDebuggableError::Pause)?;
resume = true; resume = true;