watchdog机制

转自:http://blog.sina.com.cn/s/blog_4dff871201012yzh.html

什么是Watchdog?

Watchdog,又称watchdog timer,是计算机可靠性(dependability)领域中一个极为简单同时非常有效的检测(detection)工具。其基本思想是针对被监视的目标设置一个计数器和一个阈值,watchdog会自己增加计数值,并等待被监视的目标周期性地重置计数值。一旦目标发生错误,没来得及重置计数值,watchdog会检测到计数值溢出,并采取恢复措施(通常情况下是重启)。总结一下就是计数——溢出——触发。

Watchdog的工作方式是事件触发的,它可以对任何合理的事件计数(如CPU指令)。其中时间事件(timeout)最常使用,这也是为什么watchdog又叫做watchdog timer。但无论watchdog统计什么事件,它的思想都是一样的。

归根结底,Watchdog是一种检测手段,它监视的目标可以是一个进程也可以是整个操作系统。Watchdog的合理性基于这样的假设:一个正常运行的系统,它的执行流应该是可预测的,因此可以在它正常执行路径上设置一些周期性重置watchdog的点;但如果系统发生故障,它可能执行不到下一个重置watchdog的点,此时故障将被watchdog捕捉到。看到这儿,您应该想到watchdog对于检测死循环或死锁这类故障非常有效。

Watchdog的实现

针对不同的监视目标,watchdog可以采取不同的实现方法。

  • 监视一个进程

如果监视目标只是一个进程,那么利用操作系统提供的定时功能即可实现一个watchdog。

  • 监视一个操作系统

如果要监视操作系统,就得使用操作系统之外的工具,通常是一个附加的计数器。现代Intel CPU都包含的performance counter也可以提供这样的功能,从而不需要额外的设备就能实现监视操作系统的watchdog。

关于操作系统watchdog的设计策略以及实现方法,可参考论文"Exploring Recovery from Operating System Lockups"。

Watchdog in Linux

Linux很早就引进了watchdog,事实上,Linux中有两套watchdog体系:

1) The Linux Watchdog driver API

2) NMI watchdog

第一种watchdog网上已经有很多很好的讲解资料,比如这篇《使用 watchdog 构建高可用性的 Linux 系统及应用》以及Linux的文档man手册。 本文要详解的是第二种,即NMI Watchdog。

NMI watchdog in Linux

NMI watchdog是Linux的开发者为了debugging而添加的特性,但也能用来检测和恢复Linux kernel hang,现代多核x86体系都能支持NMI watchdog。NMI(Non Maskable Interrupt)即不可屏蔽中断,之所以要使用NMI,是因为NMI watchdog的监视目标是整个内核,而内核可能发生在关中断同时陷入死循环的错误,此时只有NMI能拯救它。

NMI watchdog的思想如前所述,仍然是通过计数和阈值进行监控。要打开NMI watchdog,只需要在grub.cfg中添加一句"nmi_watchdog=N",重启之后NMI watchdog就已经开启了。

Linux中有两种NMI watchdog,分别是I/O APIC watchdog(nmi_watchdog=1)和Local APIC watchdog(nmi_watchdog=2)。它们的触发机制不同,但触发NMI之后的操作是几乎一样的。从名字上看,它们都利用了APIC,所以前面强调这是被现代多核x86体系支持的功能。下面介绍这两种NMI watchdog的监测机制。

P.S. 我的Linux内核版本是2.6.32.21。

I/O APIC watchdog

如果已经熟悉了Intel APIC架构,那么再来了解Linux NMI watchdog就是易如反掌,相关资料可以先看看这篇《Linux内核中断内幕》热热身,然后看完最新的Intel® 64 and IA-32 Architectures Software Developer‘s Manual, Volume 3: System Programming Guide的第10章《Chapter 10 Advanced Programmable Interrupt Controller (APIC)》就够了,没有什么资料比Intel手册更详尽了。

I/O APIC watchdog的工作方式比较奇葩,一旦开启了I/O APIC watchdog(nmi_watchdog=1),那么每个CPU对应的Local APIC的LINT0线都关联到NMI,这样每个CPU将周期性地接到NMI(这个周期与Local timer的周期相同),接到中断的CPU立即处理NMI。处理的过程就是检查CPU的irq_stat(统计CPU中断信息的结构体,多核系统中这将是个数组)中的apic_timer_irqs和irq0_irqs这两个字段的和,它们分别代表了当前CPU从启动到现在处理的本地时钟中断次数和全局时钟中断次数。如果这两个值的和在一定时间(在我的机子上是5秒)之内都没有增加,说明这个CPU已经连续5秒没有处理过一次时钟中断,显然,出大事了。

arch/x86/kernel/traps.c: do_nmi, default_do_nmi

arch/x86/kernel/dumpstack.c: die_nmi

arch/x86/kernel/apic/nmi.c: nmi_watchdog_tick

Local APIC watchdog

想了解Local APIC watchdog也需要先看Intel手册……仍然是最新的Intel® 64 and IA-32 Architectures Software Developer‘s Manual, Volume 3: System Programming Guide,第18章《Chapter 18 Performance Monitoring》。这一章列出了Intel所有体系的PM,内容超多,但只要看

  • 18.2.3 Pre-defined Architectural Performance Events
  • 18.17 Performance Monitoring (P6 Family Processor)
  • 18.18 Performance Monitoring (Pentium Processors)

这三部分就足矣。如果觉得Intel手册内容太多或者看英文比较吃力,可以参考张银奎老师的《软件调试》第5.5节,《性能监视》。

Intel CPU带有performance counter,可以对的许多事件计数(P4系列多达43到45个,具体数目视型号而定),在watchdog中,统计的事件是"UnHalted Core Cycle",即CPU处于非halt状态下经过的周期数。当计数溢出时,Local APIC会向CPU发出一个PMI(performance counter interrupt)。PMI的属性可选,理所应当的,在Local APIC watchdog中它被设置成NMI。利用这个特性,就能周期性地产生NMI。

发出NMI之后,Local APIC watchdog的行为就与I/O APIC watchdog几乎一样了,仍然是检查CPU处理时钟中断的次数。唯一的区别是,在处理NMI的过程中还多执行一项操作:重置performance counter。由于Local APIC watchdog统计的是UnHalted Cycles,所以系统空闲的时候,NMI触发的频率比较低。

arch/x86/perfctr_watchdog.c: lapic_wd_event

die_nmi

NMI watchdog在发现故障之后调用了die_nmi,我们来看看这个函数到底做了什么:

一个一个来解析:

  • notify_die通知对NMI感兴趣、即订阅了die_chain的模块
  • show_registers调用printk输出出当前寄存器信息,别忘了NMI watchdog本来是为了debugging哦
  • 根据do_panic和panic_on_timeout的值决定是否要panic,do_panic是die_nmi的参数,panic_on_timeout是启动项参数,当然启动之后也可以通过/proc动态修改它的值
  • do_exit就是恢复操作,Linux陷入hang,current进程有很大的嫌疑,所以退出当前进程有一定几率恢复系统运行。

对比两种NMI watchdog,其实各有长短。

I/O APIC watchdog的缺点很明显……每个时钟周期都要触发NMI,这对性能是个不小的影响,引用Linux Document的原话"...its NMI frequency is much higher, resulting in a more significant hit to the overall system performance",而且可靠性不太好。我开启watchdog之后,写了个关中断+死循环的kernel module并且加载到系统中,结果Linux跪了——这意味着I/O APIC watchdog没起作用。

Local APIC watchdog的触发频率要低一些,性能开销也要小一些。但是注意它统计的事件,"UnHalted Core Cycle",也就是说,万一CPU进入了关中断+halt的状态,那它也没救了,因为这时候计数器根本就不走了。但是I/O APIC watchdog却没有这个缺陷。但是就可靠性而言,Local APIC watchdog的表现更好,我开启它之后通过module注入了各种spinlock死锁,它居然都恢复了……

Postscript

以上关于两种NMI watchdog的说明,我已经省去了很多很多细节(=_=),尤其是初始化。I/O APIC watchdog的初始化细节在arch/x86/kernel/apic/apic.c;Local APIC watchdog的全部实现都在arch/x86/perfctr_watchdog.c。Local APIC watchdog的初始化看得我都要吐血了-.-

为了彻底了解Linux NMI watchdog的工作原理,我尝试了各种途径:

  • Google
  • BBS
  • Stack Overflow
  • Intel Manual
  • Linux Document
  • E-mail
  • Source code

几乎是一切有效的信息源全部用上了,但这其中真正有用的只有Source code和E-mail。源代码就不说了,我原本只有两天时间来弄清楚NMI watchdog,大树又多给我加了3天时间之后,立即决定啃源码。所幸NMI watchdog涉及到的代码总共也只有数千行,并且代码逻辑并不复杂。

另一方面,我查询了watchdog相关的邮件列表,并给相关的开发者发了邮件,只有一位Redhat的工程师Don Zickus回复了我,他的回信给了我非常大的帮助。不过他提到"ah, 2.6.32, uses the old nmi_watchdog"……old nmi_watchdog!我在另一台内核版本为3.0.3的机器上打开了NMI watchdog,发现它们都没有起作用-_-

即便我看遍了代码,还是有两个问题始终没有找到答案:

一、APIC_LVT0是怎么跟APIC_LVTT接上的,如何向所有CPU发NMI??

二、ESCR_MSR和CCCR_MSR的初始化参数到底是什么意思!!?

本次斗狗经历让我收获了许多:

一、对Intel中断体系有了更深入的了解

二、第一次在没有直接指导的情况下啃kernel code

三、一次不同寻常的学习经历,反复列出疑点解决问题

四、Source Insight真乃神器也!

五、原来在Stack Overflow上问问题也有没有人回的时候!

以下转自:http://www.cnblogs.com/sdphome/archive/2011/11/16/2251042.html

NMI Watchdog Timer

1. 没有完美的代码

没有完美的人,更没有完美的代码。虽然教科书上说deadlock(死锁)多么不好不好,但是在现实生活中,很难把它完全消灭。假 设不小心内核出现了deadlock,可能你得干瞪眼。CPU就在那里空等着,空转着,叫天天不应,叫地地不灵。等到海枯石烂,CPU生锈的那一天,它还 会那么痴痴地等着那个霸占了锁的家伙会良心发现,解下这个锁。也许你会说,哎呀,这么麻烦干嘛?RESET一下,不就一了百了吗?但是如果是一台肩负重担 的Server(服务器),在夜深人静你正呼呼大睡的时候发生了deadlock呢?如果deadlock的原因没有查到,三天五天就会发生一次,光这样 被动的重启也不是办法……

不用说让人心惊胆颤的deadlock,很多时候,一段小小的循环,就会把你彻底雷到。我们总认为循环是可以结束的,但是别要忘 记,事物都是辩证的,有的时候,碰巧发生了某些预料之外的条件,让这个循环成了彻彻底底的死循环。恰巧此时,CPU的中断如果已经被禁掉,那神仙也救不了 你。“我佛慈悲,能不能把循环给我停掉?”“阿弥陀佛,神仙也得遵守潜规则,你让我给你停掉循环,好歹也要给我一个中断,让我能够施法吧?”……不能怪父 母,更不能怪政府,如果你正好在电脑旁边,可以RESET;如果你不在旁边,就等着老板的电话吧。“小福啊,今天又超过100位客户打电话投诉我们的交友 网站不能访问了,你赶紧打的到公司,看看是怎么回事。赶紧啊!有个客户说,如果今晚12点之前不能登录网站,取得要约会的5位MM的详细资料,他就会携带 人体炸弹到办公楼来砸场子……“

2. 保留现场,强行重启

言归正传。如果应用程序进入死循环,我们可以把它KILL掉。如果内核因为意料之外的原因,导致系统进入无法自拔的死循环,最好的 办法就是让系统给强行重启。当然,这种重启最好是自动的,不需要人干预的,且最好能够打印出导致重启的原因,便于开发者调试错误。在Linux内核中,用 NMI看门狗(NMI Watchdog Timer)的方式来实现该机制。

在系统的正常运行过程当中,每秒都有非常多的中断产生。即便它啥都不做,啥外部中断都不接收,每秒至少有数以百计的用来给线程调度的时钟中断。(如果调度时间片为10ms,则有100个时钟中断。)假设如果内核发现5秒钟之内,没有产生一个中断,那将会是怎么一回事呢?

这个时候,CPU会辩解道:“我兢兢业业地执行每一条指令,有没有中断不干我的事,叫我干啥就干啥,我是真正的劳动模范,不要怀疑 我会捣鬼。中断既来之,我就安之。不来之,则说明中断已经被禁掉了。肯定是有个幕后黑手已经调用CLI之类的指令关闭了全局的外部中断,然后偷偷摸摸干自 己相干的事情,不被其他人给打断。人都有自己的隐私嘛,代码也不例外。屏蔽中断,执行不被打断的代码,人之常情。但是用得不恰当,如同毒品一样,就会出现 大问题。少量鸦片,可以当作药品;携带超过5克海洛因,就得上刑场。禁掉中断占用一点点CPU时间,可以让程序很容易地绕开race condition(竞争条件);但是如果中断被禁掉的时间长达5秒钟,那就违反常理了。5秒钟之内系统不会有其他响应,其影响之深远,罪行之恶劣,不用 满清十大酷刑简直不足以平息民愤……”

“该杀!该杀!”这个时候,内存,芯片组,硬盘……所有硬件都附和。看来CPU还是一直是IT届的老大。不怪我们不客气了,赶紧打 印出现场(CPU出现LOCKUP时的相关上下文,包括寄存器值,函数调用栈等),且记入LOG,作为判案的证据,同时有警示后人只用。接着,就对施以极 刑,给内核来一个oops,彻底终止它的执行,让它重新启动。

3. 少林扫地僧——NMI

不对,不对!也许你有这样的感觉,既然5秒之内没有一个中断,基本肯定中断是已经被禁掉了,那CPU就被迫只会一直执行那段有问题 的代码,根本没有机会来执行所谓的“保留现场,强行重启”的代码。这些代码放在内核的另外一个地方,要调用它,必须由中断出发。可是,可是中断不是已经被 禁了吗?借尸还魂?恐怖,恐怖……

“再厉害的黑社会,也斗不过我们人民警察!”这个时候,CPU又冷笑了,“虽然中断被禁掉了,但是,我还拥有秘密武器。那就是 Non-maskable interrupt,不可屏蔽中断,简称NMI。你要禁,只能禁掉一般的可屏蔽中断。NMI,我压根就让你摸不着,碰不着!”

原来,内核中隐藏着一个神秘的高手,那就是NMI。我们调用spin_lock_irq,虽然能够禁掉本地的中断,但是NMI却不 行。内核中设置了一个watchdog timer,它的中断类型就被置为NMI,每过一定的时间,这个timer就执行一次,用来悄悄监视系统的运行。如果系统正常,它啥事都不做,仅仅是更改 一些时间计数;如果系统不正常(默认5秒没有任何普通外部中断),那它就闲不住了,会立马跳出来,且中止之前程序的运行。该出手时就出手!

我想到了在血腥的武林当中,有无数的高手。刚开始的时候,似乎人人都是高手;但后来,昔日的高手看起来都是菜鸟,强中更有强中手。 再后来,更高的高手出来了,开始这里论剑那里比武,争霸天下了。最后来,天下也许是第一第二的高手开始决战……似乎故事就这个时候结束了,但是让人大跌眼 镜的是,一个小小的少林扫地僧,却能轻易地两位顶尖高手制服。NMI就是这样的角色,平时从不站在前台,也很少为人所知。除了用NMI watchdog timer监测系统是否锁住之外,一些特殊的严重的硬件错误,比如内存奇偶校验错等,也会触发NMI的发生。不过这些错误,估计很多人从来不会碰到过。

4. More...

如果出现死循环的地方没有把中断禁掉,那是不是不会触发NMI watchdog timer了呢?理论上是的。至少Linux2.6的抢占内核应该不会触发。但是,由于系统还是有机会调度到其他线程,所以整个系统可能响应很慢,但不至 于给死掉。我们可以通过top命令查看进程状况等手段来进行分析。

不是所有的Linux内核都支持NMI watchdog timer的。必须在内核中添加APIC的支持。(现在的内核和硬件一般都是没有问题的)如果是x86-64的硬件体系结构,APIC是被默认支持的。在很多发行版本当中,需要在启动的时候添加内核启动参数

nmi_watchdog=N

来启动NMI watchdog timer。N代表了该timer的source,如果为1,表示利用IO APIC的始终源;如果为2,表示利用LOCAL APIC的performance counter。具体哪个好用,可以分别测试一下,一般来说,比较新的CPU(一般都是双核了)选择2的话,系统负担更小一点。想要更多的了解NMI watchdog timer,请看如下的kernel文档

http://www.kernel.org/doc/Documentation/nmi_watchdog.txt

想要知道啥时APIC(注意不是ACPI),啥是IO APIC,啥是LOCAL APIC,那就请google一下吧。

时间: 2024-10-10 10:24:52

watchdog机制的相关文章

Android 4.4 Watchdog机制

Android 软watchdog机制主要功能集中在两个层面: 1),监听系统的reboot广播: 2),监听相关service是否死锁. 首先,从代码看,watchdog是由SystemServer.java启动: 这几行代码首先是初始化了watchdog, 添加UIThread,FgThread,IoThread,还有当前new Watchdog时候的主线程,其实就是System_server主线程. 添加至mHandlerCheckers这个MonitorList中,接下来看init接口:

android watchDog 机制

Android 平台实现了一个软件的WatchDog来监护SystemServer.SystemServer无疑是Android平台中最重要的进程了,里面运行了整个平台中绝大多数的服务. SystemServer退出反而问题不大,因为 init进程会重新启动它,但是它死锁就麻烦了,因为整个系统就没法动了.所以我们需要使用看门狗来监护它,当很长一段时间没有喂狗,就会重启SystemServer进程. WatchDog的作用: 1).接收系统内部reboot请求,重启系统. 2).监护SystemS

Android中的软件Watchdog

由于Android的SystemServer内有一票重要Service,所以在进程内有一个软件实现的Watchdog机制,用于监视SystemServer中各Service是否正常工作.如果超过一定时间(默认30秒),就dump现场便于分析,再超时(默认60秒)就重启SystemServer保证系统可用性.同时logcat中会打印类似下面信息: W Watchdog: *** WATCHDOG KILLING SYSTEM PROCESS: Blocked in monitor com.andr

系统进程的Watchdog [转]

3.1 Watchdog简介 对于像笔者这样没玩过硬件的纯软程序员来说,第一次看到这个家伙的时候真心一头雾水,只是觉得这个名字很有意思.一番调查后发现,Watchdog机制最 早来源于硬件,在计算机系统中,单片机的工作容易受到来自外界电磁场的干扰,而陷入死循环,系统无法继续工作,为了解决这个问题,便产生了一种专门用于监 测单片机程序运行状态的芯片,俗称"看门狗"(Watchdog). “看门狗”本身是一个定时器电路,内部会不断的进行计时(或计数)操作.计算机系统和“看门狗”有两个引脚相

系统进程的Watchdog

编写者:李文栋 /rayleeya http://rayleeya.iteye.com/blog/1963408 3.1 Watchdog简介 对于像笔者这样没玩过硬件的纯软程序员来说,第一次看到这个家伙的时候真心一头雾水,只是觉得这个名字很有意思.一番调查后发现,Watchdog机制最早来源于硬件,在计算机系统中,单片机的工作容易受到来自外界电磁场的干扰,而陷入死循环,系统无法继续工作,为了解决这个问题,便产生了一种专门用于监测单片机程序运行状态的芯片,俗称"看门狗"(Watchdo

iOS应用崩溃日志分析

转自raywenderlich 作为一名应用开发者,你是否有过如下经历? 为确保你的应用正确无误,在将其提交到应用商店之前,你必定进行了大量的测试工作.它在你的设备上也运行得很好,但是,上了应用商店后,还是有用户抱怨会闪退 ! 如果你跟我一样是个完美主义者,你肯定想将应用做到尽善尽美.于是你打开代码准备修复闪退的问题……但是,从何处着手呢? 这时iOS崩溃日志派上用场了.在大多数情况下,你能从中了解到关于闪退的详尽.有用的信息. 通过本教程,你将学习到一些常见的崩溃日志案例,以及如何从开发设备和

手游频繁崩溃”闪退”? 从程序上找原因

游戏程序 平台类型: iOS Android  程序设计: 算法逻辑/智能AI 服务器 数据库  编程语言: C/C++ Java  引擎/SDK: 其它  <ignore_js_op> 文 / 网易 Tjay(QA) 作为玩家,当游戏crash的时候是什么心情,如果这个游戏玩起来还不错的话,那我可能还会打开第二次,如果这个游戏一般的话我可能直接怒删了.当多次出现闪退crash的时候,这种糟糕的体验很容易让用户流失,造成很大的损失.但是作为测试人员,面对如此棘手的事情,首先要做的是协助开发组解

iOS 应用崩溃日志分析

通过本教程,你将学习到一些常见的崩溃日志案例,以及如何从开发设备和iTunes Connect上获取崩溃日志文件.你还将学习到符号化( symbolication),从日志追踪到代码 .你还将学习调试一个在待定情况下会闪退的应用. 让我们开始动手吧! 什么是崩溃日志,从哪里能得它? iOS设备上的应用闪退时,操作系统会生成一个崩溃报告,也叫崩溃日志,保存在设备上. 崩溃日志上有很多有用的信息,包括应用是什么情况下闪退的.通常,上面有每个正在执行线程的完整堆栈跟踪信息,所以你能从中了解到闪退发生时

iOS应用崩溃日志分析-备用

作为一名应用开发者,你是否有过如下经历? 为确保你的应用正确无误,在将其提交到应用商店之前,你必定进行了大量的测试工作.它在你的设备上也运行得很好,但是,上了应用商店后,还是有用户抱怨会闪退 ! 如果你跟我一样是个完美主义者,你肯定想将应用做到尽善尽美.于是你打开代码准备修复闪退的问题……但是,从何处着手呢? 这时iOS崩溃日志派上用场了.在大多数情况下,你能从中了解到关于闪退的详尽.有用的信息. 通过本教程,你将学习到一些常见的崩溃日志案例,以及如何从开发设备和iTunes Connect上获