Skip to content

Commit 592b3a6

Browse files
committed
refactor: remove TLS from vcpus
Instead of storing mmaped kvm_vcpu struct in the TLS, we can have it in the VcpuHandle. This way we don't need to deal with TLS and it's synchronization. Signed-off-by: Egor Lazarchuk <[email protected]>
1 parent 4a21dc6 commit 592b3a6

File tree

3 files changed

+70
-97
lines changed

3 files changed

+70
-97
lines changed

src/vmm/src/builder.rs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ pub fn build_microvm_for_boot(
281281
boot_cmdline,
282282
)?;
283283

284-
let vmm = Vmm {
284+
let mut vmm = Vmm {
285285
instance_info: instance_info.clone(),
286286
shutdown_exit_code: None,
287287
kvm,
@@ -292,6 +292,16 @@ pub fn build_microvm_for_boot(
292292
device_manager,
293293
};
294294

295+
// Move vcpus to their own threads and start their state machine in the 'Paused' state.
296+
vmm.start_vcpus(
297+
vcpus,
298+
seccomp_filters
299+
.get("vcpu")
300+
.ok_or_else(|| StartMicrovmError::MissingSeccompFilters("vcpu".to_string()))?
301+
.clone(),
302+
)
303+
.map_err(VmmError::VcpuStart)?;
304+
295305
let vmm = Arc::new(Mutex::new(vmm));
296306

297307
#[cfg(feature = "gdb")]
@@ -308,18 +318,6 @@ pub fn build_microvm_for_boot(
308318
debug!("No GDB socket provided not starting gdb server.");
309319
}
310320

311-
// Move vcpus to their own threads and start their state machine in the 'Paused' state.
312-
vmm.lock()
313-
.unwrap()
314-
.start_vcpus(
315-
vcpus,
316-
seccomp_filters
317-
.get("vcpu")
318-
.ok_or_else(|| StartMicrovmError::MissingSeccompFilters("vcpu".to_string()))?
319-
.clone(),
320-
)
321-
.map_err(VmmError::VcpuStart)?;
322-
323321
// Load seccomp filters for the VMM thread.
324322
// Execution panics if filters cannot be loaded, use --no-seccomp if skipping filters
325323
// altogether is the desired behaviour.

src/vmm/src/lib.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -353,8 +353,11 @@ impl Vmm {
353353
#[cfg(target_arch = "x86_64")]
354354
vcpu.kvm_vcpu.set_pio_bus(self.vm.pio_bus.clone());
355355

356-
self.vcpus_handles
357-
.push(vcpu.start_threaded(vcpu_seccomp_filter.clone(), barrier.clone())?);
356+
self.vcpus_handles.push(vcpu.start_threaded(
357+
&self.vm,
358+
vcpu_seccomp_filter.clone(),
359+
barrier.clone(),
360+
)?);
358361
}
359362
self.instance_info.state = VmState::Paused;
360363
// Wait for vCPUs to initialize their TLS before moving forward.
@@ -369,7 +372,7 @@ impl Vmm {
369372

370373
// Send the events.
371374
self.vcpus_handles
372-
.iter()
375+
.iter_mut()
373376
.try_for_each(|handle| handle.send_event(VcpuEvent::Resume))
374377
.map_err(|_| VmmError::VcpuMessage)?;
375378

@@ -391,7 +394,7 @@ impl Vmm {
391394
pub fn pause_vm(&mut self) -> Result<(), VmmError> {
392395
// Send the events.
393396
self.vcpus_handles
394-
.iter()
397+
.iter_mut()
395398
.try_for_each(|handle| handle.send_event(VcpuEvent::Pause))
396399
.map_err(|_| VmmError::VcpuMessage)?;
397400

@@ -450,7 +453,7 @@ impl Vmm {
450453
}
451454

452455
fn save_vcpu_states(&mut self) -> Result<Vec<VcpuState>, MicrovmStateError> {
453-
for handle in self.vcpus_handles.iter() {
456+
for handle in self.vcpus_handles.iter_mut() {
454457
handle
455458
.send_event(VcpuEvent::SaveState)
456459
.map_err(MicrovmStateError::SignalVcpu)?;
@@ -479,7 +482,7 @@ impl Vmm {
479482

480483
/// Dumps CPU configuration.
481484
pub fn dump_cpu_config(&mut self) -> Result<Vec<CpuConfiguration>, DumpCpuConfigError> {
482-
for handle in self.vcpus_handles.iter() {
485+
for handle in self.vcpus_handles.iter_mut() {
483486
handle
484487
.send_event(VcpuEvent::DumpCpuConfig)
485488
.map_err(DumpCpuConfigError::SendEvent)?;
@@ -615,7 +618,7 @@ impl Vmm {
615618
// We send a "Finish" event. If a VCPU has already exited, this is the only
616619
// message it will accept... but running and paused will take it as well.
617620
// It breaks out of the state machine loop so that the thread can be joined.
618-
for (idx, handle) in self.vcpus_handles.iter().enumerate() {
621+
for (idx, handle) in self.vcpus_handles.iter_mut().enumerate() {
619622
if let Err(err) = handle.send_event(VcpuEvent::Finish) {
620623
error!("Failed to send VcpuEvent::Finish to vCPU {}: {}", idx, err);
621624
}

0 commit comments

Comments
 (0)