概括
timer简单理解就是cpu给硬件定时器写一个超时时间,超时时间到了后,硬件定时器超时后发送中断打断cpu。在虚拟化环境中,硬件定时器不存在,是kvm模拟出来的,guest给硬件定时器写超时时间就会导致guest exit出来,kvm进行模拟,kvm模拟时可以利用软件定时器也可以利用真正的硬件定时器,假如利用了真正的硬件定时器,kvm写完硬件定时器后重新enter guest,硬件定时器超时后发送中断打断cpu,cpu收到中断后从guest中exit出来,处理中断,然后把中断注入guest,模拟虚拟定时器的中断。这样guest就至少有两次exit。
具体问题
看我的一个环境,用kvm_stat看exit统计:
主要是external interrupt和msr write
- external interrupt
exit info中有大量800000ec,根据SDM 3c中所说,ec就是vector,十进制是236。
这台物理机39号cpu做了隔离,vcpu线程759956绑定到它,大量收到236 vector的中断,这个vector是local timer,这个中断就会导致cpu从non-root exit到root,影响性能。
据统计93%的external interrupt是local timer导致的。
- msr write
msr write有62.5%是由于写TSCDEADLINE导致的,虚拟机里在配置local timer。
解决办法
- 腾讯exit-less timer
guest write msr,kvm把timer配置到其它pcpu的local timer上,timer fire interrupt就不会导致本cpu exit,其它pcup用post interrupt注入本cpu,问题就是本vcpu write msr时还需要exit。 https://patchwork.kernel.org/project/kvm/cover/1562376411-3533-1-git-send-email-wanpengli@tencent.com/
4.18内核没有,需要配置nohz_full隔离vcpu运行的pcpu,upstream已经合入,详见pi_inject_timer。
- 阿里exit-less timer
详见 kvm forum 《KVM performance tunning》by Yang Zhang guest和kvm share page,kvm用其它pcpu poll这些page,guest配置timer时不write msr而是写这个share page,这样就不存在write msr exit,由于其它pcpu一直要poll有点浪费cpu。 kvm patch: https://lore.kernel.org/patchwork/cover/860831/
qemu patch: https://www.spinics.net/lists/kvm/msg160295.html upstream没有合入。
- 字节跳动exit-less timer
timer passthrough方案,相比阿里方案省了cpu poll,相比腾讯方案少了WRMSR exit,但切换来切换去,太复杂。
详见kvm forum 《Minimizing VMExits in Private Cloud by Aggressive PV IPI and Passthrough Timer》 by Huaqiao & Yibo zhou
总结
具体效果怎样得等代码合过来测试后看数据,感谢这些大厂的无私奉献,都是技术大牛,我只是拿来主义,希望有一天自己也能发几个patch出来,但愿这一天早点到来。