云计算之路-阿里云上:“黑色1秒”问题与2009年Xen一个补丁的故事
在之前对“黑色1秒”问题的分析博文中,我们将最大嫌疑对象锁定在了Xen,在这篇博文我们将从Xen的角度进行分析。也许有人会问,为什么不知道天多高地多厚地去研究不属于自己范围的问题?只因我们对一个问题的强烈好奇心——究竟是不是我们用Windows的错?
(注1:文中所说的Xen补丁问题只是提供一种分析问题的思路,我们遇到的“黑色1秒”问题与有没有打这个补丁没有关系)
(注2:关于这个Xen补丁背后的故事,推荐阅读阿里云分享的博文:云计算之路:2009年Xen一个补丁背后那不为人知的故事)
2009年3月20日,来自Intel的Yu Ke通过Xen-dev Mailing List给来自Citrix的Keir Fraser(负责的Xen开发者之一)发了一封邮件,提交了Xen的一个patch——cpuidle: suspend/resume scheduler tick timer during cpu idle entry/exit.
这个补丁的用途是什么呢?
cpuidle can collaborate with scheduler to reduce unnecessary timer interrupt. For example, credit scheduler accounting timer doesn't need to be active at
idle time, so it can be stopped at cpuidle entry and resumed at cpuidle exit. This patch implements this function by adding two ops in scheduler:
tick_suspend/tick_resume, and implement them for credit scheduler.
上面的文字是邮件中的第一段内容,大意是:Xen中的cpuidle(在物理CPU没有被给分配VCPU时,cpuidle可以让物理CPU进入C-state,好处之一是省电,详见这里)可以与CPU调度器(负责CPU的调度,关于Xen中的CPU调度,详见这里)一起协作从而减少不必要的时钟中断。比如,当CPU空闲时,credit scheduler(Xen中的一种CPU调度算法,详见这里)的accounting timer就没有继续工作的必要,所以可以让它在cpuidle时停止工作,在退出cpuidle时再唤醒它。这个patch通过添加tick_suspend/tick_resum这两个调度器操作来实现这个。
简而言之,这个补丁的用途是——在CPU空闲时,让调度器也休息;当CPU工作时,再把调度器唤醒。
应该这个补丁会带来什么好处呢?
With this patch, under idle scenario, timer interrupt frequency decreased from ~100HZ to ~10HZ, and average C state residency increase from ~10ms to larger than 100ms. Also in a two-socket machine, about 4% idle power saving is observed.
上面的文字是文字是邮件中的第二段内容,大意是:用了这个补丁,在CPU空闲场景下,时钟中断频率由~100HZ减少到~10HZ,平均的C状态(CPU的电源管理状态,详见这里)停留时间从10ms增加到100ms(看到这让我们想到“黑色0.1秒”)。在有2颗CPU的机器上,从观察情况看,可以节省4%的电量。
简单言之,这个补丁的好处是——省电。
这个补丁的临床试验情况怎么样?
However, one issue is observed with this patch, i.e. there is soft-lockup in dom0 occasionally. This issue is still under debugging. Currently we already find a >1s VCPUOP_set_singleshot_timer timeout, which imply this may be a dom0 issue. we are working hard to figure the root cause.
上面的文字是文字是邮件中的第三段内容,大意是:应用这个补丁后,观察到一个症状。在dom0(Xen中的特权虚拟机,“内部包含了真实的设备驱动,可直接访问物理硬件”)中偶尔会出现软死锁(soft-lockup),而且发现大于1秒的VCPUOP_set_singleshot_timer(详见Xen的domain.c代码)超时的情况,这暗示了dom0中可能藏着某个坑。
注意!这里的1秒!这个“1秒”与“黑色1秒”中的“1秒”,是偶然的巧合,还是本是同根生?这个地方是一个非常重要的线索,让我们看到了走出“黑色1秒”最有希望的一线光明。
继续看这封邮件中接下来的内容:
Considering the very visible effect of this patch, and the issue mentioned above only occurs when cpuidle is enabled, and has no impact to normal user, we
finally decide to send out this patch to see if it is possible for 3.4 inclusion. In the bug fix phase, we will send out bug fix for the issue.
大意是:考虑到这个补丁诱人的省电效果(省电就是省钱啊),而且上面提到的问题(疑似黑色1秒)只在启用cpuidle的情况下发生,不会影响到正常普通用户(这地方有点疑惑,什么才是普通用户?),最终决定发出这个补丁(似乎缺少了一点不放过任何一个问题的偏执)。
接下来我们看看负责向Xen提交代码的Keir Fraser的回复:
I don't really want to take the patch while it is soft locking up. I would expect linux-2.6.18-xen.hg:22 to avoid lockup warnings due to too long
singleshot timeouts (I assume you are testing with the 2.6.18 tree?).Personally I would rather have cpuidle be enabled by default (or even always with no disable option) and get existing Cx benefits for everyone, rather
than have a slightly broken cpuidle option.Is there a reason not to turn on cpuidle by default now? Or even enable and
then remove the boot option?
还好Keir Fraser不愿放过这个小问题,他希望解决软死锁问题之后再发布这个补丁,而且他希望默认开启cpuidle。这里可以看出Keir Fraser坚持的原因,如果默认开启cpuidle,这个问题的影响就会很大。
再看一下Yu Ke紧接着的回复:
Right, I am testing it with 2.6.18 tree. I am also looking into the dom0 code, to see if should change dom0.
There is no obvious obstacle to turn on cpuidle by default. According to our testing and measurement, cpuidle is pretty stable now, maybe it is time to enable it by default.
Keir Fraser的坚持打动了Yu Ke,决定寻找并填掉这个坑,并且他也希望默认开启cpuidle。
那Yu Ke究竟有没有找到这个坑,有没有填平这个坑?
去哪里寻找答案?我们想到了Xen的git日志:
2009年3月31日,Keir Fraser向Xen代码库提交了Yu Ke完成的补丁代码。在这个提交中,只字未提坑的事。
这个坑究竟有没有被填平呢?照之前Keir Fraser的性格,应该不会有让有坑的代码提交上去。所以,我们更关注的是这个坑究竟是怎么被填平的?
于是,我们又回到Xen-devel mailing list中寻找。。。
2009年3月26日Yu Ke向Keir Fraser发了一封邮件并提交了填好坑的代码:
Hi Keir,
This attached is the version 2 of the patch. The major update is fixing the soft-lockup issue.
The root cause is: sched_tick_suspend will call __stop_timer and may raise TIMER_SOFTIRQ if the timer deadline is changed. In this case, the assumption of
no softirq pending in acpi_processor_idle is broken, and later the hpet broadcast wakeup IPI will not be delivered to this CPU, since its softirq pending bit is set. Then the CPU will be sleeping until random external interrupt happen. To fix this issue, the sched_tick_suspend is moved before the softirq pending bit checking, to keep the assumption correct.I also measure the performance by SPECJbb in dom0, no performance degradation observed.
Best Regards
Ke
原来Yu Ke遇到的“黑色1秒”问题的原因是这样的:
前面我们说过这个补丁的用途是在CPU空闲时,让调度器也休息;当CPU工作时,再把调度器唤醒。让调度器休息调用的是sched_tick_suspend(),而sched_tick_suspend则会调用_stop_timer(),如果这时时钟(Timer)的时间戳被改变,会触发TIMER_SOFTIRQ(时钟软中断,欲了解软中断的知识,详见这里),而坑就是这个软中断造成的。
开始的补丁代码是这样的:
if ( softirq_pending(smp_processor_id()) )
do_softirq(); sched_tick_suspend();
//...
开始的softirq_pending代码就是为了处理软中断,之后的代码就认为不会再出现软中断,可是在执行sched_tick_suspend()时在某种条件下(比如时钟时间戳被改变)会触发软中断,造成softirq pending bit被设置了值;当CPU由空闲状态进入工作状态时(比如某个线程被调度到该CPU执行),系统会发出hpet(High Precision Event Timer)广播唤醒IPI(Inter-processor interrupt)从而唤醒CPU,但由于当时处于softirq pending状态,hpet到达不了这个CPU,于是CPU没有被唤醒,继续悠闲着。而那个需要被执行的线程只能傻傻地等着,直到CPU被外部的中断唤醒。
打个比方来说明一下CPU的这种状态。你中午吃过饭闲着没事想睡会觉,于是在iPad定了一下闹钟就开始睡觉;但是一个同事在你睡觉的时候把iPad设置为了静音,结果闹钟准时工作了,你却听不到,继续做着美梦直到有人叫你或打你手机,你才开始干活。
由此,我们联想到,我们遭遇“黑色1秒”问题时,CPU很可能处于同一种状况。HTTP.SYS的一个线程被调度到一颗空闲的CPU核,系统给美梦中的CPU发了一个通知——“快起床,开始快活啦!”,结果某种原因造成CPU没收到,继续美梦。而HTTP.SYS的线程只能傻等着,直到1秒后,有人直接去敲CPU的门把CPU叫醒,于是CPU开始忙活起来。
这时你也许会问,如果真是这样的话,那只会造成当时线程卡住。为什么“黑色1秒”期间,所有的HTTP.SYS线程都会卡住?那是因为HTTP.SYS不是一般人,它运行于Windows的内核模式,我们猜测HTTP.SYS很有可能用到spinlock,所以只要一个线程卡住,所有线程都无法干活(猜测依据的是我们在曾经遭遇的“黑色10秒”期间写的一篇博文,其中有一句话:“SpinLock是在Windows内核级别使用了”)。而如果是用户模式的线程(比如ASP.NET线程),就不会这样。从昨天进一步的监测数据看,在“黑色1秒”期间有时有些ASP.NET线程会卡住,但不会全部卡住。
在之前的分析中,我们有这样的猜想:
黑色10秒,黑色30秒,黑色1秒,黑色5秒。。。就叫黑色n秒吧。不管黑色多少秒,这些都只是问题的表象,而真正的黑色在虚拟机层面,更准确地说就是Xen。
而这一次,我们要作出更更准确的猜想——黑色n秒的问题很可能出在Xen的CPU调度环节。
2009年Xen那个的补丁引发的“黑色1秒”问题的解决方法出人意料地简单——只要把softirq_pending与sched_tick_suspend()的代码调换一下位置,让sched_tick_suspend()先执行。
而对于我们遇到的“黑色1秒”问题,只要阿里云从内心承认是Xen的问题,我们就觉得出人意料了!
不管怎么样,这次是黑色n秒问题最重要的一次突破,同时也让我们遇到了千载难逢的学习Xen的好机会!
云计算之路-阿里云上:“黑色1秒”问题与2009年Xen一个补丁的故事的更多相关文章
- 云计算之路-阿里云上:从ASP.NET线程角度对“黑色30秒”问题的全新分析
在这篇博文中,我们抛开对阿里云的怀疑,完全从ASP.NET的角度进行分析,看能不能找到针对问题现象的更合理的解释. “黑色30秒”问题现象的主要特征是:排队的请求(Requests Queued)突增 ...
- 云计算之路-阿里云上:Web服务器遭遇奇怪的“黑色30秒”问题
今天下午访问高峰的时候,主站的Web服务器出现奇怪的问题,开始是2台8核8G的云服务器(ECS),后来又加了1台8核8G的云服务器,问题依旧. 而且3台服务器特地使用了不同的配置:1台是禁用了虚拟内存 ...
- 云计算之路-阿里云上:原来“黑色0.1秒”发生在socket读取数据时
在昨天的博文(云计算之路-阿里云上:读取缓存时的“黑色0.1秒”)中我们犯了一个很低级的错误——把13ms算成了130ms(感谢陈硕发现这个错误!),从而对问题的原因作出了错误的推断,望大家谅解! 从 ...
- 云计算之路-阿里云上:SLB会话保持的一个坑
冒着被大家厌烦的风险,今天再发一篇“云计算之路-阿里云上”.这是在前一篇发过之后真实发生的事情,我们觉得定位问题的过程值得分享.而且估计园子里不少朋友被这个问题骚扰过,我们有责任让大家知道问题的真正原 ...
- 云计算之路-阿里云上-容器难容:容器服务故障以及自建 docker swarm 集群故障
3月21日,由于使用阿里云服务器自建 docker swarm 集群的不稳定,我们将自建 docker swarm 集群上的所有应用切换阿里云容器服务 swarm 版(非swarm mode). 3月 ...
- 云计算之路-阿里云上-新发现:又一种与虚拟内存有关的CPU波动情况
在云上真是无奇不有,昨天偶然间发现在IIS的应用程序池回收设置中,仅仅设置了一下基于虚拟内存限制的回收,就引发了CPU有规律的波动.在这篇博文中,我们将向大家汇报一下云计算之路上的这个小发现. 在之前 ...
- 云计算之路-阿里云上:启用Windows虚拟内存引发的CPU 100%故障
今天上午11:35~11:40左右,由于负载均衡中的两台云服务器CPU占用突然飚至100%,造成网站5分钟左右不能正常访问,请大家带来了麻烦,请谅解! (上图中红色曲线表示CPU占用) 经过分析,我们 ...
- 云计算之路-阿里云上:禁用Windows虚拟内存引发的重启
昨天(2013年8月6日)下午,承载www.cnblogs.com主站的两台云服务器分别自动重启了1次,由于这两台云服务器使用了负载均衡(SLB),重启并未影响网站的正常访问. 与这次重启相关的Win ...
- 云计算之路-阿里云上:OCS问题的进展以及11:30-11:50遇到的问题
(上图是今天出问题期间Web服务器性能监控图,紫色表示的是Request Execution Time) 昨天我们发布了一篇博客分享了我们这两天遇到的OCS(开放缓存服务)问题,详见云计算之路-阿里云 ...
随机推荐
- Codeforces Round #521 (Div. 3) D. Cutting Out 【二分+排序】
任意门:http://codeforces.com/contest/1077/problem/D D. Cutting Out time limit per test 3 seconds memory ...
- 最短路算法 —— Dijkstra算法
用途: 解决单源最短路径问题(已固定一个起点,求它到其他所有点的最短路问题) 算法核心(广搜): (1)确定的与起点相邻的点的最短距离,再根据已确定最短距离的点更新其他与之相邻的点的最短距离. (2) ...
- MR中简单实现自定义的输入输出格式
import java.io.DataOutput; import java.io.IOException; import java.util.HashMap; import java.util.Ma ...
- 第12章 GPIO输出—使用固件库点亮LED
本章参考资料:<STM32F76xxx参考手册>.库帮助文档<STM32F779xx_User_Manual.chm>. 利用库建立好的工程模板,就可以方便地使用STM32 H ...
- LINQ to XML简介
我们的配置文件使用XML存储信息.ADO.NET的DataSet(利用扩展方法)可以方便的将数据保存(或加载)为XML..NET特有的XML API,如XmlReader/XmlWriter类.微端提 ...
- o'Reill的SVG精髓(第二版)学习笔记——第一章
1.1图形系统 计算机中描述图形信息的两大系统是栅格系统(raster graphics)和矢量图形(vector graphics) 1.1.4矢量图形的用途 ①计算机辅助绘图(CAD)程序. ②设 ...
- js 防抖 节流 JavaScript
实际工作中,通过监听某些事件,如scroll事件检测滚动位置,根据滚动位置显示返回顶部按钮:如resize事件,对某些自适应页面调整DOM的渲染:如keyup事件,监听文字输入并调用接口进行模糊匹配等 ...
- Oracle块修改跟踪功能
块修改跟踪功能是指使用二进制文件记录数据库中数据库更改的过程. 其目的是提高增量备份操作的性能,因为RMAN可以使用快修改跟踪文件找到上次执行备份操作后被修改的数据块.这可以节省大量时间,因为如果不这 ...
- Python函数中参数类型
在学习Python函数的时候,函数本身的定义和调用并不是很复杂,但是函数的参数类型和用法的确有些复杂.在此做一个小结,加深理解. Python参数的定义 负责给函数提供一些必要的数据或信息,以保证函数 ...
- Linux环境中配置环境变量无效
1.在Linux系统中的[ ~/.baserc ]文件与[ /etc/profile ]配置环境变量后(可以使任意环境变量)无效的现象,如下为解决办法: 使用命令: vim ~/.zshrc 在 [# ...