可靠性、可用性和可服务性 (RAS)¶
本文档介绍了内核中存在的 RAS 功能的不同方面。
RAS 概念¶
可靠性、可用性和可服务性 (RAS) 是一个用于服务器的概念,旨在衡量其稳健性。
- 可靠性 (Reliability)
是系统产生正确输出的概率。
通常以平均无故障时间 (MTBF) 来衡量
通过有助于避免、检测和修复硬件故障的功能来增强
- 可用性 (Availability)
是系统在给定时间处于运行状态的概率
通常以一段时间内停机时间的百分比来衡量
通常使用在运行时检测和纠正硬件故障的机制;
- 可服务性 (Serviceability,或可维护性)
是系统修复或维护的简单程度和速度
通常按平均修复时间 (MTBR) 衡量
提高 RAS¶
为了减少系统停机时间,系统应该能够检测硬件错误,并在可能的情况下在运行时纠正它们。它还应提供检测硬件老化的机制,以便警告系统管理员在导致数据丢失或系统停机之前采取更换组件的操作。
在监测措施中,最常见的包括
CPU – 检测指令执行以及 L1/L2/L3 缓存中的错误;
内存 – 添加纠错逻辑 (ECC) 以检测和纠正错误;
I/O – 为传输的数据添加 CRC 校验和;
存储 – RAID、日志文件系统、校验和、自我监控、分析和报告技术 (SMART)。
通过监控错误检测的发生次数,可以识别硬件错误的概率是否正在增加,在这种情况下,可以进行预防性维护,在这些错误尚可纠正时更换老化的组件。
错误类型¶
现代系统中使用的大多数机制都使用汉明码 (Hamming Codes) 等技术,这些技术允许在位包错误数低于阈值时进行纠错。如果错误数超过阈值,这些机制可以以高度置信度指示发生了错误,但无法纠正。
此外,有时错误发生在未使用的组件上。例如,当前未分配的一块内存。
这定义了一些错误类别
可纠正错误 (CE) - 错误检测机制检测并纠正了错误。此类错误通常不是致命的,尽管某些内核机制允许系统管理员将其视为致命错误。
不可纠正错误 (UE) - 发生的错误数量超过了纠错阈值,系统无法自动纠正。
致命错误 (Fatal Error) - 当 UE 错误发生在系统的关键组件上时(例如,内核的一部分被 UE 损坏),避免数据损坏的唯一可靠方法是挂起或重启机器。
非致命错误 (Non-fatal Error) - 当 UE 错误发生在未使用的组件(如处于断电状态的 CPU 或未使用的内存库)上时,系统可能仍会运行,最终通过热备件(如果有)更换受影响的硬件。
此外,当用户空间进程发生错误时,也可以终止该进程并让用户空间重新启动它。
处理非致命错误的机制通常很复杂,可能需要一些用户空间应用程序的帮助,以便应用系统管理员所需的策略。
识别坏的硬件组件¶
仅检测硬件缺陷通常是不够的,因为系统需要精确指向应更换的最小可更换单元 (MRU),以使硬件再次可靠。
因此,它不仅需要错误日志记录设施,还需要将错误消息转换为 MRU 的丝网印刷或组件标签的机制。
通常,对于内存来说非常复杂,因为现代 CPU 会交错来自不同内存模块的内存,以提供更好的性能。DMI BIOS 通常有一个内存模块标签列表,可以使用 dmidecode 工具获取。例如,在台式机上,它显示:
Memory Device
Total Width: 64 bits
Data Width: 64 bits
Size: 16384 MB
Form Factor: SODIMM
Set: None
Locator: ChannelA-DIMM0
Bank Locator: BANK 0
Type: DDR4
Type Detail: Synchronous
Speed: 2133 MHz
Rank: 2
Configured Clock Speed: 2133 MHz
在上面的例子中,一个 DDR4 SO-DIMM 内存模块位于系统内存中,标记为“BANK 0”,如 bank locator 字段所示。请注意,在这样的系统上,total width 等于 data width。这意味着该内存模块没有错误检测/纠正机制。
遗憾的是,并非所有系统都使用相同的字段来指定内存库。在这个来自旧服务器的示例中,dmidecode 显示:
Memory Device
Array Handle: 0x1000
Error Information Handle: Not Provided
Total Width: 72 bits
Data Width: 64 bits
Size: 8192 MB
Form Factor: DIMM
Set: 1
Locator: DIMM_A1
Bank Locator: Not Specified
Type: DDR3
Type Detail: Synchronous Registered (Buffered)
Speed: 1600 MHz
Rank: 2
Configured Clock Speed: 1600 MHz
这里,DDR3 RDIMM 内存模块位于系统内存中,标记为“DIMM_A1”,如 locator 字段所示。请注意,此内存模块的 data width 为 64 位,total width 为 72 位。因此,它有 8 个额外的位供错误检测和纠正机制使用。这种内存被称为纠错码内存 (ECC memory)。
更糟糕的是,板卡上带有不同标签的系统使用完全相同的 BIOS 并不罕见,这意味着 BIOS 提供的标签将与实际标签不匹配。
ECC 内存¶
如前一节所述,ECC 内存具有用于纠错的额外位。在上面的示例中,内存模块的 data width 为 64 位,total width 为 72 位。用于错误检测和纠正机制的额外 8 位被称为 syndrome (校验子)[1][2]。
因此,当 CPU 请求内存控制器写入一个具有 data width 大小的字时,内存控制器使用汉明码或其他纠错码(如 SECDED+)实时计算 syndrome,生成一个 total width 大小的码。然后该码被写入内存模块。
读取时,total width 位的码被转换回来,使用写入时使用的相同 ECC 码,产生一个 data width 的字和一个 syndrome。即使发生错误,data width 的字也会被发送到 CPU。
内存控制器还会查看 syndrome 以检查是否存在错误,以及 ECC 码是否能够修复该错误。如果错误已纠正,则发生了可纠正错误 (CE)。如果没有,则发生了不可纠正错误 (UE)。
有关 CE/UE 错误的信息存储在内存控制器的一些特殊寄存器中,可以通过读取这些寄存器进行访问,访问方式可以是 BIOS、某些特殊的 CPU 或 Linux EDAC 驱动程序。在 x86 64 位 CPU 上,此类错误也可以通过机器检查架构 (MCA) 获取[3]。
EDAC - 错误检测和纠正¶
注意
“bluesmoke” 是该设备驱动程序子系统在“树外”并在 http://bluesmoke.sourceforge.net 维护时的名称。该站点现在大多已过时,仅供参考。
当该子系统首次推送到上游内核 2.6.16 时,它被重命名为 EDAC。
目的¶
edac 内核模块的目标是检测并报告运行在 linux 下的计算机系统中发生的硬件错误。
内存¶
内存可纠正错误 (CE) 和不可纠正错误 (UE) 是采集的主要错误。这些类型的错误由 edac_mc 设备采集。
检测 CE 事件,然后采集并报告这些事件,可以但并不一定能预测未来的 UE 事件。仅发生 CE 事件时,系统可以且将继续运行,因为数据尚未损坏。
然而,对表现出 CE 的内存模块进行预防性维护和主动部件更换,可以降低发生可怕的 UE 事件和系统崩溃 (panic) 的可能性。
其他硬件元素¶
EDAC 的一个新功能,即 edac_device 类设备,在内核 2.6.23 版本中添加。
这种新的设备类型允许非内存类型的 ECC 硬件检测器将其状态采集并通过 sysfs 界面呈现给用户空间。
某些架构具有 L1、L2 和 L3 缓存的 ECC 检测器,以及 DMA 引擎、结构交换机、主数据路径交换机、互连和各种其他硬件数据路径。如果硬件报告它,那么可能可以构建一个 edac_device 设备来采集并呈现给用户空间。
PCI 总线扫描¶
此外,还会扫描 PCI 设备以查找 PCI 总线奇偶校验错误和 SERR 错误,以便确定数据传输过程中是否发生了错误。
必须以审慎的态度对待 PCI 奇偶校验错误的存在。有几个附加适配器在奇偶校验生成和报告方面不遵循 PCI 规范。规范说,如果供应商不打算生成奇偶校验,则应将奇偶校验状态位绑定为 0。一些供应商不这样做,因此奇偶校验位可能会“漂移”产生误报。
在 sysfs 中有一个由 EDAC PCI 扫描代码检查的 PCI 设备属性。如果设置了该属性,则跳过该设备的 PCI 奇偶校验/错误扫描。该属性是:
broken_parity_status
并且位于 PCI 设备的 /sys/devices/pci<XXX>/0000:XX:YY.Z 目录中。
版本控制¶
EDAC 由一个“核心”模块 (edac_core.ko) 和几个内存控制器 (MC) 驱动模块组成。在给定的系统上,将加载 CORE 和一个 MC 驱动程序。CORE 和 MC 驱动程序 (或 edac_device 驱动程序) 都有反映其各自模块当前发布级别的单独版本。
因此,要“报告”系统正在运行的版本,必须同时报告 CORE 和 MC 驱动程序的版本。
加载¶
如果 edac 是静态链接到内核的,则无需加载。如果 edac 是作为模块构建的,则只需 modprobe 您需要的 edac 部分。您应该能够 modprobe 特定硬件的模块,并由依赖项加载必要的核心模块。
示例
$ modprobe amd76x_edac
同时加载 amd76x_edac.ko 内存控制器模块和 edac_mc.ko 核心模块。
Sysfs 接口¶
EDAC 提供了一个用于控制和报告目的的 sysfs 接口。它位于 /sys/devices/system/edac 目录中。
目前该目录下有两个组件:
mc内存控制器系统
pci
PCI 控制和状态系统
内存控制器 (mc) 模型¶
每个 mc 设备控制一组内存模块 [4]。这些模块排列在片选行 (csrowX) 和通道表 (chX) 中。可以有多个 csrow 和多个通道。
现如今,术语 DIMM(双列直插式内存模块)被广泛用于指代内存模块,尽管还有其他内存封装替代方案,如 SO-DIMM、SIMM 等。UEFI 规范 (2.7 版) 在公共平台错误记录 (CPER) 部分定义内存模块为 SMBIOS 内存设备 (类型 17)。在本文档以及 EDAC 子系统中,术语“dimm”用于所有内存模块,即使它们使用不同种类的封装。
内存控制器允许几个 csrow,8 个 csrow 是一个典型值。然而,实际的 csrow 数量取决于给定主板的布局、内存控制器和内存模块的特性。
双通道允许在 CPU 和内存之间进行双倍数据长度(例如 64 位系统上为 128 位)的数据传输。一些较新的芯片组允许超过 2 个通道,如全缓冲 DIMM (FB-DIMM) 内存控制器。以下示例假设有 2 个通道:
片选行 (CS Rows)
通道 (Channels)
通道 0 (ch0)
通道 1 (ch1)DIMM_A0
DIMM_B0
csrow0rank0
rank0
csrow1rank1
rank1
DIMM_A1
DIMM_B1
csrow2rank0
rank0
csrow3rank1
rank1
在上述示例中,主板上有 4 个物理插槽用于存放内存 DIMM:
DIMM_A0
DIMM_B0
DIMM_A1
DIMM_B1
这些插槽的标签通常丝网印刷在主板上。在此示例中,标记为 A 的插槽为通道 0。标记为 B 的插槽为通道 1。请注意,一个物理 DIMM 上可能有两个 csrow。这些 csrow 根据内存 DIMM 所在的插槽分配其 csrow 分配。因此,当每个通道放置 1 个 DIMM 时,csrow 跨越两个 DIMM。
内存 DIMM 分为“单排”(single ranked) 或“双排”(dual ranked)。Rank 是一个已填充的 csrow。在上面的例子中,同样放置了 2 个双排 DIMM。因此,csrow0 和 csrow1 都已填充。另一方面,当在插槽 DIMM_A0 和 DIMM_B0 中放置 2 个单排 DIMM 时,它们将只有一个 csrow (csrow0),而 csrow1 将为空。这种模式在 csrow2 和 csrow3 上重复。另请注意,某些内存控制器没有任何逻辑来识别内存模块,请参阅下面的 rankX 目录。
上述表示反映在 EDAC 的 sysfs 接口的目录树中。从目录 /sys/devices/system/edac/mc 开始,每个内存控制器将由其自己的 mcX 目录表示,其中 X 是 MC 的索引:
..../edac/mc/
|
|->mc0
|->mc1
|->mc2
....
在每个 mcX 目录中都有几个 EDAC 控制和属性文件。
mcX 目录¶
在 mcX 目录中,是该内存控制器 X 实例的 EDAC 控制和属性文件。
有关 sysfs API 的描述,请参阅:
dimmX 或 rankX 目录¶
使用 EDAC 子系统的推荐方法是查看 dimmX 或 rankX 目录提供的信息 [5]。
一个典型的 EDAC 系统在 /sys/devices/system/edac/ 下具有以下结构 [6]:
/sys/devices/system/edac/
├── mc
│ ├── mc0
│ │ ├── ce_count
│ │ ├── ce_noinfo_count
│ │ ├── dimm0
│ │ │ ├── dimm_ce_count
│ │ │ ├── dimm_dev_type
│ │ │ ├── dimm_edac_mode
│ │ │ ├── dimm_label
│ │ │ ├── dimm_location
│ │ │ ├── dimm_mem_type
│ │ │ ├── dimm_ue_count
│ │ │ ├── size
│ │ │ └── uevent
│ │ ├── max_location
│ │ ├── mc_name
│ │ ├── reset_counters
│ │ ├── seconds_since_reset
│ │ ├── size_mb
│ │ ├── ue_count
│ │ ├── ue_noinfo_count
│ │ └── uevent
│ ├── mc1
│ │ ├── ce_count
│ │ ├── ce_noinfo_count
│ │ ├── dimm0
│ │ │ ├── dimm_ce_count
│ │ │ ├── dimm_dev_type
│ │ │ ├── dimm_edac_mode
│ │ │ ├── dimm_label
│ │ │ ├── dimm_location
│ │ │ ├── dimm_mem_type
│ │ │ ├── dimm_ue_count
│ │ │ ├── size
│ │ │ └── uevent
│ │ ├── max_location
│ │ ├── mc_name
│ │ ├── reset_counters
│ │ ├── seconds_since_reset
│ │ ├── size_mb
│ │ ├── ue_count
│ │ ├── ue_noinfo_count
│ │ └── uevent
│ └── uevent
└── uevent
在 dimmX 目录中,是该 X 内存模块的 EDAC 控制和属性文件
size- 由此 csrow 属性文件管理的总内存此属性文件以兆字节 (MB) 为单位显示此 csrow 包含的内存量。
dimm_ue_count- 不可纠正错误计数属性文件此属性文件显示此 DIMM 上发生的不可纠正错误的总数。如果设置了 panic_on_ue,则此计数器将没有机会递增,因为 EDAC 会使系统挂起。
dimm_ce_count- 可纠正错误计数属性文件此属性文件显示此 DIMM 上发生的可纠正错误的总数。检查这个计数非常重要。CE 提供了 DIMM 开始失效的早期迹象。应对此计数字段的非零值进行监控,并向系统管理员报告此类信息。
dimm_dev_type- 设备类型属性文件此属性文件将显示此 DIMM 上使用的 DRAM 设备类型。例如:
x1
x2
x4
x8
dimm_edac_mode- EDAC 操作模式属性文件此属性文件将显示正在使用的错误检测和纠正类型。
dimm_label- 内存模块标签控制文件此控制文件允许为此 DIMM 分配标签。有了模块中的这个标签,当发生错误时,输出可以在系统日志中提供 DIMM 标签。这对于隔离 UE 事件原因的紧急事件至关重要。
DIMM 标签必须在引导后分配,其信息应能够正确标识物理插槽及其丝网印刷标签。目前这些信息非常依赖主板,目前必须在用户空间确定这些信息。
dimm_location- 内存模块的位置位置最多可有 3 个层级,描述内存控制器如何识别内存模块的位置。取决于内存和内存控制器的类型,它可以是:
csrow 和 channel - 在内存控制器无法识别单个 DIMM 时使用 - 例如在
rankX目录中;branch、channel、slot - 通常用于 FB-DIMM 内存控制器;
channel、slot - 用于 Nehalem 及更新的 Intel 驱动程序。
dimm_mem_type- 内存类型属性文件此属性文件将显示此 csrow 上当前的内存类型。通常是缓冲 (buffered) 或无缓冲 (unbuffered) 内存。例如:
Registered-DDR
Unbuffered-DDR
在某些系统上,内存控制器没有任何逻辑来识别内存模块。在这些系统上,目录名为 rankX。在现代 Intel 内存控制器上,内存控制器直接识别内存模块。在这些系统上,目录名为 dimmX。
sysfs 映射中还有一些由 sysfs 子系统自动创建的 power 目录和 subsystem 符号链接。目前,它们没有实际用途。
系统日志¶
如果启用了 UE 和 CE 的记录,那么系统日志将包含指示已检测到错误的信息:
EDAC MC0: CE page 0x283, offset 0xce0, grain 8, syndrome 0x6ec3, row 0, channel 1 "DIMM_B1": amd76x_edac
EDAC MC0: CE page 0x1e5, offset 0xfb0, grain 8, syndrome 0xb741, row 0, channel 1 "DIMM_B1": amd76x_edac
消息的结构为:
内容
示例
内存控制器
MC0
错误类型
CE
内存页
0x283
页内偏移
0xce0
错误的字节粒度或分辨率
grain 8
错误校验子 (syndrome)
0xb741
内存行 (row)
row 0
内存通道 (channel)
channel 1
DIMM 标签(如果之前已设置)
DIMM B1
以及一个可选的驱动程序特定消息,可能包含其他信息。
对于没有信息的 UE 和 CE,将只显示内存控制器、错误类型、“no info”提示,以及可选的驱动程序特定错误消息。
PCI 总线奇偶校验检测¶
对于 Header Type 00 设备,无论设备上是否启用了奇偶校验,都会查看主要状态是否存在任何奇偶校验错误。(规范指示在某些情况下会生成奇偶校验)。对于 Header Type 01 桥接器,还会查看次要状态寄存器,以查看桥接器另一侧的总线上是否发生了奇偶校验。
Sysfs 配置¶
在 /sys/devices/system/edac/pci 目录下有如下控制和属性文件:
check_pci_parity- 启用/禁用 PCI 奇偶校验检查控制文件此控制文件启用或禁用 PCI 总线奇偶校验扫描操作。向此文件写入 1 启用扫描。向此文件写入 0 禁用扫描。
启用
echo "1" >/sys/devices/system/edac/pci/check_pci_parity
禁用
echo "0" >/sys/devices/system/edac/pci/check_pci_parity
pci_parity_count- 奇偶校验计数此属性文件将显示检测到的奇偶校验错误数。
模块参数¶
edac_mc_panic_on_ue- 遇到 UE 时挂起 (panic) 控制文件不可纠正错误将导致机器挂起。这通常是符合预期的。发生不可纠正错误时继续运行是个坏主意 - 无法确定什么未被纠正,操作系统上下文可能被严重破坏,以至于继续运行会导致进一步的损坏。如果内核配置了 MCE,则 EDAC 永远不会注意到 UE。
加载时间
module/kernel parameter: edac_mc_panic_on_ue=[0|1]
运行时间
echo "1" > /sys/module/edac_core/parameters/edac_mc_panic_on_ue
edac_mc_log_ue- 记录 UE 控制文件生成描述不可纠正错误的内核消息。这些错误通过系统消息日志系统报告。即使禁用了 UE 记录,也会累积 UE 统计信息。
加载时间
module/kernel parameter: edac_mc_log_ue=[0|1]
运行时间
echo "1" > /sys/module/edac_core/parameters/edac_mc_log_ue
edac_mc_log_ce- 记录 CE 控制文件生成描述可纠正错误的内核消息。这些错误通过系统消息日志系统报告。即使禁用了 CE 记录,也会累积 CE 统计信息。
加载时间
module/kernel parameter: edac_mc_log_ce=[0|1]
运行时间
echo "1" > /sys/module/edac_core/parameters/edac_mc_log_ce
edac_mc_poll_msec- 轮询周期控制文件轮询错误信息的时间周期(以毫秒为单位)。值太小会浪费资源。值太大可能会延迟必要的错误处理,并可能丢失用于定位错误的有价值信息。1000 毫秒(每秒一次)是当前的默认值。需要尽可能多带宽的系统可以增加此值。
加载时间
module/kernel parameter: edac_mc_poll_msec=[0|1]
运行时间
echo "1000" > /sys/module/edac_core/parameters/edac_mc_poll_msec
panic_on_pci_parity- 发生 PCI 奇偶校验错误时挂起此控制文件启用或禁用在检测到奇偶校验错误时挂起系统。
模块/内核参数
edac_panic_on_pci_pe=[0|1]
启用
echo "1" > /sys/module/edac_core/parameters/edac_panic_on_pci_pe
禁用
echo "0" > /sys/module/edac_core/parameters/edac_panic_on_pci_pe
EDAC 设备类型¶
在头文件 edac_pci.h 中,有一系列针对 EDAC_DEVICE 的 edac_device 结构和 API。
用户空间通过 sysfs 接口访问 edac_device。
在 /sys/devices/system/edac (sysfs) 位置会出现新的 edac_device 设备。
在上述 edac 目录下有一个三层结构的树。例如,test_device_edac 设备(可在 http://bluesmoke.sourceforget.net 网站找到)将其自身安装为:
/sys/devices/system/edac/test-instance
该目录中有各种控制文件、一个符号链接以及一个或多个 instance 目录。
标准默认控件包括:
log_ce
布尔值,用于记录 CE 事件
log_ue
布尔值,用于记录 UE 事件
panic_on_ue
布尔值,如果遇到 UE 则使系统挂起 (
panic)(默认关闭,可通过启动脚本设置为 true)poll_msec
事件轮询周期的时间
test_device_edac 设备至少添加了一个自己的自定义控制项:
test_bits
在当前的测试驱动程序中,除了显示它是如何安装的之外什么也不做。移植的驱动程序可以为特定用途添加一个或多个此类控制项和/或属性。一个树外驱动程序在此处使用控制项,以允许对硬件注入寄存器进行错误注入 (ERROR INJECTION) 操作。
符号链接指向为该 edac_device 注册的 ‘struct dev’。
实例 (Instances)¶
存在一个或多个实例目录。对于 test_device_edac 情况:
test-instance0
在该目录中有两个默认计数器属性,它们是更深子目录中计数器的总和。
ce_count
子目录中 CE 事件的总计
ue_count
子目录中 UE 事件的总计
块 (Blocks)¶
在最低目录层级是 block 目录。每个实例中可以指定 0、1 或多个块:
test-block0
该目录中的默认属性为:
ce_count
它是正在监控的硬件
block的 CE 事件计数器ue_count
它是正在监控的硬件
block的 UE 事件计数器
test_device_edac 设备增加了 4 个属性和 1 个控制项:
test-block-bits-0
每个轮询周期此计数器递增一次
test-block-bits-1
每 10 个周期此计数器增加一次,并将 test-block-bits-0 设置为 0
test-block-bits-2
每 100 个周期此计数器增加一次,并将 test-block-bits-1 设置为 0
test-block-bits-3
每 1000 个周期此计数器增加一次,并将 test-block-bits-2 设置为 0
reset-counters
向此控制项写入任何内容都将重置上述所有计数器。
使用 test_device_edac 驱动程序应该能使其他人能够为他们的硬件系统创建自己独特的驱动程序。
test_device_edac 示例驱动程序位于 EDAC 的 http://bluesmoke.sourceforge.net 项目站点。
在 Nehalem 及更新的 Intel CPU 上使用 EDAC API¶
在较旧的 Intel 架构中,内存控制器是北桥芯片组的一部分。Nehalem、Sandy Bridge、Ivy Bridge、Haswell、Sky Lake 及更新的 Intel 架构在 CPU 内部集成了增强版的内存控制器 (MC)。
本章将介绍在较新的 Intel CPU 上发现的增强型内存控制器的差异,如 i7core_edac、sb_edac 和 sbx_edac 驱动程序。
注意
Xeon E7 处理器系列使用独立的芯片作为内存控制器,称为 Intel Scalable Memory Buffer (可扩展内存缓冲)。本节不适用于此类系列。
每个 Quick Patch Interconnect (QPI) 有一个内存控制器。在驱动程序中,术语“插槽”(socket) 表示一个 QPI。这与物理 CPU 插槽相关联。
每个 MC 有 3 个物理读取通道、3 个物理写入通道和 3 个逻辑通道。驱动程序目前将其视为仅 3 个通道。每个通道最多可容纳 3 个 DIMM。
已知最小单位是 DIMM。没有关于 csrow 的信息。由于 EDAC API 映射的最小单位是 csrow,因此驱动程序会按顺序将通道/DIMM 映射到不同的 csrow 中。
例如,假设有以下布局:
Ch0 phy rd0, wr0 (0x063f4031): 2 ranks, UDIMMs dimm 0 1024 Mb offset: 0, bank: 8, rank: 1, row: 0x4000, col: 0x400 dimm 1 1024 Mb offset: 4, bank: 8, rank: 1, row: 0x4000, col: 0x400 Ch1 phy rd1, wr1 (0x063f4031): 2 ranks, UDIMMs dimm 0 1024 Mb offset: 0, bank: 8, rank: 1, row: 0x4000, col: 0x400 Ch2 phy rd3, wr3 (0x063f4031): 2 ranks, UDIMMs dimm 0 1024 Mb offset: 0, bank: 8, rank: 1, row: 0x4000, col: 0x400
驱动程序会将其映射为:
csrow0: channel 0, dimm0 csrow1: channel 0, dimm1 csrow2: channel 1, dimm0 csrow3: channel 2, dimm0
每个 csrow 导出一个 DIMM。
每个 QPI 都作为一个不同的内存控制器导出。
MC 具有注入错误以测试驱动程序的能力。驱动程序通过一些错误注入节点实现此功能:
对于注入内存错误,在
/sys/devices/system/edac/mc/mc?/下有一些 sysfs 节点:inject_addrmatch/*:控制错误注入掩码寄存器。可以指定地址的若干特征来匹配错误代码:
dimm = the affected dimm. Numbers are relative to a channel; rank = the memory rank; channel = the channel that will generate an error; bank = the affected bank; page = the page address; column (or col) = the address column.
上述每个值都可以设置为“any”以匹配任何有效值。
驱动程序初始化时,所有值都设置为 any。
例如,要在 dimm 2 的 rank 1 生成错误,适用于任何通道、任何库 (bank)、任何页面、任何列:
echo 2 >/sys/devices/system/edac/mc/mc0/inject_addrmatch/dimm echo 1 >/sys/devices/system/edac/mc/mc0/inject_addrmatch/rank To return to the default behaviour of matching any, you can do:: echo any >/sys/devices/system/edac/mc/mc0/inject_addrmatch/dimm echo any >/sys/devices/system/edac/mc/mc0/inject_addrmatch/rank
inject_eccmask:指定哪些位会出现问题,
inject_section:指定哪个 ECC 缓存段将发生错误
3 for both 2 for the highest 1 for the lowest
inject_type:指定错误的类型,由以下位组合而成:
bit 0 - repeat bit 1 - ecc bit 2 - parity
inject_enable:当写入非 0 内容时开始生成错误。
所有 inject 变量都可以读取。写入需要 root 权限。
数据表指出,只有在对匹配 inject_addrmatch 的地址进行写入后才会生成错误。然而,读取似乎也会产生错误。
例如,以下代码将对 socket 0 通道 2 上的任何 DIMM/地址的任何写访问生成错误:
echo 2 >/sys/devices/system/edac/mc/mc0/inject_addrmatch/channel echo 2 >/sys/devices/system/edac/mc/mc0/inject_type echo 64 >/sys/devices/system/edac/mc/mc0/inject_eccmask echo 3 >/sys/devices/system/edac/mc/mc0/inject_section echo 1 >/sys/devices/system/edac/mc/mc0/inject_enable dd if=/dev/mem of=/dev/null seek=16k bs=4k count=1 >& /dev/null
对于 socket 1,需要在上述命令中将 “mc0” 替换为 “mc1”。
生成的错误消息看起来像:
EDAC MC0: UE row 0, channel-a= 0 channel-b= 0 labels "-": NON_FATAL (addr = 0x0075b980, socket=0, Dimm=0, Channel=2, syndrome=0x00000040, count=1, Err=8c0000400001009f:4000080482 (read error: read ECC error))
可纠正错误内存寄存器计数器
这些较新的 MC 具有一些计数内存错误的寄存器。驱动程序使用这些寄存器来报告带寄存器的 DIMM (RDIMM) 设备上的可纠正错误。
然而,这些计数器不适用于不带寄存器的 DIMM (UDIMM)。由于芯片组提供了一些同样适用于 UDIMM 的计数器(但粒度级别比默认的差),因此驱动程序为 UDIMM 内存公开了这些寄存器。
可以通过查看
all_channel_counts/的内容来读取它们:$ for i in /sys/devices/system/edac/mc/mc0/all_channel_counts/*; do echo $i; cat $i; done /sys/devices/system/edac/mc/mc0/all_channel_counts/udimm0 0 /sys/devices/system/edac/mc/mc0/all_channel_counts/udimm1 0 /sys/devices/system/edac/mc/mc0/all_channel_counts/udimm2 0
这里的情况是,不同 csrow 但在相同 dimm 编号上的错误将增加相同的计数器。因此,在此内存映射中:
csrow0: channel 0, dimm0 csrow1: channel 0, dimm1 csrow2: channel 1, dimm0 csrow3: channel 2, dimm0
硬件会在 csrow0、csrow2 或 csrow3 上的第一个 dimm 发生错误时增加 udimm0 的计数;
硬件会在 csrow0、csrow2 或 csrow3 上的第二个 dimm 发生错误时增加 udimm1 的计数;
硬件会在 csrow0、csrow2 或 csrow3 上的第三个 dimm 发生错误时增加 udimm2 的计数;
标准错误计数器
当驱动程序收到 mcelog 错误时,会生成标准错误计数器。由于使用 UDIMM 时这是由软件计数的,因此可能会丢失一些错误。对于 RDIMM,它们显示寄存器的内容:
amd64_edac 使用的参考文档¶
amd64_edac 模块基于以下文档(可从 http://support.amd.com/en-us/search/tech-docs 获取):
- 标题:
AMD Athlon 64 和 AMD Opteron 处理器 BIOS 与内核开发者指南
- AMD 出版物编号 #:
26094
- 修订版本:
3.26
- 链接:
- 标题:
AMD NPT Family 0Fh 处理器 BIOS 与内核开发者指南
- AMD 出版物编号 #:
32559
- 修订版本:
3.00
- 发布日期:
2006 年 5 月
- 链接:
- 标题:
AMD Family 10h 处理器 BIOS 与内核开发者指南 (BKDG)
- AMD 出版物编号 #:
31116
- 修订版本:
3.00
- 发布日期:
2007 年 9 月 7 日
- 链接:
- 标题:
AMD Family 15h Models 30h-3Fh 处理器 BIOS 与内核开发者指南 (BKDG)
- AMD 出版物编号 #:
49125
- 修订版本:
3.06
- 发布日期:
2015 年 2 月 12 日(最新版本)
- 链接:
http://support.amd.com/TechDocs/49125_15h_Models_30h-3Fh_BKDG.pdf
- 标题:
AMD Family 15h Models 60h-6Fh 处理器 BIOS 与内核开发者指南 (BKDG)
- AMD 出版物编号 #:
50742
- 修订版本:
3.01
- 发布日期:
2015 年 7 月 23 日(最新版本)
- 链接:
http://support.amd.com/TechDocs/50742_15h_Models_60h-6Fh_BKDG.pdf
- 标题:
AMD Family 16h Models 00h-0Fh 处理器 BIOS 与内核开发者指南 (BKDG)
- AMD 出版物编号 #:
48751
- 修订版本:
3.03
- 发布日期:
2015 年 2 月 23 日(最新版本)
- 链接:
致谢¶
由 Doug Thompson 编写 <dougthompson@xmission.com>
2005 年 12 月 7 日
2007 年 7 月 17 日更新
© Mauro Carvalho Chehab
2009 年 8 月 5 日 Nehalem 接口
2016 年 10 月 26 日转换为 ReST 并清理 Nehalem 章节
EDAC 作者/维护者
Doug Thompson, Dave Jiang, Dave Peterson et al,
Mauro Carvalho Chehab
Borislav Petkov
原作者: Thayne Harbaugh