【75】PCIe错误的Firmware first model和OS native model

    之前写过一篇怎么禁止Firmware first model的文章,感觉内容组织得有点混乱,本来想删了重新写,看到有人收藏了,索性新写一篇吧。

公众号 PCIe 错误的FFM 和 OS Native Model

1、PCIe错误的Firmware first model和OS native model

1.1 Firmware first model

    错误通过SMI中断到CPU,CPU进入SMM(system management mode),并调用BIOS/firmware注册handler,BIOS/firmware先收集故障信息,把错误信息填写到APEI表,然后通过SCI或者NMI通知OS。详细流程可以参考APCI spec。一般服务器会选择这种方式,因为这种方式可以通过BIOS把错误报给BMC,从而通过页面显示错误。

18. ACPI Platform Error Interfaces (APEI) — ACPI Specification 6.5 documentation

注意这种方式会让CPU进入SMM(system management mode),关于SMM,intel 64 and IA-32 architecture software developer's manual 的30.1章有介绍

1.2 OS native model

    错误通过MSI或者NMI方式直接报告给OS,OS对应的handler获取错误信息。

1.2.1 NMI方式上报错误

    传统的PCI设备检测到address phase parity error,会assert SERR#,检测到data phase error,会assert PERR#。PERR#和SERR#信号连接到南桥里(现在叫PCH)的error logic。错误发生时,error logic会assert NMI信号通知CPU。。

    PCH(之前的南桥)内部设备或者PCH下面的设备的错误会触发SERR#,error logic会assert NMI信号,产生NMI中断到CPU,通知OS处理错误。

1.2.2 MSI方式上报错误

    PCIe设备出现错误时会产生对应的error message(endpoint、switch、RP出现错误时都会产生error message),error message会路由到Root port,Root Port产生MSI中断到CPU,通知OS处理错误。

2、选择那种模式呢

    Linux PCIEAER service的作者在《Enable PCI Express Advanced Error Reporting in the Kernel》进行了一些说明。

    在2.6.18之前的kernel,linux kernel没有root port AER service的驱动。BIOS提供了基础的错误机制,但是这种机制不能配合相应设备得到更详细的错误信息,更重要的没有recovery的功能,因此linux kernel引入的AER driver。

2.1 SMI上报错误

    如果在日志中发现下面打印"Hardware Error........",就是使用firmware first model。

从日志中可以看到linux没有优化流程前(椭圆中的日志是优化后的打印)对于correctable的错误,只能看到Root port接收到了correct错误,至于是什么错误,哪个设备出错了是看不到的,缺乏定位能力。

新版本的linux对这个流程进行了优化(新增了椭圆中的日志),会调用PCIeAer service的接口把错误信息打印出来。具体实现见ghes_proc-> ghes_do_proc-> ghes_handle_aer-> aer_recover_queue->

aer_recover_work_func-> cper_print_aer

    至于uncorrectable error会导致系统panic。Linux kernel中具体实现见ghes_proc-> __ghes_panic。

2.2 NMI上报

    如果在日志中发现下面打印NMI: PCI system error......,就是使用了NMI上报。这个是里面没有任何定位信息,PCH内部PCI设备及其PCH下面的PCIe设备出现错误都有触发该流程(做项目时真实遇到过PCH报错

走到这个流程,我在pci_serr_error增加了定位信息,把Aer service的流程移植到pci_serr_error,发现PCH报错)。

具体实现见default_do_nmi->pci_serr_error

2.3 MSI上报

想让AER通过MSI上报需要在cmdline增加pcie_ports=native,剩下的就是把整个链路上的ctrl reg打通(一般设置了pcie_ports=native,bridge的对应reg会被打通。endpoint设备调用pci_enable_pcie_error_reporting:写device ctrl reg使能EP设备的PCIe错误上报就可以了

见:【58】PCIe错误处理机制是如何工作的_pcle错误_linjiasen的博客-CSDN博客

sudo vim /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash pcie_ports=native"

update-grub

    如果在日志中发现下面打印,就是使用了MSI上报。具体流程见aer_irq -> aer_isr-> aer_isr_one_error-> aer_process_err_devices-> aer_print_error。

    firmware first model和os native model没有优劣之分,需要根据自己的项目做取舍。一般来说,服务器这类对可靠性要求不高的场景会选择firmware firmware model,让错误通过BMC显示在界面上,

而存储这种对可靠性要求高的场景会选择os natvie model,并且有实力的存储厂商会禁止linux kernel自带的pci service,改用自研的PCIe driver。

3、怎么禁止firmware first model

    禁止firmware first model涉及到芯片厂商特有的寄存器,每家厂商实现方式不同,这里说一下intel和AMD相关的寄存器。

    Intel的架构图和芯片手册比较清楚地说明了miscctrlsts_1和miscctrlsts_0对应bit可以覆盖PCIe标准配置空间的寄存器。miscctrlsts_1的bit3-1清零,防止miscctrlsts_1覆盖了root ctrl reg对应bit。miscctrlsts_0的bit4也需要清零,防止MSI和INTx中断被disable。

找到对应root port(17:0.0),可以使用setpci临时修改miscctrlsts_1和miscctrlsts_0 reg

至于PCIe标准配置空间的寄存器,只要加载AER service,驱动会使能对应的寄存器。

  AMD是没有架构框图说明哪些寄存器可以禁止firmware first model,经过试验发现下面的寄存器清零可以禁止firmware first model。

IOHCRASx0000017C (IOHC::PCIE0PortASerr_ACTION_CONTROL)

到IOHCRASx00000378 (IOHC::PCIE1PortHParityErr_ACTION_CONTROL)清零

  • 3
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

linjiasen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值