可靠性、可用性和可维护性 (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 和多个通道。

内存控制器允许多个 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。

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

mcX 目录

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

有关 sysfs API 的描述,请参见

Documentation/ABI/testing/sysfs-devices-edac

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 上发生的可纠正错误的总计数。此计数对于检查非常重要。CE 提供了一个 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 目录中;

    • branchchannelslot - 通常用于 FB-DIMM 内存控制器;

    • channelslot - 用于 Nehalem 和更新的 Intel 驱动程序。

  • dimm_mem_type - 内存类型属性文件

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

    • Registered-DDR

    • Unbuffered-DDR

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_edacsb_edacsbx_edac 驱动程序)的差异。

注意

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

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

  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 的 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))
    
  3. 已更正的错误内存寄存器计数器

    这些较新的 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;

  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