Skip to content

Commit faca4ac

Browse files
committed
feat: 添加 VM 初始化和运行管理模块,优化 CPU 处理逻辑
1 parent 7ac8334 commit faca4ac

File tree

7 files changed

+138
-28
lines changed

7 files changed

+138
-28
lines changed
Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::{
88
use arm_vcpu::Aarch64VCpuSetupConfig;
99

1010
use crate::{
11-
GuestPhysAddr, TASK_STACK_SIZE, VmAddrSpace, VmMachineInitedOps,
11+
GuestPhysAddr, TASK_STACK_SIZE, VmAddrSpace, VmMachineInitedOps, VmMachineRunningCommon,
1212
arch::{VmMachineRunning, cpu::VCpu},
1313
config::AxVMConfig,
1414
data::VmDataWeak,
@@ -40,15 +40,17 @@ impl VmMachineInitedOps for VmMachineInited {
4040
&self.name
4141
}
4242

43-
fn start(self, vmdata: VmDataWeak) -> Result<Self::Running, (anyhow::Error, Self)> {
43+
fn start(self, vmdata: VmDataWeak) -> Result<Self::Running, anyhow::Error> {
4444
debug!("Starting VM {} ({})", self.id, self.name);
45-
let running = VmMachineRunning::new();
46-
info!(
47-
"VM {} ({}) with {} cpus booted successfully.",
48-
self.id,
49-
self.name,
50-
self.vcpus.len()
51-
);
45+
let mut running = VmMachineRunning {
46+
common: VmMachineRunningCommon::new(self.vmspace, self.vcpus, vmdata),
47+
};
48+
49+
let main = running.common.take_cpu()?;
50+
51+
running.common.run_cpu(main)?;
52+
53+
info!("VM {} ({}) main cpu started.", self.id, self.name,);
5254
Ok(running)
5355
}
5456
}

src/arch/aarch64/vm/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ use alloc::string::String;
22

33
use crate::GuestPhysAddr;
44

5-
mod init;
5+
mod inited;
66
mod running;
77
mod unint;
88

9-
pub(crate) use init::*;
9+
pub(crate) use inited::*;
1010
pub(crate) use running::*;
1111
pub(crate) use unint::*;
1212

src/arch/aarch64/vm/running.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
use fdt_edit::NodeRef;
22

3-
use crate::{VmMachineRunningOps, VmMachineStoppingOps, arch::vm::DevMapConfig};
3+
use crate::{
4+
VmAddrSpace, VmMachineRunningCommon, VmMachineRunningOps, VmMachineStoppingOps,
5+
arch::vm::DevMapConfig,
6+
};
47

58
/// Data needed when VM is running
6-
pub struct VmMachineRunning {}
9+
pub struct VmMachineRunning {
10+
pub(super) common: VmMachineRunningCommon,
11+
}
712

813
impl VmMachineRunning {
9-
pub(crate) fn new() -> Self {
10-
Self {}
11-
}
12-
1314
fn handle_node_regs(dev_vec: &mut [DevMapConfig], node: &NodeRef<'_>) {}
1415
}
1516

src/arch/aarch64/vm/unint.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,11 @@ impl VmMachineUninitOps for VmMachineUninit {
3333
}
3434
}
3535

36-
fn init(mut self, vmdata: VmDataWeak) -> Result<Self::Inited, (anyhow::Error, Self)>
36+
fn init(mut self, vmdata: VmDataWeak) -> Result<Self::Inited, anyhow::Error>
3737
where
3838
Self: Sized,
3939
{
40-
match self.init_raw(vmdata) {
41-
Ok(inited) => Ok(inited),
42-
Err(e) => Err((e, self)),
43-
}
40+
self.init_raw(vmdata)
4441
}
4542
}
4643

src/vm/data.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,10 @@ impl VmData {
111111
VmMachineState::Uninit(uninit) => {
112112
let init = match uninit.init(self.downgrade()) {
113113
Ok(inited) => inited,
114-
Err((e, uninit)) => {
115-
*status_guard = VmMachineState::Uninit(uninit);
114+
Err(e) => {
115+
self.set_err(RunError::ExitWithError(anyhow!("{e}")));
116+
*status_guard = VmMachineState::Stopped;
117+
self.status.store(VMStatus::Stopped);
116118
return Err(e);
117119
}
118120
};
@@ -137,8 +139,10 @@ impl VmData {
137139
self.status.store(VMStatus::Running);
138140
Ok(())
139141
}
140-
Err((e, init)) => {
141-
*status_guard = VmMachineState::Inited(init);
142+
Err(e) => {
143+
self.set_err(RunError::ExitWithError(anyhow!("{e}")));
144+
*status_guard = VmMachineState::Stopped;
145+
self.status.store(VMStatus::Stopped);
142146
Err(e)
143147
}
144148
},
@@ -195,6 +199,14 @@ impl VmDataWeak {
195199
false
196200
}
197201
}
202+
203+
pub(crate) fn set_stopped(&self) {
204+
if let Some(inner) = self.upgrade() {
205+
let mut status_guard = inner.machine.write();
206+
*status_guard = VmMachineState::Stopped;
207+
inner.status.store(VMStatus::Stopped);
208+
}
209+
}
198210
}
199211

200212
impl Debug for VmDataWeak {

src/vm/machine/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@ use crate::{
77
data::VmDataWeak,
88
};
99

10+
mod running;
11+
12+
pub(crate) use running::*;
13+
1014
pub trait VmMachineUninitOps {
1115
type Inited: VmMachineInitedOps;
1216
fn new(config: AxVMConfig) -> Self;
13-
fn init(self, vmdata: VmDataWeak) -> Result<Self::Inited, (anyhow::Error, Self)>
17+
fn init(self, vmdata: VmDataWeak) -> Result<Self::Inited, anyhow::Error>
1418
where
1519
Self: Sized;
1620
}
@@ -19,7 +23,7 @@ pub trait VmMachineInitedOps {
1923
type Running: VmMachineRunningOps;
2024
fn id(&self) -> VmId;
2125
fn name(&self) -> &str;
22-
fn start(self, vmdata: VmDataWeak) -> Result<Self::Running, (anyhow::Error, Self)>
26+
fn start(self, vmdata: VmDataWeak) -> Result<Self::Running, anyhow::Error>
2327
where
2428
Self: Sized;
2529
}

src/vm/machine/running.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
use core::sync::atomic::{AtomicUsize, Ordering};
2+
use std::{
3+
collections::btree_map::BTreeMap,
4+
os::arceos::{api::task::AxCpuMask, modules::axtask::set_current_affinity},
5+
sync::Arc,
6+
};
7+
8+
use alloc::vec::Vec;
9+
10+
use crate::{
11+
RunError, TASK_STACK_SIZE, VmAddrSpace, arch::cpu::VCpu, data::VmDataWeak, vhal::cpu::CpuHardId,
12+
};
13+
14+
pub struct VmMachineRunningCommon {
15+
pub cpus: BTreeMap<CpuHardId, VCpu>,
16+
pub vmspace: VmAddrSpace,
17+
pub vm: VmDataWeak,
18+
running_cpu_count: Arc<AtomicUsize>,
19+
}
20+
21+
impl VmMachineRunningCommon {
22+
pub fn new(vmspace: VmAddrSpace, vcpu: Vec<VCpu>, vm: VmDataWeak) -> Self {
23+
let mut cpus = BTreeMap::new();
24+
for cpu in vcpu.into_iter() {
25+
cpus.insert(cpu.hard_id(), cpu);
26+
}
27+
28+
VmMachineRunningCommon {
29+
vmspace,
30+
cpus,
31+
vm,
32+
running_cpu_count: Arc::new(AtomicUsize::new(0)),
33+
}
34+
}
35+
36+
pub fn take_cpu(&mut self) -> anyhow::Result<VCpu> {
37+
let next = self
38+
.cpus
39+
.keys()
40+
.next()
41+
.cloned()
42+
.ok_or_else(|| anyhow!("No CPUs available"))?;
43+
let cpu = self.cpus.remove(&next).unwrap();
44+
Ok(cpu)
45+
}
46+
47+
pub fn run_cpu(&mut self, mut cpu: VCpu) -> anyhow::Result<()> {
48+
let waiter = self.new_waiter();
49+
50+
let bind_id = cpu.bind_id();
51+
std::thread::Builder::new()
52+
.name(format!("init-cpu-{}", bind_id))
53+
.stack_size(TASK_STACK_SIZE)
54+
.spawn(move || {
55+
// Initialize cpu affinity here.
56+
assert!(
57+
set_current_affinity(AxCpuMask::one_shot(bind_id.raw())),
58+
"Initialize CPU affinity failed!"
59+
);
60+
info!("Starting VCpu {} on {}", cpu.hard_id(), bind_id);
61+
let res = cpu.run();
62+
if let Err(e) = res {
63+
if let Some(vm) = waiter.vm.upgrade() {
64+
vm.set_err(RunError::ExitWithError(e));
65+
}
66+
}
67+
waiter.running_cpu_count.fetch_sub(1, Ordering::SeqCst);
68+
if waiter.running_cpu_count.load(Ordering::SeqCst) == 0 {
69+
waiter.vm.set_stopped();
70+
}
71+
})
72+
.map_err(|e| anyhow!("{e:?}"))?;
73+
74+
Ok(())
75+
}
76+
77+
fn new_waiter(&self) -> Waiter {
78+
let running_cpu_count = self.running_cpu_count.clone();
79+
running_cpu_count.fetch_add(1, Ordering::SeqCst);
80+
Waiter {
81+
running_cpu_count,
82+
vm: self.vm.clone(),
83+
}
84+
}
85+
86+
pub fn vmspace(&self) -> &VmAddrSpace {
87+
&self.vmspace
88+
}
89+
}
90+
91+
struct Waiter {
92+
running_cpu_count: Arc<AtomicUsize>,
93+
vm: VmDataWeak,
94+
}

0 commit comments

Comments
 (0)