783 字
4 分钟
Guest OS 运行和迁移线程的关系
这是一个非常好的问题!让我为您详细分析 QEMU 中 Guest OS 运行和迁移线程的关系:
[10 tools called]
基于代码分析,我为您详细解释 QEMU 中 Guest OS 运行和迁移线程的关系:
🔄 并行 + 协调模式
QEMU 采用的是并行为主,协调同步的模式:
1️⃣ 并行运行阶段 (大部分时间)
// 创建独立的迁移线程
qemu_thread_create(&s->thread, "live_migration",
migration_thread, s, QEMU_THREAD_JOINABLE);
特点:
- ✅ Guest OS 继续运行 - vCPU 线程正常执行 Guest 代码
- ✅ 迁移线程并行工作 - 独立传输内存页和设备状态
- ✅ 真正的”热”迁移 - 虚拟机对用户来说仍在正常工作
2️⃣ 协调同步机制 - BQL (Big QEMU Lock)
// 迁移线程访问共享资源时获取锁
bql_lock(); // 获取大内核锁
qemu_savevm_state_setup(s->to_dst_file); // 访问VM状态
bql_unlock(); // 释放大内核锁
作用:
- 🔒 保护共享的 VM 状态不被同时修改
- 🔄 让迁移线程和 vCPU 线程轮流访问关键数据
- ⚡ 迁移线程会周期性让出控制权给主循环
3️⃣ 短暂暂停阶段 (Downtime)
// 迁移最后阶段:暂停VM完成最终传输
static int migration_stop_vm(MigrationState *s, RunState state)
{
migration_downtime_start(s); // 开始停机时间计算
ret = vm_stop_force_state(state); // 🛑 暂停Guest OS
// 传输最后的脏页和设备状态
migration_downtime_end(s); // 结束停机时间计算
}
触发条件:
- 脏页数量降至阈值以下 (
pending_size < s->threshold_size
) - 准备完成最终状态传输
📊 完整时间线
Guest OS: [运行中] ──────────────────── [暂停] ── [继续运行/切换到目标]
↑ ↑ ↑
迁移线程: [启动] ─── [并行传输] ─── [完成] [结束]
↑ ↑
时间轴: Setup阶段 Complete阶段
(几秒-几分钟) (几毫秒-几秒)
🎯 各阶段详情:
- Setup 阶段 - Guest OS 继续运行,迁移线程开始工作
- Iterate 阶段 - 并行运行,迁移线程传输脏页,Guest OS 产生新脏页
- Complete 阶段 - Guest OS 短暂暂停,完成最终状态传输
💡 关键设计原理
为什么要并行?
- 最小化停机时间 - Guest OS 大部分时间都在运行
- 用户体验 - 应用感受不到迁移过程
- 性能优化 - 充分利用多核 CPU 资源
为什么需要协调?
- 数据一致性 - 避免迁移过程中状态损坏
- 内存同步 - 正确处理脏页标记和传输
- 设备状态 - 确保设备寄存器状态正确迁移
RAM 迁移的特殊处理:
// RAM迁移会周期性让出控制权
// 让Guest OS有机会运行
if ((i & 32767) == 0 && qemu_in_coroutine()) {
qemu_coroutine_yield(); // 让出控制权给主循环
}
🎯 总结
QEMU 的迁移模式是智能的并行+协调架构:
- 99%的时间并行运行 - Guest OS 和迁移线程同时工作
- 关键时刻协调同步 - 使用 BQL 保护共享状态
- 最小化暂停时间 - 只在最后完成阶段短暂暂停 Guest OS
这就是为什么叫”热迁移”或”活迁移”的原因 - Guest OS 在迁移过程中大部分时间都保持运行状态!
Guest OS 运行和迁移线程的关系
https://scudays.github.io/posts/icsas/guest-os-运行和迁移线程的关系/