可靠性、可用性和可维护性 (RAS)¶
本文档介绍了内核中存在的 RAS 功能的不同方面。
RAS 概念¶
可靠性、可用性和可维护性 (RAS) 是服务器上使用的一个概念,旨在衡量其稳健性。
- 可靠性
是系统产生正确输出的概率。
通常以平均故障间隔时间 (MTBF) 来衡量
通过有助于避免、检测和修复硬件故障的功能来增强
- 可用性
是系统在给定时间可操作的概率
通常以每段时间的停机时间的百分比来衡量
通常使用运行时检测和纠正硬件故障的机制;
- 可维护性
是系统可以修复或维护的简易性和速度
通常以平均修复时间 (MTBR) 来衡量
改进 RAS¶
为了减少系统停机时间,系统应能够检测硬件错误,并且在可能的情况下,在运行时纠正这些错误。它还应提供检测硬件退化的机制,以便警告系统管理员采取措施更换组件,以免导致数据丢失或系统停机。
在监控措施中,最常见的措施包括
CPU – 检测指令执行时以及 L1/L2/L3 缓存中的错误;
内存 – 添加错误纠正逻辑 (ECC) 以检测和纠正错误;
I/O – 为传输的数据添加 CRC 校验和;
存储 – RAID、日志文件系统、校验和、自我监控、分析和报告技术 (SMART)。
通过监控错误检测的发生次数,可以确定硬件错误的概率是否在增加,在这种情况下,进行预防性维护以在这些错误可纠正时更换退化的组件。
错误类型¶
现代系统上使用的大多数机制都使用诸如汉明码之类的技术,当位数据包上的错误数量低于阈值时,该技术允许纠错。如果错误数量高于该阈值,这些机制可以高度自信地表明发生了错误,但它们无法纠正。
此外,有时会在未使用的组件上发生错误。例如,当前未分配的一部分内存。
这定义了错误的一些类别
可纠正错误 (CE) - 错误检测机制检测并纠正了错误。此类错误通常不是致命的,尽管某些内核机制允许系统管理员将其视为致命错误。
未纠正错误 (UE) - 发生的错误数量高于错误纠正阈值,并且系统无法自动纠正。
致命错误 - 当 UE 错误发生在系统的关键组件上(例如,内核的一部分被 UE 损坏)时,避免数据损坏的唯一可靠方法是挂起或重新启动机器。
非致命错误 - 当 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”,由库定位器字段给出。请注意,在此类系统上,总宽度等于数据宽度。这意味着此类内存模块没有错误检测/纠正机制。
不幸的是,并非所有系统都使用相同的字段来指定内存库。在此示例中,来自较旧的服务器,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”,由定位器字段给出。请注意,此内存模块具有 64 位的数据宽度和 72 位的总宽度。因此,它有 8 个额外的位供错误检测和纠正机制使用。这种类型的内存称为纠错码内存 (ECC 内存)。
更糟糕的是,系统主板上具有不同标签的系统使用完全相同的 BIOS 并非不常见,这意味着 BIOS 提供的标签与实际标签不匹配。
ECC 内存¶
如上一节所述,ECC 内存有额外的位用于纠错。在上面的示例中,一个内存模块具有 64 位的数据宽度和 72 位的总宽度。用于错误检测和纠正机制的额外 8 位称为校验位[1][2]。
因此,当 CPU 请求内存控制器写入具有数据宽度的字时,内存控制器会使用汉明码或一些其他纠错码(如 SECDED+)实时计算校验位,从而生成一个具有总宽度大小的代码。然后将此代码写入内存模块。
在读取时,将使用与写入时相同的 ECC 代码将总宽度位代码转换回,生成一个具有数据宽度和校验位的字。即使发生错误,也还是将具有数据宽度的字发送到 CPU。
内存控制器还会查看校验位,以检查是否存在错误,以及 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 事件和系统恐慌的可能性。
其他硬件元件¶
EDAC 的一个新功能,即 edac_device
类设备,在内核的 2.6.23 版本中添加。
这种新设备类型允许非内存类型的 ECC 硬件检测器通过 sysfs 接口收集其状态并呈现给用户空间。
一些架构为 L1、L2 和 L3 缓存以及 DMA 引擎、结构交换机、主数据路径交换机、互连和各种其他硬件数据路径配备了 ECC 检测器。如果硬件报告了它,那么可能会构建一个 edac_device 设备来收集并将其呈现给用户空间。
PCI 总线扫描¶
此外,还会扫描 PCI 设备是否存在 PCI 总线奇偶校验和 SERR 错误,以确定数据传输期间是否发生错误。
必须谨慎对待 PCI 奇偶校验错误的存在。有几个附加适配器不遵守 PCI 规范关于奇偶校验生成和报告的规定。规范指出,如果供应商不打算生成奇偶校验,则应将奇偶校验状态位绑定为 0。一些供应商没有这样做,因此奇偶校验位可能会“浮动”,从而产生误报。
在 sysfs 中有一个 PCI 设备属性,EDAC 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 目录中。
在此目录中,当前存在 2 个组件
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 或从 CPU 到内存的双倍数据长度(例如,64 位系统上的 128 位)数据传输。一些较新的芯片组允许多于 2 个通道,例如全缓冲 DIMM (FB-DIMM) 内存控制器。以下示例将假定有 2 个通道
CS 行
通道
ch0
ch1
DIMM_A0
DIMM_B0
csrow0
rank0
rank0
csrow1
rank1
rank1
DIMM_A1
DIMM_B1
csrow2
rank0
rank0
csrow3
rank1
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 有单“ranked”或双“ranked”之分。一个 rank 是一个已填充的 csrow。在上面的示例中,两个双 ranked DIMM 以类似方式放置。因此,csrow0 和 csrow1 都已填充。另一方面,当两个单 ranked DIMM 放置在 DIMM_A0 和 DIMM_B0 插槽中时,它们将只有一个 csrow (csrow0),并且 csrow1 将为空。csrow2 和 csrow3 的模式会重复自身。另请注意,某些内存控制器没有任何逻辑来识别内存模块,请参见下面的 rankX
目录。
上述表示形式反映在 EDAC sysfs 接口的目录树中。从 /sys/devices/system/edac/mc
目录开始,每个内存控制器都将由其自己的 mcX
目录表示,其中 X
是 MC 的索引
..../edac/mc/
|
|->mc0
|->mc1
|->mc2
....
在每个 mcX
目录下,每个 csrowX
再次由 csrowX
表示,其中 X
是 csrow 索引
.../mc/mc0/
|
|->csrow0
|->csrow2
|->csrow3
....
请注意,没有 csrow1,这表明 csrow0 由单 ranked DIMM 组成。为了使双通道模式能够运行,这也应适用于两个通道。由于 csrow2 和 csrow3 都已填充,这表示通道 0 和 1 的一组双 ranked DIMM。
在每个 mcX
和 csrowX
目录中,都有几个 EDAC 控制和属性文件。
mcX
目录¶
在 mcX
目录中,是此 X
内存控制器实例的 EDAC 控制和属性文件。
有关 sysfs API 的描述,请参见
Documentation/ABI/testing/sysfs-devices-edac
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 属性文件管理的内存总量此属性文件以兆字节为单位显示此 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 上当前使用的内存类型。通常,是缓冲内存或非缓冲内存。示例:
Registered-DDR
Unbuffered-DDR
在某些系统中,内存控制器没有任何逻辑来识别内存模块。在这样的系统上,该目录被称为 rankX
,其工作方式类似于 csrowX
目录。在现代 Intel 内存控制器上,内存控制器直接识别内存模块。在这样的系统上,该目录被称为 dimmX
。
在 sysfs 映射内部还有一些 power
目录和 subsystem
符号链接,它们是由 sysfs 子系统自动创建的。目前,它们没有任何用途。
csrowX
目录¶
当启用 CONFIG_EDAC_LEGACY_SYSFS 时,sysfs 将包含 csrowX
目录。由于此 API 对于 Rambus、FB-DIMM 和现代 Intel 内存控制器无法正常工作,因此已被弃用,转而支持 dimmX
目录。
在 csrowX
目录中,包含此 X
个 csrow 实例的 EDAC 控制和属性文件
ue_count
- 总的不可纠正错误计数属性文件此属性文件显示在此 csrow 上发生的不可纠正错误的总计数。如果设置了 panic_on_ue,则此计数器将没有机会递增,因为 EDAC 会使系统崩溃。
ce_count
- 总的可纠正错误计数属性文件此属性文件显示在此 csrow 上发生的可纠正错误的总计数。此计数对于检查非常重要。CE 提供 DIMM 开始出现故障的早期迹象。应监视此计数字段的非零值,并将此类信息报告给系统管理员。
size_mb
- 此 csrow 管理的总内存属性文件此属性文件以兆字节为单位显示此 csrow 包含的内存。
mem_type
- 内存类型属性文件此属性文件将显示此 csrow 上当前使用的内存类型。通常,是缓冲内存或非缓冲内存。示例:
Registered-DDR
Unbuffered-DDR
edac_mode
- EDAC 操作模式属性文件此属性文件将显示正在使用的错误检测和纠正的类型。
dev_type
- 设备类型属性文件此属性文件将显示此 DIMM 上使用的 DRAM 设备类型。示例
x1
x2
x4
x8
ch0_ce_count
- 通道 0 CE 计数属性文件此属性文件将显示位于通道 0 中的此 DIMM 上的 CE 计数。
ch0_ue_count
- 通道 0 UE 计数属性文件此属性文件将显示位于通道 0 中的此 DIMM 上的 UE 计数。
ch0_dimm_label
- 通道 0 DIMM 标签控制文件此控制文件允许为此 DIMM 分配一个标签。有了模块中的此标签,当发生错误时,输出可以在系统日志中提供 DIMM 标签。这对于隔离 UE 事件的原因的崩溃事件至关重要。
DIMM 标签必须在启动后分配,并包含正确标识物理插槽及其丝印标签的信息。此信息目前非常依赖于主板,并且此时必须在用户空间中确定此信息。
ch1_ce_count
- 通道 1 CE 计数属性文件此属性文件将显示位于通道 1 中的此 DIMM 上的 CE 计数。
ch1_ue_count
- 通道 1 UE 计数属性文件此属性文件将显示位于通道 0 中的此 DIMM 上的 UE 计数。
ch1_dimm_label
- 通道 1 DIMM 标签控制文件此控制文件允许为此 DIMM 分配一个标签。有了模块中的此标签,当发生错误时,输出可以在系统日志中提供 DIMM 标签。这对于隔离 UE 事件的原因的崩溃事件至关重要。
DIMM 标签必须在启动后分配,并包含正确标识物理插槽及其丝印标签的信息。此信息目前非常依赖于主板,并且此时必须在用户空间中确定此信息。
系统日志记录¶
如果启用了 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
错误的字节粒度或分辨率
粒度 8
错误综合症
0xb741
内存行
行 0
内存通道
通道 1
DIMM 标签(如果事先设置)
DIMM B1
然后是可选的、特定于驱动程序的、可能包含其他信息的消息。
没有信息的 UE 和 CE 都将缺少除内存控制器、错误类型、“无信息”的通知,以及可选的、特定于驱动程序的错误消息之外的所有内容。
PCI 总线奇偶校验检测¶
在标头类型 00 设备上,无论设备是否启用了奇偶校验,都会检查主状态是否存在任何奇偶校验错误。(规范指出在某些情况下会生成奇偶校验)。在标头类型 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 崩溃控制文件不可纠正的错误将导致机器崩溃。这通常是可取的。在发生不可纠正的错误时继续操作是一个坏主意 - 未纠正的内容是不确定的,并且操作系统上下文可能已严重损坏,以至于继续操作将导致进一步的损坏。如果内核配置了 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
在当前的测试驱动程序中,除了显示其安装方式外,不执行任何操作。移植的驱动程序可以添加一个或多个此类控件和/或属性以供特定用途。一个外部驱动程序在此处使用控件以允许对硬件注入寄存器执行错误注入操作
该符号链接指向为此 edac_device 注册的“struct dev”。
实例¶
存在一个或多个实例目录。对于 test_device_edac
的情况
test-instance0
在此目录中,有两个默认计数器属性,它们是更深层子目录中计数器的总和。
ce_count
子目录的 CE 事件总数
ue_count
子目录的 UE 事件总数
块¶
在最低目录级别是 block
目录。每个实例中可以指定 0 个、1 个或多个块。
test-block0
在此目录中,默认属性为:
ce_count
这是被监控的硬件的此
block
的 CE 事件计数器。ue_count
这是被监控的硬件的此
block
的 UE 事件计数器。
test_device_edac
设备添加 4 个属性和 1 个控制。
test-block-bits-0
在每个 POLL 周期,此计数器都会递增。
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 可扩展内存缓冲器。本节不适用于此类系列。
每个快速通道互连 (QPI) 有一个内存控制器。在驱动程序中,“插槽”一词表示一个 QPI。这与物理 CPU 插槽相关联。
每个 MC 有 3 个物理读取通道、3 个物理写入通道和 3 个逻辑通道。驱动程序目前将其视为 3 个通道。每个通道最多可以有 3 个 DIMM。
已知的最小单位是 DIMM。没有关于 csrows 的信息。由于 EDAC API 映射的最小单位是 csrows,因此驱动程序将通道/DIMM 依次映射到不同的 csrows。
例如,假设以下布局
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、任何 page、任何 column 生成错误
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 内容时,启动错误生成。
可以读取所有注入变量。写入需要 root 权限。
数据表指出,只有在与 inject_addrmatch 匹配的地址上进行写入后才会生成错误。但是,似乎读取也会产生错误。
例如,以下代码将在插槽 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
对于插槽 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 有一些寄存器来计算内存错误。驱动程序使用这些寄存器来报告具有 Registered DIMM 的设备上的已更正错误。
但是,这些计数器不适用于 Unregistered DIMM。由于芯片组提供了一些也适用于 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
这里发生的事情是,在不同 csrows 上但在相同 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 等人,
Mauro Carvalho Chehab
Borislav Petkov
原始作者:Thayne Harbaugh