在https://github.com/qemu/qemu/blob/stable-4.2/cpus.c#L1290中,有一个非常重要的Qemu。我猜这是KVM上CPU的事件循环。
这是代码:
static void *qemu_kvm_cpu_thread_fn(void *arg)
{
CPUState *cpu = arg;
int r;
rcu_register_thread();
qemu_mutex_lock_iothread();
qemu_thread_get_self(cpu->thread);
cpu->thread_id = qemu_get_thread_id();
cpu->can_do_io = 1;
current_cpu = cpu;
r = kvm_init_vcpu(cpu);
if (r < 0) {
error_report("kvm_init_vcpu failed: %s", strerror(-r));
exit(1);
}
kvm_init_cpu_signals(cpu);
/* signal CPU creation */
cpu->created = true;
qemu_cond_signal(&qemu_cpu_cond);
qemu_guest_random_seed_thread_part2(cpu->random_seed);
do {
if (cpu_can_run(cpu)) {
r = kvm_cpu_exec(cpu);
if (r == EXCP_DEBUG) {
cpu_handle_guest_debug(cpu);
}
}
qemu_wait_io_event(cpu);
} while (!cpu->unplug || cpu_can_run(cpu));
qemu_kvm_destroy_vcpu(cpu);
cpu->created = false;
qemu_cond_signal(&qemu_cpu_cond);
qemu_mutex_unlock_iothread();
rcu_unregister_thread();
return NULL;
}
我对do
循环感兴趣。它调用kvm_cpu_exec
一个循环,该循环在这里定义:https : //github.com/qemu/qemu/blob/stable-4.2/accel/kvm/kvm-all.c#L2285
在的一点kvm_cpu_exec
,它调用run_ret = kvm_vcpu_ioctl(cpu, KVM_RUN, 0);
,它调用KVM_RUN
此处记录的ioctl:https : //www.kernel.org/doc/Documentation/virtual/kvm/api.txt
4.10 KVM_RUN
功能:基本
体系结构:全部
类型:vcpu ioctl
参数:无
返回值:成功时为0,错误时为-1
错误:
EINTR:未屏蔽的信号正在等待处理该ioctl用于运行来宾虚拟cpu。虽然没有
显式参数,但可以
通过mmap()将vcpu fd偏移为0来获得隐式参数块,其大小由
KVM_GET_VCPU_MMAP_SIZE给出。参数块的格式为“ struct
kvm_run”(请参见下文)。
我正在努力了解此ioctl是否会阻止执行?在什么情况下返回?
我想对正在发生的事情有一点了解。给定该行qemu_wait_io_event(cpu)
,至少在每次要向CPU读取/写入事件时,ioctl都会返回。我不知道,我很困惑。
KVM API设计要求VM中的每个虚拟CPU在诸如QEMU之类的程序中具有关联的用户空间线程,该线程控制着该VM(该程序通常称为“虚拟机监视器”或VMM,并且不必QEMU;其他示例是kvmtool和firecracker。
该线程的行为就像QEMU中的普通用户空间线程一样,直到生成KVM_RUN ioctl为止。此时,内核使用该线程在与该线程关联的vCPU上执行客户代码。这一直持续到遇到某种情况为止,这意味着来宾执行无法继续进行。(一个常见的条件是“来宾对QEMU正在模拟的设备进行内存访问”。)这时,内核停止在该线程上运行来宾代码,而是使其从KVM_RUN ioctl返回。然后,QEMU中的代码查看返回代码,以此类推,以找出为什么获得控制权,处理任何情况,然后循环回以再次调用KVM_RUN以要求内核继续运行来宾代码。
通常,在运行VM时,您几乎会看到线程一直在KVM_RUN ioctl内部运行,并一直在运行真实的来宾代码。有时执行会返回,QEMU将花费尽可能少的时间做任何需要做的事情,然后循环运行并再次运行来宾代码。一种提高VM效率的方法是,尝试确保这些“ VM出口”的数量尽可能少(例如,通过仔细选择来宾所使用的网络或块设备类型)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句