前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于虚拟机中IPI中断的思考

关于虚拟机中IPI中断的思考

原创
作者头像
金庆辉
发布2019-03-08 15:13:51
12.2K3
发布2019-03-08 15:13:51
举报

前言

感谢intel的vt-x技术,让虚拟机大部分指令可以直接运行在CPU中,只有少部分敏感指令需要有VMM来模拟执行。其中,每个CPU的LAPIC接收到的中断是虚拟化的开销一个大头。

LAPIC接收到的中断分为外部中断,内部中断,IPI中断:

  1. 外部中断源主要是IO设备,重度使用的IO设备比如有网卡,磁盘控制器等。目前,dpdk,spdk技术在虚拟化中的应用,已经把网络,存储中断减少到了0。
  2. 内部中断源包括时钟,性能监控,错误检测,温度传感器。这几个中断,绝大多数日常使用虚拟机情况下发生频率极低。对虚拟化的开销影响很小。
  3. IPI中断是多核CPU系统中CPU彼此通信的唯一方法。主要使用在分布在不同CPU上的进程/线程彼此唤醒的情况中。比较常见的是网络场景,比如有请求到达时唤醒后端网络服务程序,比如:redis,nginx。以及整合了网络服务的别的系统。比如:mysql。

可见,目前公有云中,中断虚拟化中性能瓶颈点落在了IPI中断中。

测试

虚拟机中IPI中断开销到底多大?我们可以写一个内核模块来定量分析,可以利用内核中的smp_call_function_single()和smp_call_function_many()函数,来测量IPI性能。

在我的测试环境中,物理机采用的是Intel(R) Xeon(R) Gold 6148 CPU @ 2.40GHz 2路共80超线程的CPU。虚拟机运行在KVM上的72核CentOS系统。

虚拟机默认配置

IPI类型

100000次IPI耗时(ns)

发给所有CPU

15601355147

发给同NUMA的一个CPU

230063725

发给跨NUMA的一个CPU

665893155

为了知道IPI测试时kvm在背后到底进行了什么动作。我们使用perf kvm工具来统计。

perf kvm stat record -a sleep 100

人工掐好时间,在IPI测试时在物理机上运行该命令,测试完成时中断perf工具。

perf kvm stat report

采用该命令来分析数据。

虚拟机中IPI的开销基本花在了MSR_WRITE 和 HLT虚拟化上。

我们知道HLT是由于CPU进入idle状态时,就会调用该指令把CPU挂起。这样虚拟CPU挂起后就能出让物理CPU给其它进程使用。如果我们不允许虚拟机中CPU挂起会如何呢?可以修改虚拟机启动选项,增加idle=poll选项。

虚拟机启动时开启idle=poll

IPI类型

100000次IPI耗时(ns)

发给所有CPU

8457203324

发给同NUMA的一个CPU

177809074

发给跨NUMA的一个CPU

243261198

在虚拟机角度观察,IPI中断耗时明显减少,特别是跨NUMA的情况。

在物理机角度观察,从VM-EXIT到VM-ENTRY之间经历的时间,从5956389325us减少到了30678080us。数量级的减少。

分析

为何HLT的虚拟化,消耗了那么多时间?谷歌工程师David Matlack的一篇文章给了我们答案。这里引用他的文章截图:

引用自David Matlack 文章截图
引用自David Matlack 文章截图

这篇文章的测试环境,使用的是x2apic中断控制器,虚拟机发起IPI中断通过写入MSR寄存器开始,到目标VCPU调用IPI中断服务程序结束。

从图可见,时间集中消耗在了kvm_vcpu_kick()和schedule()上。当VCPU执行HLT指令挂起自己,陷入VMM处理,VMM知道该VCPU目前不需要使用了,便将该VCPU所在线程挂起进入睡眠状态。当另一个VCPU需要唤醒该挂起的VCPU时,就在虚拟机内发起IPI中断,陷入到VMM中,随后便是执行kvm_vcpu_kick()和schedule()函数,最后注入IPI中断到目标VCPU。

虚拟机使用idle=poll启动选项,能够完全避免VCPU执行HTL指令,因此,该VCPU在物理机上对应的线程将一直占用cpu(除非被中断或者抢占),那么该线程几乎不会睡眠,那么kvm_vcpu_kick()和schedule()调用开销将大幅下降(假设系统中没有别的高优先级进程和频繁外部中断)(如下图)。这也就是为何虚拟机中IPI测试耗时减少的原因。

引用自David Matlack 文章截图
引用自David Matlack 文章截图

进一步

看起来设置虚拟机idle=poll启动选项完全避免了HTL指令执行,可以大幅提升虚拟机中IPI中断性能,这将直接提升网络服务性能。问题真正解决了吗?答案是否定的。

  1. 从虚拟机角度来看,IPI中断性能是提高了,网络,数据库服务性能都能提高。但是从物理机角度来看,由于本该挂起进入睡眠的VCPU,现在不再睡眠,而是持续占有CPU。这对云主机可不是件好事情,因为这部分"空闲"CPU配额本该交给别的虚拟机来执行,现在却被禁止了HTL的虚拟机在空转,实在是在经济上不划算。
  2. 虚拟机中禁止HTL也不是所有情况下都有明显效果。假如虚拟机中的业务场景CPU负载很高,到了100%,该场景中自然不会调用HTL(VCPU没有空闲,自然不会进入idle状态)。因此,修改idle=poll启动选项就失去了作用。

为了在物理机经济效益和虚拟机性能最大化之间取得折中,目前内核的方案是提供了halt_poll_ns机制,即在VCPU HTL之前,先轮询下有没有虚拟中断要来,来的话就马上注入虚拟机,如果超过轮询上限都没有虚拟中断过来,才真正进入睡眠。

测试halt_poll_ns方案,echo 2000000 > /sys/module/kvm/parameters/halt_poll_ns

IPI类型

100000次IPI耗时(ns)

发给所有CPU

12530570738

发给同NUMA的一个CPU

185949471

发给跨NUMA的一个CPU

283615009

测试结果介于虚拟机缺省配置和设置idle=poll性能之间。

汇总下perf kvm统计的物理机处理虚拟化经过的挂钟时间。

缺省配置

idle=poll

halt_poll_ns=2000000

5956389325us

30678080us

4858977523

值得注意的是,缺省配制和halt_poll_ns=2000000条件下,perf kvm统计的物理机处理虚拟化的挂钟时间包括了VCPU睡眠状态的时间。所以这两组值不能完全的反映虚拟化开销(需要剔除VCPU睡眠时间)。

总结

HTL指令导致的IPI中断虚拟化开销是目前中断虚拟化性能瓶颈,目前的优化方案都是在经济效益-虚拟机性能之间的平衡方案。本文分析了HTL+IPI场景的性能开销原因。在没有更好的解决方案出现前,只能根据现有业务方案选择合适的方法。

笔者设想到的业务场景中,如果是私有云中,使用KVM主要目的是为了隔离系统,对物理机成本不敏感情况下,不妨设置虚拟机的idle=poll选项。如果是公有云中,不妨设置halt_poll_ns值,但是如何设置该值以达到性能-经济效益的平衡,需要进一步研究。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 测试
  • 分析
  • 进一步
  • 总结
相关产品与服务
云服务器
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档