From b6801e355ec58222d60e7af5b60fa76da9d19d66 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Tue, 26 Nov 2019 13:06:24 +0000 Subject: [PATCH] vmm: cpu: Refactor vCPU thread starting Refactor the vCPU thread starting so that there is the possibility to bring on extra vCPU threads. Signed-off-by: Rob Bradford --- vmm/src/cpu.rs | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index 538ae500c..25ca31c0d 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -117,6 +117,9 @@ pub enum Error { /// Failed to allocate IO port AllocateIOPort, + + /// Asking for more vCPUs that we can have + DesiredVCPUCountExceedsMax, } pub type Result = result::Result; @@ -444,7 +447,7 @@ impl CpuManager { fd, vcpus_kill_signalled: Arc::new(AtomicBool::new(false)), vcpus_pause_signalled: Arc::new(AtomicBool::new(false)), - threads: Vec::with_capacity(boot_vcpus as usize), + vcpu_states: Vec::with_capacity(max_vcpus as usize), reset_evt, selected_cpu: 0, })); @@ -468,13 +471,17 @@ impl CpuManager { Ok(cpu_manager) } - // Starts all the vCPUs that the VM is booting with. Blocks until all vCPUs are running. - pub fn start_boot_vcpus(&mut self, entry_addr: GuestAddress) -> Result<()> { + fn activate_vcpus(&mut self, desired_vcpus: u8, entry_addr: GuestAddress) -> Result<()> { + if desired_vcpus > self.max_vcpus { + return Err(Error::DesiredVCPUCountExceedsMax); + } + let creation_ts = std::time::Instant::now(); + let vcpu_thread_barrier = Arc::new(Barrier::new( + (desired_vcpus - self.present_vcpus() + 1) as usize, + )); - let vcpu_thread_barrier = Arc::new(Barrier::new((self.boot_vcpus + 1) as usize)); - - for cpu_id in 0..self.boot_vcpus { + for cpu_id in self.present_vcpus()..desired_vcpus { let ioapic = if let Some(ioapic) = &self.ioapic { Some(ioapic.clone()) } else { @@ -559,6 +566,11 @@ impl CpuManager { Ok(()) } + // Starts all the vCPUs that the VM is booting with. Blocks until all vCPUs are running. + pub fn start_boot_vcpus(&mut self, entry_addr: GuestAddress) -> Result<()> { + self.activate_vcpus(self.boot_vcpus(), entry_addr) + } + pub fn shutdown(&mut self) -> Result<()> { // Tell the vCPUs to stop themselves next time they go through the loop self.vcpus_kill_signalled.store(true, Ordering::SeqCst);