machine check 是一种用来报告内部错误的一种硬件的方式。它包括 machine check exceptions 和 silent machine check。
其中,machine check exceptions(MCEs) 是在硬件不能纠正内部错误的时候发生,在这种情况下,通常会中断 CPU 当前正在运行的程序,并且调用一个特殊的异常处理程序。这种情况通常需要软件来进行处理,即 machine check exception handler。
当硬件能够纠正内部错误的时候,这种情况通常称作 silent machine check。当这种错误发生的时候,硬件会把相应的错误信息登记到特殊的寄存器中。之后,操作系统或者是固件(BIOS)就可以从这写寄存器中读取信息,登记和分析这些错误信息有助于提前预测机器硬件的故障。
MCE(Machine Check Exception)是由CPU侦测出来的错误,它错误包含两种主要类型:notice(提示)/warning(警告),和fatal exception(致命性的错误)。Warning(警告)将会在你的系统log下输出一条类似于"Machine Check Event logged"的信息,我们可以通过一些linux的应用程序对这部分log进行详细的信息查看;而fatal MCE(致命的错误)会导致机器停止响应,MCE的详细信息也将会输出到系统的console中。
随着每一代芯片中晶体管数量的增加,以及芯片大小的减小,硬件发生错误的概率也在提高,因此能够处理这种错误变得越来越重要。
另外,现在将许多计算机集成在一起进行高性能的科学计算也越来越流行。这些集群的计算机中,发生硬件错误的概率将比普通的计算机发生错误的概率要高,因此,为了保证可靠性,处理这些硬件错误也是很重要的。
产生 machine checks 的原因很多,这些来源包括 CPU, 缓存, 内部总线, 内存等等,当然也有可能是驱动中的软件错误。
常见原因有以下几种:
因为当前的内核服务都不能被使用。我们知道内核代码可以运行在进程上下文和中断上下文,在中断上下文可以做的事情比进程上下文可以做的事情要少。在中断上下文调用的函数必须合适的保护了它的数据结构,防止来自多个中断的并发访问。这些函数被称为是“中断安全的”。
但是,我们知道 machine check exception 在任何时候都可能会发生,甚至在所有中断都被禁止的临界区中也有可能会发生。因此在这种情况下,如果在 machine check exception 处理函数中调用了这些中断安全的函数,就可能会死锁在自旋锁上。
由于为了让代码更加的简单, silent machine check 处理函数和 machine check exception 处理函数共享了同一条代码路径,因此上面所讨论的问题对于 silent machine check 处理函数同样适用。
同样,能够尽快的处理 machine check 也是非常重要的,因为在发生了一个硬件错误之后,机器的状态可能变得已经不太稳定了。当处理函数在等待机器进入一个更加容易被处理的状态的时候,这个事件可能会变得不能被处理。例如,在等待的时间内,在同一个 bank 上,又发生了另一个错误,这个错误就会覆盖之前的错误,并且变得不可处理。
对于一些复杂的 RAM 错误,处理函数除了等待就没有别的办法了,因为这要求和内核锁进行同步。不像其他的异常,machine check 是异步的。这就是说,CPU 报告的错误并不在发生错误的那条指令处,这可能已经过了几百个时钟周期,这就导致了处理的不可靠性。
传统的,登记 machine check 是由固件来进行的(即BIOS),当操作系统没有 machine check 处理函数时,那些 MC 寄存器将不会被清零。在下一次热启动之后,BIOS将从最后一次 machine check 中找到信息,并登记到日志文件中。这种方式显然存在很多缺点,例如,必须在每次机器重新启动时才能够登记日志文件,不能够记录在同一个 bank 上发生的多个错误,在网络中收集信息和将日志写到磁盘是很困难的。
因此,最好的方法是将登记日志的任务交给操作系统,就可以解决这些问题。但是,当前大多数的 linux 用户使用的都是 X 界面,因此控制口是不可见的。当操作系统登记一个致命的 machine check 后,X 界面看起来就像是冻住了一样,不会响应用户。为了解决这个问题,这种致命的 machine check 都在机器重启时再登记。这也能够将日文件写道磁盘里,使后来的支持人员分析称为可能。
将 machine check 日志文件和 软件错误日志文件分开是有必要的,因为用户可能分不清出这两种错误。经验表明,最好将这两种日志文件完全分开。
Linux系统下,如果在Console或者系统log中看到MCE的错误,可以运行mcelog命令从系统内核中读取详细的信息。需要注意的是,一旦运行了mcelog,我们将无法再通过这条命令去查询已经出现的错误,所以最好运行mcelog的时候讲文本输出到文件中以做进一步的分析,参考命令如下:#/usr/sbin/mcelog> mcelog.ou
有些系统会定期执行这个操作,并将文件输出到/var/log/mcelog中,因此,如果系统log中发现了MCE信息,但是使用mcelog查询不到任何数据时,可以试着查看/var/log/mcelog文件。
mcelog 是Linux 系统上用来检查硬件错误,特别是内存和CPU错误的工具。
mcelog 能捕获两类错误:已纠正的 和未纠正的。已纠正的错误是由 CPU 处理的事件,可用来识别可能预测更大问题的趋势。
未纠正的错误是关键异常,如果 CPU 无法恢复,往往会导致系统上的内核错误。这会导致应用程序重置和中断。对于未纠正的错误,mcelog 捕获错误的能力取决于错误导致热重启还是硬重启。如果是热重启,信息会被 mcelog 捕获,恢复后可看到。硬重启会导致数据丢失,而且 mcelog 可能捕获不到该事件。
/dev/mcelog 设备文件
/var/log/mcelog messages日志文件
/etc/mcelog/mcelog.conf配置文件
/var/run/mcelog.pid
默认故障日志只记录在/var/log/mcelog,并不记录到系统日志中。
如果需要在系统日志中也体现,需修改/etc/mcelog/mcelog.conf文件,将前面#去掉,并保存。
(1)手动运行mcelog的方式:
[root@RedHat_test ~]# mcelog --daemon
(2)查看mcelog日志
[root@RedHat_test ~]# tail /var/log/mcelog
# 什么也没有输出,表明正常
(3)查看mcelog守护进程是否检测到错误信息
[root@RedHat_test ~]# mcelog --client
# 什么也没有输出,表明正常
(4)解析系统异常时的mcelog输出
[root@RedHat_test ~]# mcelog --ascii < file.log
# or或者
[root@RedHat_test ~]# mcelog --ascii --file file.log
致命的MCE错误通常都是由硬件错误所引起的,我们通过重启设备重新进入系统后,首先需要查看系统log,一个典型的MCE相关的错误log如下:
CPU 1: Machine Check Exception: 4 Bank 4: f600200137080813
TSC b0ce27165dd3 ADDR 180ee1b40
这时我们可以通过mcelog去将这条error log的详细信息dump出来,命令如下:
root@localhost:/root> /usr/sbin/mcelog --ascii < myerror
得到的详细错误信息如下:
HARDWARE ERROR. This is *NOT* a software problem!
Please contact your hardware vendor
CPU 1 4 northbridge TSC b0ce27165dd3
Northbridge Chipkill ECC error
Chipkill ECC syndrome = 3700
bit32 = err cpu0
bit45 = uncorrected ecc error
bit57 = processor context corrupt
bit61 = error uncorrected
bit62 = error overflow (multiple errors)
bus error 'local node origin, request didn't time out
generic read mem transaction
memory access, level generic'
STATUS f600200137080813 MCGSTATUS 4
这表示发生了Uncorrected ECC error,意味着其中一根内存模块出现了问题。
https://blog.csdn.net/xiaocainiaoshangxiao/article/details/38046239