Skip to content

Commit 5a2ad13

Browse files
committed
feat: 增强 vCPU 启动过程的调试信息,优化 CPU 启动逻辑
1 parent 323836b commit 5a2ad13

File tree

3 files changed

+91
-45
lines changed

3 files changed

+91
-45
lines changed

src/arch/aarch64/cpu.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,9 @@ impl VCpuOp for VCpu {
145145
entry_point,
146146
arg,
147147
} => {
148+
debug!("vCPU {} requested CPU {} up", self.bind_id(), target_cpu);
148149
self.vm()?.with_machine_running_mut(|running| {
150+
debug!("vCPU {} is bringing up CPU {}", self.bind_id(), target_cpu);
149151
running.cpu_up(CpuHardId::new(target_cpu as _), entry_point, arg)
150152
})??;
151153
}

src/vm/data.rs

Lines changed: 80 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -106,51 +106,75 @@ impl VmData {
106106
}
107107

108108
pub fn init(&self) -> anyhow::Result<()> {
109-
let mut status_guard = self.machine.write();
110-
match core::mem::replace(&mut *status_guard, VmMachineState::Switching) {
109+
let next;
110+
let res;
111+
let next_state;
112+
113+
match self.replace_status(VmMachineState::Switching) {
111114
VmMachineState::Uninit(uninit) => {
112-
let init = match uninit.init(self.downgrade()) {
113-
Ok(inited) => inited,
115+
match uninit.init(self.downgrade()) {
116+
Ok(inited) => {
117+
next_state = Some(VMStatus::Inited);
118+
res = Ok(());
119+
next = VmMachineState::Inited(inited);
120+
}
114121
Err(e) => {
115122
self.set_err(RunError::ExitWithError(anyhow!("{e}")));
116-
*status_guard = VmMachineState::Stopped;
117-
self.status.store(VMStatus::Stopped);
118-
return Err(e);
123+
next_state = Some(VMStatus::Stopped);
124+
next = VmMachineState::Stopped;
125+
res = Err(e);
119126
}
120127
};
121-
*status_guard = VmMachineState::Inited(init);
122-
self.status.store(VMStatus::Inited);
123-
Ok(())
124128
}
125129
other => {
126-
*status_guard = other;
127-
Err(anyhow::anyhow!("VM is not in Uninit state"))
130+
next = other;
131+
next_state = None;
132+
res = Err(anyhow::anyhow!("VM is not in Uninit state"));
128133
}
129134
}
135+
self.replace_status(next);
136+
if let Some(status) = next_state {
137+
self.status.store(status);
138+
}
139+
res
140+
}
141+
142+
fn replace_status(&self, new_status: VmMachineState) -> VmMachineState {
143+
let mut status_guard = self.machine.write();
144+
core::mem::replace(&mut *status_guard, new_status)
130145
}
131146

132147
pub fn start(&self) -> anyhow::Result<()> {
133148
let data = self.downgrade();
134-
let mut status_guard = self.machine.write();
135-
match core::mem::replace(&mut *status_guard, VmMachineState::Switching) {
149+
let next_state;
150+
let res;
151+
let next = match self.replace_status(VmMachineState::Switching) {
136152
VmMachineState::Inited(init) => match init.start(data) {
137153
Ok(running) => {
138-
*status_guard = VmMachineState::Running(running);
139-
self.status.store(VMStatus::Running);
140-
Ok(())
154+
next_state = Some(VMStatus::Running);
155+
res = Ok(());
156+
VmMachineState::Running(running)
141157
}
142158
Err(e) => {
143159
self.set_err(RunError::ExitWithError(anyhow!("{e}")));
144-
*status_guard = VmMachineState::Stopped;
145-
self.status.store(VMStatus::Stopped);
146-
Err(e)
160+
161+
next_state = Some(VMStatus::Stopped);
162+
res = Err(e);
163+
VmMachineState::Stopped
147164
}
148165
},
149166
other => {
150-
*status_guard = other;
151-
Err(anyhow::anyhow!("VM is not in Init state"))
167+
next_state = None;
168+
169+
res = Err(anyhow::anyhow!("VM is not in Init state"));
170+
other
152171
}
172+
};
173+
self.replace_status(next);
174+
if let Some(status) = next_state {
175+
self.status.store(status);
153176
}
177+
res
154178
}
155179

156180
pub fn downgrade(&self) -> VmDataWeak {
@@ -163,32 +187,46 @@ impl VmData {
163187
where
164188
F: FnOnce(&VmMachineRunning) -> R,
165189
{
166-
let status = self.machine.read();
167-
let running = match &*status {
168-
VmMachineState::Running(running) => running,
169-
_ => {
170-
return Err(RunError::ExitWithError(anyhow!(
171-
"VM is not in Running state"
172-
)));
173-
}
174-
};
175-
Ok(f(running))
190+
loop {
191+
let status = self.machine.read();
192+
let running = match &*status {
193+
VmMachineState::Running(running) => running,
194+
VmMachineState::Switching => {
195+
drop(status);
196+
std::thread::yield_now();
197+
continue;
198+
}
199+
_ => {
200+
return Err(RunError::ExitWithError(anyhow!(
201+
"VM is not in Running state"
202+
)));
203+
}
204+
};
205+
return Ok(f(running));
206+
}
176207
}
177208

178209
pub(crate) fn with_machine_running_mut<F, R>(&self, f: F) -> Result<R, RunError>
179210
where
180211
F: FnOnce(&mut VmMachineRunning) -> R,
181212
{
182-
let mut status = self.machine.write();
183-
let running = match &mut *status {
184-
VmMachineState::Running(running) => running,
185-
_ => {
186-
return Err(RunError::ExitWithError(anyhow!(
187-
"VM is not in Running state"
188-
)));
189-
}
190-
};
191-
Ok(f(running))
213+
loop {
214+
let mut status = self.machine.write();
215+
let running = match &mut *status {
216+
VmMachineState::Running(running) => running,
217+
VmMachineState::Switching => {
218+
drop(status);
219+
std::thread::yield_now();
220+
continue;
221+
}
222+
_ => {
223+
return Err(RunError::ExitWithError(anyhow!(
224+
"VM is not in Running state"
225+
)));
226+
}
227+
};
228+
return Ok(f(running));
229+
}
192230
}
193231
}
194232

src/vm/machine/running.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use core::sync::atomic::{AtomicUsize, Ordering};
1+
use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
22
use std::{
33
collections::btree_map::BTreeMap,
44
os::arceos::{api::task::AxCpuMask, modules::axtask::set_current_affinity},
@@ -47,7 +47,8 @@ impl VmMachineRunningCommon {
4747

4848
pub fn run_cpu<C: VCpuOp>(&mut self, mut cpu: C) -> anyhow::Result<()> {
4949
let waiter = self.new_waiter();
50-
50+
let started = Arc::new(AtomicBool::new(false));
51+
let started_clone = started.clone();
5152
let bind_id = cpu.bind_id();
5253
std::thread::Builder::new()
5354
.name(format!("init-cpu-{}", bind_id))
@@ -58,9 +59,11 @@ impl VmMachineRunningCommon {
5859
set_current_affinity(AxCpuMask::one_shot(bind_id.raw())),
5960
"Initialize CPU affinity failed!"
6061
);
62+
started_clone.store(true, Ordering::SeqCst);
6163
info!("Starting VCpu {} on {}", cpu.hard_id(), bind_id);
6264
let res = cpu.run();
6365
if let Err(e) = res {
66+
info!("vCPU {} exited with error: {e}", bind_id);
6467
if let Some(vm) = waiter.vm.upgrade() {
6568
vm.set_err(e);
6669
}
@@ -72,7 +75,10 @@ impl VmMachineRunningCommon {
7275
}
7376
})
7477
.map_err(|e| anyhow!("{e:?}"))?;
75-
78+
debug!("Waiting for CPU {} to start", bind_id);
79+
while !started.load(Ordering::SeqCst) {
80+
std::thread::yield_now();
81+
}
7682
Ok(())
7783
}
7884

0 commit comments

Comments
 (0)