From a03f17a275fcf5a09403732f79dee1129eb05727 Mon Sep 17 00:00:00 2001 From: Yi Wang Date: Thu, 10 Aug 2023 11:34:09 +0800 Subject: [PATCH] vmm: cpu: Add pending removed vcpu check to avoid resize vcpu hang Add pending removed vcpu check according to VcpuState.removing, which can avoid cloud hypervisor hangup during continual vcpu resize. Fix #5419 Signed-off-by: Yi Wang (cherry picked from commit d46dd4b31f82f487706db9a1be9b1c3f6a10be3e) --- vmm/src/cpu.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index 8db5775a5..f4339ec82 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -116,6 +116,9 @@ pub enum Error { #[error("Error configuring vCPU: {0}")] VcpuConfiguration(#[source] arch::Error), + #[error("Still pending removed vcpu")] + VcpuPendingRemovedVcpu, + #[cfg(target_arch = "aarch64")] #[error("Error fetching preferred target: {0}")] VcpuArmPreferredTarget(#[source] hypervisor::HypervisorVmError), @@ -558,6 +561,7 @@ impl BusDevice for CpuManager { struct VcpuState { inserting: bool, removing: bool, + pending_removal: Arc, handle: Option>, kill: Arc, vcpu_run_interrupted: Arc, @@ -1127,9 +1131,21 @@ impl CpuManager { // Mark vCPUs for removal, actual removal happens on ejection for cpu_id in desired_vcpus..self.present_vcpus() { self.vcpu_states[usize::from(cpu_id)].removing = true; + self.vcpu_states[usize::from(cpu_id)] + .pending_removal + .store(true, Ordering::SeqCst); } } + pub fn check_pending_removed_vcpu(&mut self) -> bool { + for state in self.vcpu_states.iter() { + if state.active() && state.pending_removal.load(Ordering::SeqCst) { + return true; + } + } + false + } + fn remove_vcpu(&mut self, cpu_id: u8) -> Result<()> { info!("Removing vCPU: cpu_id = {}", cpu_id); let mut state = &mut self.vcpu_states[usize::from(cpu_id)]; @@ -1140,6 +1156,7 @@ impl CpuManager { // Once the thread has exited, clear the "kill" so that it can reused state.kill.store(false, Ordering::SeqCst); + state.pending_removal.store(false, Ordering::SeqCst); Ok(()) } @@ -1173,6 +1190,10 @@ impl CpuManager { return Ok(false); } + if self.check_pending_removed_vcpu() { + return Err(Error::VcpuPendingRemovedVcpu); + } + match desired_vcpus.cmp(&self.present_vcpus()) { cmp::Ordering::Greater => { self.create_vcpus(desired_vcpus, None)?;