当前位置:

首页 > 硬件相关 > RAS(三)Intel MCA-CMCI深度解读

RAS(三)Intel MCA-CMCI深度解读

RAS(三)IntelMCA-CMCI修正的机器检查错误中断(CMCI)是MCA的一个增强特性,它提供了一种基于阈值的错误报告方式。通过这种模式,软件可以配置硬件校正MC错误的阈值,当硬件发生的CE(校正错误)次数达到设定阈值时,会产生一个中断通知软件处理。需要注意的是,CMCI是随MCA引入的特性,最初只能通过软件轮询方式获取CE信息。CMCI中断通知方式的优势在于,每个CE都将通过IRQ处理,不会丢失任何CE;而轮询方式则可能因轮询频率低、存储空间有限等原因导致CE丢失。然而,CMCI并非总是最佳选

RAS(三)Intel MCA-CMCI

修正的机器检查错误中断(CMCI)是MCA的一个增强特性,它提供了一种基于阈值的错误报告方式。通过这种模式,软件可以配置硬件校正MC错误的阈值,当硬件发生的CE(校正错误)次数达到设定阈值时,会产生一个中断通知软件处理。

需要注意的是,CMCI是随MCA引入的特性,最初只能通过软件轮询方式获取CE信息。CMCI中断通知方式的优势在于,每个CE都将通过IRQ处理,不会丢失任何CE;而轮询方式则可能因轮询频率低、存储空间有限等原因导致CE丢失。然而,CMCI并非总是最佳选择,其缺点在于大量的CE可能引发中断风暴,影响机器性能。在云服务器场景中,CE风暴较为常见,那么Intel服务器是如何解决这一问题的呢?下文将详细说明。

CMCI机制

CMCI默认是关闭的,软件需要通过配置IA32_MCG_CAP[10] = 1来启用。

软件通过IA32_MCi_CTL2 MSR来控制对应Bank的CMCI功能的启用或关闭。

通过IA32_MCi_CTL2 Bit 14:0设置阈值,如果设置非0,则使用配置的阈值;如果CMCI不支持,则全0;

CMCI机制如下图所示:

RAS(三)Intel MCA-CMCI硬件通过比较IA32_MCi_CTL2 Bit 14:0和IA32_MCi_STATUS Bit 52:38,如果数值相等,则溢出事件发送到APIC的CMCI LVT条目。如果MC错误涉及多个处理器,那么CMCI中断会同时发送到这些处理器,例如两个CPU共享的缓存发生CE,这两个CPU都会收到CMCI。

CMCI初始化

以Linux v6.3分支为例,内核启用CMCI的代码如下:

arch/x86/kernel/cpu/mce/intel.c
void intel_init_cmci(void)
{
    int banks;
    if (!cmci_supported(&banks))
        return;
    mce_threshold_vector = intel_threshold_interrupt;
    cmci_discover(banks);
    /* 
     * For CPU #0 this runs with still disabled APIC, but that's 
     * ok because only the vector is set up. We still do another 
     * check for the banks later for CPU #0 just to make sure 
     * to not miss any events. 
     */
    apic_write(APIC_LVTCMCI, THRESHOLD_APIC_VECTOR|APIC_DM_FIXED);
    cmci_recheck();
}
  1. cmci_supported()函数的主要任务包括:

    • 根据内核启动参数"mce=no_cmci,ignore_ce"判断是否启用cmci和ce报告功能
    • 检查硬件是否支持cmci
    • 通过MCG_CMCI_P位判断硬件是否已启用cmci功能
  2. mce_threshold_vector = intel_threshold_interrupt; 声明cmci的中断处理函数为intel_threshold_interrupt();

  3. cmci_discover()函数的主要功能是:

    • 遍历所有banks,通过配置IA32_MCi_CTL2寄存器启用所有bank的cmci功能;
rdmsrl(MSR_IA32_MCx_CTL2(i), val);
...
val |= MCI_CTL2_CMCI_EN;
wrmsrl(MSR_IA32_MCx_CTL2(i), val);
rdmsrl(MSR_IA32_MCx_CTL2(i), val);
  • 设置cmci阈值,代码如下:
#define CMCI_THRESHOLD 1
if (!mca_cfg.bios_cmci_threshold) {
    val &= ~MCI_CTL2_CMCI_THRESHOLD_MASK;
    val |= CMCI_THRESHOLD;
} else if (!(val & MCI_CTL2_CMCI_THRESHOLD_MASK)) {
    /* 
     * If bios_cmci_threshold boot option was specified 
     * but the threshold is zero, we'll try to initialize 
     * it to 1. 
     */
    bios_zero_thresh = 1;
    val |= CMCI_THRESHOLD;
}

如果用户未通过启动参数"mce=bios_cmci_threshold"配置值,则val = CMCI_THRESHOLD,为1;

如果启动参数"mce=bios_cmci_threshold"配置,那么表示bios已配置阈值,即val & MCI_CTL2_CMCI_THRESHOLD_MASK不为0,跳过else if判断,采用bios配置值;如果bios未配置值,val & MCI_CTL2_CMCI_THRESHOLD_MASK为0,那么驱动将阈值初始化为1。

  1. cmci_recheck()

    cmci_recheck函数通过调用machine_check_poll(),检查CPU #0是否有遗漏的CE&UCE事件。

CMCI处理

cmci中断处理函数为intel_threshold_interrupt(),定义在arch/x86/kernel/cpu/mce/intel.c:

/* 
 * The interrupt handler. This is called on every event. 
 * Just call the poller directly to log any events. 
 * This could in theory increase the threshold under high load, 
 * but doesn't for now. 
 */
static void intel_threshold_interrupt(void)
{
    if (cmci_storm_detect())
        return;
    machine_check_poll(MCP_TIMESTAMP, this_cpu_ptr(&mce_banks_owned));
}
  1. cmci_storm_detect()函数主要是对cmci风暴的处理,代码如下:
static bool cmci_storm_detect(void)
{
    unsigned int cnt = __this_cpu_read(cmci_storm_cnt);
    unsigned long ts = __this_cpu_read(cmci_time_stamp);
    unsigned long now = jiffies;
    int r;
    if (__this_cpu_read(cmci_storm_state) != CMCI_STORM_NONE)
        return true;
    if (time_before_eq(now, ts + CMCI_STORM_INTERVAL)) {
        cnt++;
    } else {
        cnt = 1;
        __this_cpu_write(cmci_time_stamp, now);
    }
    __this_cpu_write(cmci_storm_cnt, cnt);
    if (cnt >= CMCI_STORM_THRESHOLD) {
        cmci_toggle_interrupt_mode();
        return true;
    }
    return false;
}

该函数通过jiffies,判断固定时间内发生的cmci次数是否大于CMCI_STORM_THRESHOLD(15),如果不是则返回,否则说明发生了cmci风暴,则执行cmci_toggle_interrupt_mode()关闭cmci功能,切换为轮询模式,通过轮询方式获取事件;

  1. 在非cmci风暴情况下,通过machine_check_poll(MCP_TIMESTAMP, this_cpu_ptr(&mce_banks_owned))函数获取并记录故障信息。

    参数1定义如下,MCP_TIMESTAMP表示会记录当前TSC:

enum mcp_flags {
    MCP_TIMESTAMP = BIT(0), /* log time stamp */
    MCP_UC = BIT(1), /* log uncorrected errors */
    MCP_DONTLOG = BIT(2), /* only clear, don't log */
};

machine_check_poll函数的主要功能是通过读取IA32_MCG_STATUS、IA32_MCi_STATUS寄存器信息和CPU的ip、cs等相关信息,然后对故障进行分类,将CE事件或其他类型的故障事件记录到/dev/mcelog。用户可以通过读取/dev/mcelog获取错误记录。

执行流程如下,过程说明在代码注释中:

bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
{
    if (flags & MCP_TIMESTAMP)
        m.tsc = rdtsc(); // 记录当前TSC
    /* CE Error记录 */
    /* If this entry is not valid, ignore it */
    if (!(m.status & MCI_STATUS_VAL))
        continue;
    /* 
     * If we are logging everything (at CPU online) or this 
     * is a corrected error, then we must log it. 
     */
    if ((flags & MCP_UC) || !(m.status & MCI_STATUS_UC))
        goto log_it;
    /* UCNA Error记录 */
    /* 
     * Log UCNA (SDM: 15.6.3 "UCR Error Classification") 
     * UC == 1 && PCC == 0 && S == 0 
     */
    if (!(m.status & MCI_STATUS_PCC) && !(m.status & MCI_STATUS_S))
        goto log_it;
    /* 通过mce_log记录故障信息 */
    log_it:
    /* 
     * Don't get the IP here because it's unlikely to 
     * have anything to do with the actual error location. 
     */
    if (!(flags & MCP_DONTLOG) && !mca_cfg.dont_log_ce)
        mce_log(&m);
    else if (mce_usable_address(&m)) {
        /* 
         * Although we skipped logging this, we still want 
         * to take action. Add to the pool so the registered 
         * notifiers will see it. 
         */
        if (!mce_gen_pool_add(&m))
            mce_schedule_work();
    }
}

总结一下,CMCI是MCA的一个增强特性,主要用于将硬件CE、UCNA等类型故障通过中断方式报告给软件,软件收到中断后,执行中断处理函数intel_threshold_interrupt(),采取IRQ模式或轮询模式记录错误信息到/dev/mcelog,用户态可以通过/dev/mcelog获取硬件故障信息。

参考文档:《Intel® 64 and IA-32 Architectures Software Developer’s Manual》

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
作者最新文章
硬件相关 Intel
相关文章 更多
显示器色温怎么调不刺眼?色温调多少看着最舒服
显示器色温怎么调不刺眼?色温调多少看着最舒服

详解显示器色温的舒适调节区间、刺眼的核心诱因,以及在不同使用场景与环境光下的具体调节步骤与校准方法。

显卡风扇不转怎么回事判断是否正常及解决方法
显卡风扇不转怎么回事判断是否正常及解决方法

发现显卡风扇不转先别慌,这很可能是正常的智能启停功能。本文详解如何区分待机静音与硬件故障,提供从软件检测到物理清理的完整解决思路。

笔记本加内存条后无法开机怎么办及解决方法
笔记本加内存条后无法开机怎么办及解决方法

笔记本加装新内存后遇到黑屏或无法开机?不要慌张,本文通过重新插拔、清洁金手指、单根测试等具体操作步骤,帮你快速判断是安装失误还是硬件不兼容,并给出相应解决办法。

电脑主机前置usb不能用怎么解决排查修复教程
电脑主机前置usb不能用怎么解决排查修复教程

针对电脑主机前置USB接口无法识别设备的问题,本文提供一套基于因果逻辑的排查流程。涵盖检查机箱内部USB针脚连接、验证BIOS中USB控制器状态、更新芯片组驱动以及排除供电不足等常见原因,帮助用户快速恢复接口功能。

无线鼠标充不进电解决办法及故障排查步骤
无线鼠标充不进电解决办法及故障排查步骤

遇到无线鼠标充不进电的问题,不要急于更换设备。本文详解从清理接口氧化层、更换数据线到检测电池电压的完整排查流程,帮助你判断是临时故障还是硬件损坏。

蓝牙游戏手柄连接教程吃鸡
蓝牙游戏手柄连接教程吃鸡

想知道如何用蓝牙手柄玩吃鸡游戏?本文详细讲解手机蓝牙手柄的连接步骤、主流映射软件的使用方法以及实战中的键位布局技巧,助你提升射击手感,同时解析外设玩家的匹配机制与注意事项。

游戏手柄蓝牙连接为何每次都要重连原因排查与解决方法
游戏手柄蓝牙连接为何每次都要重连原因排查与解决方法

本文深入分析游戏手柄蓝牙频繁断开且需重连的根本原因,涵盖电池电压检测、操作系统电源管理策略及驱动冲突。通过具体的系统设置调整和固件更新步骤,解决蓝牙握手失败问题,恢复手柄的稳定连接状态。

显示器画面模糊抖动怎么解决及排查方法教程
显示器画面模糊抖动怎么解决及排查方法教程

遇到显示器画面模糊或抖动时,可通过检查视频连接线、调整系统分辨率与刷新率、更新显卡驱动等步骤进行排查和修复。

小米智能门锁换电池后怎么开机
小米智能门锁换电池后怎么开机

小米智能门锁更换新电池后无法开机或屏幕不亮?本文详解电池极性检查、金属触点清洁及强制重启方法,帮你快速解决供电问题,让门锁恢复正常使用。

电视机声音怎么连接到外置音响
电视机声音怎么连接到外置音响

想让电视声音更震撼?本文详解如何通过HDMI ARC、光纤、蓝牙和3.5mm接口将电视连接至外置音响,包含具体设置步骤与常见问题排查,助你轻松打造家庭影院。

查看更多
精品专题 更多
装机必备
装机必备

正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

Windows
Windows

正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

PDF教程
PDF教程

正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

Mac软件 更多
Shapr3D macOS版
Shapr3D macOS版
Mac

Shapr3D是一款面向工业设计、机械工程、建筑概念和三维打印工作流的CAD软件。Mac版采用Parasolid建模内核,支持草图约束、实体建模、工程图、可视化渲染及常见CAD格式交换,并可通过账户在多台设备之间同步项目。

REAPER macOS版
REAPER macOS版
Mac

REAPER是Cockos开发的数字音频工作站,提供多轨音频与MIDI录制、剪辑、处理、混音和母带制作工具。Mac版兼容Intel与Apple芯片,支持AU、VST、VST3、CLAP等插件格式,并提供高度可定制的工作流程。

Ableton Live macOS版
Ableton Live macOS版
Mac

Ableton Live 是面向音乐制作人与现场表演者的数字音频工作站,提供编曲视图、独具特色的现场视图、音频录制、MIDI创作、实时变速、乐器及效果器。Mac版原生支持Apple芯片,并可连接音频接口、MIDI控制器和第三方插件。

WINDOWS 更多
3dmax(3ds max)
3dmax(3ds max)
Windows

Autodesk 3ds Max 是一款专业的三维建模、动画与渲染软件,广泛应用于建筑可视化、游戏开发、影视动画、广告设计和产品展示等领域。

photoshop
photoshop
Windows、macOS 、 iPad

Photoshop 2026 是 Adobe 推出的专业图像处理与视觉设计软件,支持 Windows、macOS 和 iPad 等平台,广泛应用于摄影修图、电商设计、平面海报、数字绘画及视觉合成等创作场景。

Blender
Blender
Windows、macOS 和 Linux

Blender 是一款免费开源、跨平台的专业 3D 创作软件,集建模、动画、渲染、视频编辑与视觉合成等功能于一体,广泛应用于影视动画、游戏设计和建筑可视化等领域。软件支持 Cycles 物理渲染器与 Eevee 实时渲染引擎,并提供多边形建模、骨骼绑定、物理模拟等专业工具。Blender 兼容 Windows、macOS 和 Linux 系统,安装包轻巧、运行流畅,依托活跃的全球开发者社区持续更新,是从初学者到专业创作者都值得选择的正版 3D 创作工具。