代码版本:linux-git v4.10.0-rc3

1.kvm clock时钟

1)KVM clock 在guest中:

kvmclock_init负责在guest启动过程中初始化kvm clock,首先更新了两个MSR值:

#define MSR_KVM_WALL_CLOCK_NEW 0x4b564d00

#define MSR_KVM_SYSTEM_TIME_NEW 0x4b564d01

然后为每个CPU分配struct pvclock_vsyscall_time_info内存,

获取了首要CPU的pvti对应的物理地址,将其写入到msr_kvm_system_time MSR中

获取当前的时钟偏移

获取pv clock信息转换成hz

写完msr后wall_clock就是更新后的墙上时间,即guest启动的日期。

然后再加上pvclock_clocksource_read(vcpu_time)即guest启动时间,则就是当前guest中的real time

2)KVM clock 在host中:

(1) MSR_KVM_SYSTEM_TIME_NEW

缓存地址转换的信息。

(2) MSR_KVM_WALL_CLOCK_NEW

在kvm_arch_init_vm中有

kvm->arch.kvmclock_offset = -ktime_get_boot_ns();

因为kvmclock_offset为负值,相减即相加,host启动日期加上guest启动的距离host启动时间的差值等于guest启动的日期,所以write msr的结果就是这样。

2.kvm_guest_time_update分析

3.关于use_master_clock

在kvm_write_tsc中,本次tsc写和上次的tsc写比较,得到elapsed和usdiff

用usdiff与elapsed进行对冲,如果二者差值小于usdiff < USEC_PER_SEC则证明tsc是稳定

因为last_tsc_write和last_tsc_nsec都是在KVM下而非vcpu下,就是证明所有tsc是稳定的意义

4.KVMCLOCK的优点

kvm_get_wallclock替代mach_get_cmos_time获取rtc时间,mach_get_cmos_time函数在guest中执行需要多个pio vmexit才能完成,而kvm_get_wallclock只需要一个msr write即可,简便了操作,也不要在QEMU RTC的支持。

通过0x70,0x71端口操作。
参考LINUX内核:mach_get_cmos_time(),启动的时候获取日期时间。虽然内核也可以在每次需要的得到当前时间的时候读取 RTC,但这是一个 IO 调用,性能低下。实际上,在得到了当前时间后,Linux 系统会立即启动 tick 中断。此后,在每次的时钟中断处理函数内,Linux 更新当前的时间值,并保存在全局变量 xtime 内。比如时钟中断的周期为 10ms,那么每次中断产生,就将 xtime 加上 10ms。

对于calibrate_tsc和calibrate_cpu同理。因为kvmclock效率只在启动的时候有体现,整体看替代效率并不明显。

关键在于时钟源的读取不再依赖于xtime的中断

直接获取虚拟的clock时间。

而tsc的时钟源是

和TSC相比,kvmclock优势并不明显,除非TSC进行了迁移


kvmclock时钟虚拟化源代码分析来自于OenHan

链接为:http://oenhan.com/kvm-pv-kvmclock-tsc

1 对 “kvmclock时钟虚拟化源代码分析”的想法;

发表评论