可靠性、可用性和可维护性 (RAS)

本文档介绍了内核中 RAS 功能的不同方面。

RAS 概念

可靠性、可用性和可维护性 (RAS) 是服务器上用于衡量其健壮性的概念。

可靠性

是指系统产生正确输出的概率。

  • 通常以平均故障间隔时间 (MTBF) 衡量

  • 通过有助于避免、检测和修复硬件故障的功能来增强

可用性

是指系统在给定时间处于运行状态的概率

  • 通常以每单位时间的停机时间百分比衡量

  • 通常使用机制在运行时检测和纠正硬件故障;

可服务性(或可维护性)

是指系统可以被修复或维护的简单性和速度

  • 通常以平均修复时间 (MTBR) 衡量

改进 RAS

为了减少系统停机时间,系统应该能够检测硬件错误,并在可能的情况下在运行时纠正它们。它还应该提供机制来检测硬件退化,以便在组件导致数据丢失或系统停机之前警告系统管理员采取更换组件的行动。

在监控措施中,最常见的包括

  • CPU – 检测指令执行和 L1/L2/L3 缓存中的错误;

  • 内存 – 添加错误纠正逻辑 (ECC) 来检测和纠正错误;

  • I/O – 为传输的数据添加 CRC 校验和;

  • 存储 – RAID、日志文件系统、校验和、自我监测、分析与报告技术 (SMART)。

通过监控错误检测的发生次数,可以识别硬件错误的概率是否正在增加,在这种情况下,进行预防性维护以在这些错误可纠正时更换退化的组件。

错误类型

现代系统中使用的大多数机制都使用汉明码等技术,这些技术允许在位包中的错误数量低于阈值时进行错误纠正。如果错误数量超过阈值,这些机制可以高度确信地指示发生了错误,但它们无法纠正。

此外,有时错误会发生在未使用的组件上。例如,当前未分配的内存部分。

这定义了一些错误类别

  • 可纠正错误 (CE) - 错误检测机制检测并纠正了错误。此类错误通常不是致命的,尽管某些内核机制允许系统管理员将其视为致命错误。

  • 不可纠正错误 (UE) - 发生的错误数量超过错误纠正阈值,系统无法自动纠正。

  • 致命错误 - 当系统关键组件(例如,内核的一部分被 UE 破坏)发生 UE 错误时,避免数据损坏的唯一可靠方法是挂起或重启机器。

  • 非致命错误 - 当未使用组件(如处于断电状态的 CPU 或未使用的内存组)发生 UE 错误时,系统可能仍能运行,并在可用时最终用热备件替换受影响的硬件。

    此外,当用户空间进程发生错误时,也可以终止该进程并让用户空间重新启动它。

处理非致命错误的机制通常很复杂,可能需要一些用户空间应用程序的帮助,以便应用系统管理员所需的策略。

识别故障硬件组件

仅仅检测硬件缺陷通常是不够的,因为系统需要精确定位应该更换的最小可替换单元 (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 定位器字段所示。请注意,在此类系统中,总宽度等于数据宽度。这意味着此类内存模块没有错误检测/纠正机制。

不幸的是,并非所有系统都使用相同的字段来指定内存组。在此示例中,来自一台旧服务器,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字段所示。请注意,此内存模块的数据宽度为 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 缓存的 ECC 检测器,以及 DMA 引擎、互连开关、主数据路径开关、互连和其他各种硬件数据路径。如果硬件报告了它,那么很可能可以构建一个 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 和多个通道。

内存控制器允许使用多个 csrow,其中 8 个 csrow 是典型值。然而,csrow 的实际数量取决于给定主板、内存控制器和内存模块特性的布局。

双通道允许双数据长度(例如,在 64 位系统上为 128 位)数据在 CPU 和内存之间传输。一些较新的芯片组允许超过 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 编号。因此,当每个通道放置一个 DIMM 时,csrow 跨越两个 DIMM。

内存 DIMM 有单“逻辑行”或双“逻辑行”之分。逻辑行是已填充的 csrow。在上述示例中,两个双逻辑行 DIMM 以类似方式放置。因此,csrow0 和 csrow1 都已填充。另一方面,当两个单逻辑行 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 由单个逻辑行 DIMM 组成。这也应该适用于两个通道,以使双通道模式正常运行。由于 csrow2 和 csrow3 都已填充,这表明通道 0 和 1 具有双逻辑行 DIMM 组。

在每个 mcXcsrowX 目录中都有几个 EDAC 控制和属性文件。

mcX 目录

mcX 目录中是此内存控制器 X 实例的 EDAC 控制和属性文件。

有关 sysfs API 的说明,请参阅

dimmXrankX 目录

使用 EDAC 子系统的推荐方法是查看 dimmXrankX 目录提供的信息[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 上发生可纠正错误的总计数。此计数检查非常重要。CEs 提供了 DIMM 开始出现故障的早期迹象。此计数字段应监控非零值并向系统管理员报告此类信息。

  • dimm_dev_type - 设备类型属性文件

    此属性文件将显示此 DIMM 上正在使用的 DRAM 设备类型。示例

    • x1

    • x2

    • x4

    • x8

  • dimm_edac_mode - EDAC 运行模式属性文件

    此属性文件将显示正在使用的错误检测和纠正类型。

  • dimm_label - 内存模块标签控制文件

    此控制文件允许为此 DIMM 分配一个标签。有了模块中的此标签,当发生错误时,输出可以在系统日志中提供 DIMM 标签。这对于恐慌事件隔离 UE 事件的原因至关重要。

    DIMM 标签必须在启动后分配,并带有正确标识物理插槽及其丝印标签的信息。此信息目前非常依赖于主板,并且此信息的确定必须在此刻在用户空间中进行。

  • dimm_location - 内存模块位置

    位置可以有最多 3 个级别,并描述内存控制器如何识别内存模块的位置。根据内存和内存控制器的类型,它可以是

    • csrowchannel - 当内存控制器无法识别单个 DIMM 时使用 - 例如在 rankX 目录中;

    • branch, channel, slot - 通常用于 FB-DIMM 内存控制器;

    • channel, slot - 用于 Nehalem 和更新的 Intel 驱动程序。

  • dimm_mem_type - 内存类型属性文件

    此属性文件将显示此 csrow 上当前的内存类型。通常是缓冲或非缓冲内存。示例

    • 注册式 DDR

    • 非缓冲式 DDR

csrowX 目录

当 CONFIG_EDAC_LEGACY_SYSFS 启用时,sysfs 将包含 csrowX 目录。由于此 API 对 Rambus、FB-DIMM 和现代 Intel 内存控制器不能正常工作,因此正在弃用,转而使用 dimmX 目录。

csrowX 目录中是此 csrow X 实例的 EDAC 控制和属性文件

  • ue_count - 不可纠正错误总数属性文件

    此属性文件显示此 csrow 上发生的不可纠正错误的总计数。如果设置了 panic_on_ue,则此计数器将没有机会递增,因为 EDAC 会使系统崩溃。

  • ce_count - 可纠正错误总数属性文件

    此属性文件显示此 csrow 上发生的可纠正错误的总计数。此计数检查非常重要。CEs 提供了 DIMM 开始出现故障的早期迹象。此计数字段应监控非零值并向系统管理员报告此类信息。

  • size_mb - 此 csrow 属性文件管理的内存总大小

    此属性文件以兆字节为单位显示此 csrow 包含的内存大小。

  • mem_type - 内存类型属性文件

    此属性文件将显示此 csrow 上当前的内存类型。通常是缓冲或非缓冲内存。示例

    • 注册式 DDR

    • 非缓冲式 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

每个轮询周期此计数器递增

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 架构将增强版内存控制器 (MC) 集成到 CPU 内部。

本章将介绍在较新 Intel CPU 上发现的增强型内存控制器(例如 i7core_edacsb_edacsbx_edac 驱动程序)的差异。

注意

Xeon E7 处理器系列使用独立的芯片作为内存控制器,称为 Intel 可扩展内存缓冲区。本节不适用于此类系列。

  1. 每个快速补丁互连 (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 都作为不同的内存控制器导出。

  2. 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 的逻辑行 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 值时开始错误生成。

    所有注入变量都可以读取。写入需要 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))
    
  3. 可纠正错误内存寄存器计数器

    这些较新的 MC 具有一些计数内存错误的寄存器。驱动程序使用这些寄存器来报告具有注册式 DIMM 的设备上的可纠正错误。

    然而,这些计数器不适用于非注册式 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
    

    这里发生的情况是,不同 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;

  4. 标准错误计数器

    当驱动程序收到 mcelog 错误时,会生成标准错误计数器。由于使用 UDIMM 时,这是由软件计数的,因此可能会丢失一些错误。对于 RDIMM,它们显示寄存器的内容

amd64_edac 中使用的参考文档

amd64_edac 模块基于以下文档(可从 http://support.amd.com/en-us/search/tech-docs 获取)

  1. 标题:

    AMD Athlon 64 和 AMD Opteron 处理器 BIOS 和内核开发者指南

    AMD 出版号:

    26094

    修订版:

    3.26

    链接:

    http://support.amd.com/TechDocs/26094.PDF

  2. 标题:

    AMD NPT Family 0Fh 处理器 BIOS 和内核开发者指南

    AMD 出版号:

    32559

    修订版:

    3.00

    发布日期:

    2006 年 5 月

    链接:

    http://support.amd.com/TechDocs/32559.pdf

  3. 标题:

    AMD Family 10h 处理器 BIOS 和内核开发者指南 (BKDG)

    AMD 出版号:

    31116

    修订版:

    3.00

    发布日期:

    2007 年 9 月 7 日

    链接:

    http://support.amd.com/TechDocs/31116.pdf

  4. 标题:

    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

  5. 标题:

    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

  6. 标题:

    AMD Family 16h Models 00h-0Fh 处理器 BIOS 和内核开发者指南 (BKDG)

    AMD 出版号:

    48751

    修订版:

    3.03

    发布日期:

    2015/2/23(最新版本)

    链接:

    http://support.amd.com/TechDocs/48751_16h_bkdg.pdf

致谢

  • 撰写者: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