4. Xeon RAS特性深入
在上一章我们建立了RAS的整体分层认知,这一章把镜头拉近到Xeon处理器内部,逐一拆解六个最常被提及、也最容易混淆的RAS机制。理解它们的共同点在于:每一个机制都对应“检测—上报—恢复”链条上的一个具体环节,区别只在于检测的对象、上报的路径和恢复的粒度不同。
MCA:机器检查架构的寄存器语义
MCA(Machine Check Architecture)是x86处理器报告硬件错误的寄存器框架。它并不“检测”错误,而是为检测逻辑提供标准化的记录位置。每个CPU核心和每个Uncore单元都有一组MCi_STATUS、MCi_ADDR、MCi_MISC寄存器,i为bank编号。当某个bank捕获到错误时,硬件置位MCi_STATUS中的VAL位,同时写入错误类型(ECC、奇偶、超时等)、错误严重度(UC不可纠正 / CE可纠正 / UCR可恢复不可纠正)以及错误来源。
读取这些寄存器最直接的方式是通过MSR。例如在Linux下用rdmsr工具读取bank 4的状态:
# 读取CPU0 bank4的MCi_STATUS
rdmsr -p 0 0x40D
# 输出示例:0xbe00000000400151
# bit63=1 表示VAL有效,bit62=0 表示未溢出
# bit61=1 表示UE,bit58=1 表示可恢复
解读时先看bit63(VAL)确认记录有效,再看bit61(UC)判断是否可纠正,最后结合MCi_MISC中的地址信息定位物理页。MCA的价值在于它是所有上层机制的数据源头——CMCI、SMI、OS的EDAC驱动最终都读同一组寄存器。
CMCI:可纠正错误的中断化上报
传统上可纠正错误(CE)通过轮询MCi_STATUS发现,延迟高且浪费CPU周期。CMCI(Corrected Machine Check Interrupt)把CE上报改为中断方式:当某个bank的CE计数超过阈值时,硬件产生CMCI中断,OS在中断处理中读取寄存器并决定是否采取动作(如页面离线)。
配置CMCI的关键是设置阈值。以Linux为例,可通过/sys/devices/system/machinecheck/machinecheck0/下的接口调整:
# 查看当前CMCI阈值
cat /sys/devices/system/machinecheck/machinecheck0/check_interval
# 设置bank4的CE阈值为10
echo 10 > /sys/devices/system/machinecheck/machinecheck0/bank4/threshold
阈值过低会导致中断风暴,过高则可能错过早期劣化信号。工程上通常把内存CE阈值设在5~20之间,并结合巡检机制一起使用。
内存巡检:主动发现潜在故障
内存巡检(Memory Patrol Scrub)是硬件在后台周期性读取内存、校验ECC并纠正CE的过程。它的意义在于:把“等到访问时才暴露”的CE提前发现并纠正,避免CE累积成UE。巡检由内存控制器自动执行,可通过BIOS或OS接口控制速率。
在Linux下可通过EDAC子系统观察巡检状态:
# 查看内存控制器巡检统计
cat /sys/devices/system/edac/mc/mc0/ce_count
cat /sys/devices/system/edac/mc/mc0/ue_count
# 查看巡检速率(部分平台支持)
cat /sys/devices/system/edac/mc/mc0/scrub_rate
巡检速率需要权衡:速率越高,发现CE越快,但占用内存带宽越多。对于延迟敏感型业务,通常把巡检安排在业务低峰期或采用较低速率。
PPR:页级内存修复
PPR(Post Package Repair)是在内存颗粒级别修复故障行的机制。当某个DRAM行出现可纠正错误时,PPR可以把该行重映射到颗粒内部的备用行,从而在不更换内存条的情况下消除故障源。PPR分为硬PPR(hPPR,永久性,需重启)和软PPR(sPPR,临时性,可在线执行)。
触发PPR的典型流程是:巡检或访问发现某行CE超过阈值 → 记录行地址 → 在下次重启时由BIOS执行hPPR。部分平台支持sPPR在线修复,但备用行数量有限,用尽后只能更换内存。配置上需在BIOS中启用“Memory Post Package Repair”选项,并确认备用行资源充足。
DDDC:设备数据损坏检测与纠正
DDDC(Device Data Corruption Detection and Correction)针对的是PCIe设备DMA写入内存时可能引入的数据损坏。传统ECC只能保护内存颗粒本身,无法发现设备写入的错误数据。DDDC在数据通路上增加校验,当检测到设备写入的数据与预期不符时,触发错误上报并尝试纠正。
DDDC通常与DMAr(DMA Remapping)和AER(Advanced Error Reporting)配合使用。配置时需在BIOS中启用“DDDC”或“Data Poisoning”相关选项,并在OS侧确认AER驱动已加载:
# 确认AER服务状态
systemctl status aer-inject
# 查看PCIe设备AER能力
lspci -vvv | grep -i "Advanced Error"
DDDC的误报率较低,但一旦触发往往意味着设备固件或链路存在问题,应结合AER日志定位具体设备。
SMI Lane Failover:链路级冗余切换
SMI Lane Failover针对的是UPI或PCIe链路中单条Lane故障的场景。当某条Lane出现持续错误时,硬件可以把该Lane上的流量切换到备用Lane,从而维持链路整体可用。这要求链路在物理上预留冗余Lane,并在BIOS中启用Failover功能。
配置要点包括:确认CPU之间或CPU与设备之间的链路有备用Lane;在BIOS中启用“SMI Lane Failover”或“Link Width Degradation”策略;在OS侧通过lspci或dmidecode观察链路宽度是否发生降级。例如:
# 查看UPI链路状态
lspci -vvv | grep -i "LnkSta"
# 输出示例:LnkSta: Speed 10.4GT/s, Width x20 (downgraded)
当看到“downgraded”时,说明发生了Lane降级,需要结合MCA和AER日志判断是暂时性错误还是硬件故障。
机制协同与配置要点
这六个机制不是孤立运行的。一次典型的内存CE事件会经历:巡检或访问发现CE → MCA bank记录 → CMCI中断上报 → OS读取EDAC统计 → 若同一行反复出错则触发PPR → 重启后备用行生效。而DDDC和SMI Lane Failover则分别覆盖设备侧和链路侧的故障域。
配置时建议按以下顺序检查:首先确认BIOS中MCA、CMCI、Patrol Scrub、PPR、DDDC、Lane Failover均已启用;其次在OS侧确认EDAC驱动加载、CMCI阈值合理、AER服务正常;最后通过rasdaemon或mcelog持续监控错误计数,建立基线以便发现异常增长。