mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-24 22:55:19 +00:00
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 <foxywang@tencent.com>
(cherry picked from commit d46dd4b31f
)
This commit is contained in:
parent
c14f9ee2f4
commit
a03f17a275
@ -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<AtomicBool>,
|
||||
handle: Option<thread::JoinHandle<()>>,
|
||||
kill: Arc<AtomicBool>,
|
||||
vcpu_run_interrupted: Arc<AtomicBool>,
|
||||
@ -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)?;
|
||||
|
Loading…
Reference in New Issue
Block a user