本文翻译自内核文档:linux\Documentation\PCI\pcieaer-howto.txt
《 PCI Express高级错误报告驱动程序指南》 HOWTO
T.Long Nguyen
张衍民
2006年7月29日
目录
1.概述
1.1关于本指南
1.2版权所有(C)英特尔公司2006。
1.3什么是PCI Express AER驱动程序?
2.用户指南
2.1将PCI Express AER根驱动程序包含到Linux内核中
2.2加载PCI Express AER根驱动程序
2.3 AER错误输出
3.开发人员指南
3.1配置AER capability structure
3.2 提供回调
3.2.1回调reset_link用于重置PCI Express链接
3.2.2 PCI错误恢复回调
3.3 助手功能
3.3.1 int pci_enable_pcie_error_reporting(struct pci_dev * dev);
3.3.2 int pci_disable_pcie_error_reporting(struct pci_dev * dev);
3.3.3 int pci_cleanup_aer_uncorrect_error_status(struct pci_dev * dev);
3.4常见问题
4.软件错误注入
本指南介绍了PCI Express Advanced错误的基础知识。
介绍报告(AER)的驱动程序,并提供有关如何使用它的信息,例如如何启动端点设备的驱动使其适用于PCI Express AER驱动程序。
PCI Express错误信号可能会在PCI Express链接本身上发生或链路上产生了某些指示错误的传输事务。
PCI Express定义了两个错误报告范例:基准capability和高级错误报告功能(AER capability)。基准能力是
所有PCI Express组件必选的,提供最低要求的一组错误报告。
高级错误报告(AER)可实现基准功能的扩展,提供了更强大的错误报告能力。
内核的PCI Express AER驱动程序提供了支持AER功能的基础软件架构。
PCI Express AER驱动程序提供以下三个基本功能:
注意:AER驱动程序仅支持PCI-Express AER的根(RC)端口。
PCI Express AER根驱动程序是根端口驱动程序的一部分。如果用户想使用它,这部分驱动编译进内核。
选项CONFIG_PCIEAER支持此功能。它依赖于CONFIG_PCIEPORTBUS,所以请设置CONFIG_PCIEPORTBUS = y并
CONFIG_PCIEAER = y。
某些系统在firmware中已经包含了对AER支持。同时启用Linux AER支持,可能会导致firmware处理AER的同时,产生不可预测的
行为。因此,除非固件通过ACPI _OSC方法将AER控制权授予OS,否则Linux不会处理AER事件。
参见PCI FW 3.0有关_OSC使用情况的详细信息规范。
当捕获到PCIe AER错误时,错误消息将输出到console。
如果是可纠正的错误,则将其作为警告输出(warning)。
否则,将其打印为错误(error)。因此用户可以选择不同的日志级别以过滤出可纠正的错误消息。
下面显示了一个示例:
0000:50:00.0: PCIe Bus Error: severity=Uncorrected (Fatal), type=Transaction Layer, id=0500(Requester ID)
0000:50:00.0: device [8086:0329] error status/mask=00100000/00000000
0000:50:00.0: [20] Unsupported Request (First)
0000:50:00.0: TLP Header: 04000001 00200a03 05010000 00050100
在示例中,“RequesterID”是指发送信息到根端口的设备的ID。请请参阅PCI Express specs其他领域。
要启用AER感知支持,需要使用软件驱动程序对AER capability structure进行配置并提供回调接口。
为了更好地支持AER,首先,开发人员需要了解AER的工作原理。
PCI Express错误分为两种类型:可纠正的错误和不可纠正的错误。
此分类的依据是基于这些错误中,是否会导致性能或功能下降。
可纠正的错误不会对功能接口造成影响。 PCI Express协议无需任何软件干预即可恢复,且不会有任何数据丢失。
完全由硬件检测到并纠正这些错误。与可纠正错误不同,不可纠正错误会影响接口的功能。
无法纠正的错误可能导致特定的事务或链接变得不可靠。
根据这些错误情况,无法纠正错误进一步分为非致命错误和致命错误。
非致命错误会导致某些事务不可靠,但是PCI Express链接本身可以正常使用。
致命错误会导致链接不可靠。
启用AER后,PCI Express设备检测到错误产生后将把错误消息自动发送到其上方的PCIe根端口。
一根端口,在收到错误报告消息后,内部处理错误消息。并将其记录在其PCI Express capability中。
记录的错误信息包括:存储错误报告的请求者ID,并设置相应的根节点错误寄存器位。
如果在根端口的错误命令寄存器中启用了AER错误报告,当错误被检测到后会产生一个中断请求。
请注意,上述错误与PCI Express 架构和连接有关。
这些错误不包括任何特定于设备的错误,因为特定于设备的错误仍将直接发送到设备驱动程序。
PCI Express组件的AER感知驱动程序需要配置设备控制寄存器以启用AER支持。
驱动程序也会配置AER的capability 寄存器,包括掩码(mask)和严重性(severity)寄存器。
函数pci_enable_pcie_error_reporting可用于启用AER。具体参见第3.3节。
在发生致命错误的情况下,此回调用于重置pci express物理链接:
根端口aer服务驱动程序提供了一个默认的reset_link函数,但不同的RC控制器可能有不同的方式来重置PCI Express链接,因此所有上游端口应提供自己的reset_link函数。
在struct pcie_port_service_driver中,新的指针reset_link已经被添加(控制器驱动程序需要对其赋值)。
pci_ers_result_t(* reset_link)(struct pci_dev * dev);
第3.2.2.2节提供了有关reset_link何时被调用的更多详细信息。
执行错误恢复操作时,PCI Express AER根驱动程序使用错误恢复回调对下游设备驱动程序进行协调。
数据结构pci_driver具有指向err_handler的指针
pci_error_handlers由几个回调函数组成的。
AER驱动程序遵循定义在pci-error-recovery.txt中的规则要求,除了pcie特定的部分(例如reset_link)。
详细信息,请参考pci-error-recovery.txt对回调的定义。
以下各节介绍何时调用错误回调函数。
3.2.2.1可纠正的错误
可纠正的错误不会对功能接口造成影响。 PCI Express协议无需任何软件干预即可恢复,且不会有任何数据丢失。
这些错误不需要任何恢复操作。 AER驱动程序会清除设备的可纠正的错误状态,并相应地注册并记录这些错误。
3.2.2.2不可纠正(非致命和致命)错误
如果错误消息指示非致命错误,上游端口是不需要执行link reset的。
AER驱动程序会调用error_detected(dev,pci_channel_io_normal)到层次结构中关联的所有有问题的驱动程序。
例如,
端点<==>下游端口B <==>上游端口A <==>根端口。
如果上游端口A捕获AER错误,则层次结构包括下游端口B和EndPoint。
驱动程序可能会返回PCI_ERS_RESULT_CAN_RECOVER,
PCI_ERS_RESULT_DISCONNECT或PCI_ERS_RESULT_NEED_RESET,
具体取决于是否可以恢复还是AER驱动程序接下来调用mmio_enabled。
如果错误消息指示致命错误,则内核将广播error_detected(dev,pci_channel_io_frozen)到系统中所有有问题的驱动程序。
然后,在上游执行link reset是有必要的。由于不同类型的设备可能会使用不同的函数实现来重置链接,需要AER端口服务驱动程序提供重置链接的函数接口。首先,内核寻找上游组件具有aer的驱动程序。如果有,内核使用aer驱动程序的reset_link回调。
如果上游组件没有aer驱动程序并且该端口是下游端口,我们通过设置桥接器控制的次级总线复位位来将执行hot reset。
至于上游端口,他们应该使用自己的aer服务驱动程序提供reset_link函数。
如果error_detected返回PCI_ERS_RESULT_CAN_RECOVER和reset_link返回PCI_ERS_RESULT_RECOVERED,错误处理
将启用mmio_enabled。
pci_enable_pcie_error_reporting使设备能够发送错误
检测到错误时将消息发送到根端口。注意设备(ep device)默认情况下不启用错误报告,因此设备驱动程序需要
调用此功能将其启用。
pci_disable_pcie_error_reporting禁止设备发送错误
检测到错误时将消息发送到根端口。
pci_cleanup_aer_uncorrect_error_status 清除无法纠正的错误状态寄存器。
问:如果PCI Express设备驱动程序不提供错误恢复处理程序(pci_driver-> err_handler等于NULL)会怎么样?
答:驱动程序附带的设备将无法恢复。如果错误是致命的,内核将打印出警告消息。请参阅第3节以获取更多信息。
问:如果上游端口服务驱动程序不提供回调reset_link会怎样?
答:如果错误是由服务驱动程序连接的上游端口报告的,则致命错误将无法恢复。
问:此基础架构如何处理非PCIe驱动程序?
答:发生错误时此基础架构会调用驱动程序的错误回调函数。
但是如果驱动不是用于PCI Express的,设备可能不会将自己的错误报告给root端口。
问:该驱动程序需要进行哪些修改才能使其兼容PCI Express AER根驱动程序?
答:它可以调用帮助程序函数以在设备中启用AER,并清理不可纠正的状态寄存器。请请参阅第3.3节。
调试PCIe AER错误恢复代码非常困难,因为它很难触发真正的硬件错误。基于软件的错误注入可用于伪造各种PCIe错误。
首先,您应该在内核中启用PCIe AER软件错误注入
配置,即以下应位于您的.config中的项目。
CONFIG_PCIEAER_INJECT = y或CONFIG_PCIEAER_INJECT = m
使用新内核重新启动或insmod模块后,名为设备文件
/ dev / aer_inject 会被创建。
然后,您需要一个名为aer-inject的用户空间工具,
该工具可以从此获取: http://www.kernel.org/pub/linux/utils/pci/aer-inject/
有关aer-inject的更多信息可以在连接中的文档及其源代码中找到。