8. PCI Express高階錯誤報告驅動程式指南 HOWTO

作者:
版權:

© 2006 Intel Corporation

8.1. 概述

8.1.1. 關於本指南

本指南描述了PCI Express (PCIe) 高階錯誤報告 (AER) 驅動程式的基本知識,並提供瞭如何使用它以及如何使終端裝置驅動程式符合PCIe AER驅動程式的資訊。

8.1.2. 什麼是PCIe AER驅動程式?

PCIe錯誤信令可能發生在PCIe鏈路上,或代表在鏈路上啟動的事務。PCIe定義了兩種錯誤報告正規化:基線能力和高階錯誤報告能力。基線能力是所有PCIe元件必須具備的,它提供了一組最低限度的錯誤報告要求。高階錯誤報告能力透過PCIe高階錯誤報告擴充套件能力結構實現,提供更強大的錯誤報告功能。

PCIe AER驅動程式提供了支援PCIe高階錯誤報告能力的基礎設施。PCIe AER驅動程式提供三個基本功能:

  • 如果發生錯誤,收集全面的錯誤資訊。

  • 向用戶報告錯誤。

  • 執行錯誤恢復操作。

AER驅動程式只附著到支援PCIe AER能力的根埠和RCECs。

8.2. 使用者指南

8.2.1. 將PCIe AER根驅動程式包含到Linux核心中

PCIe AER驅動程式是透過PCIe埠匯流排驅動程式附著的根埠服務驅動程式。如果使用者想使用它,必須編譯該驅動程式。它透過CONFIG_PCIEAER啟用,而CONFIG_PCIEAER依賴於CONFIG_PCIEPORTBUS。

8.2.2. 載入PCIe AER根驅動程式

某些系統在韌體中支援AER。如果在韌體處理AER的同時啟用Linux AER支援,將導致不可預測的行為。因此,除非韌體透過ACPI _OSC方法將AER控制權授予作業系統,否則Linux不處理AER事件。有關_OSC用法的詳細資訊,請參閱PCI韌體規範。

8.2.3. AER錯誤輸出

當捕獲到PCIe AER錯誤時,錯誤訊息將輸出到控制檯。如果是可糾正錯誤,它將作為資訊訊息輸出。否則,它將作為錯誤訊息列印。因此,使用者可以選擇不同的日誌級別來過濾掉可糾正的錯誤訊息。

下面是一個示例:

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

在示例中,'Requester ID'表示向根埠傳送錯誤訊息的裝置的ID。其他欄位請參考PCIe規範。

8.2.4. AER速率限制

由於每次事務都可能生成錯誤訊息,我們可能會看到大量錯誤報告。為了防止垃圾裝置氾濫控制檯/阻塞執行,訊息會按裝置和錯誤型別(可糾正錯誤與非致命不可糾正錯誤)進行節流。致命錯誤,包括DPC錯誤,不受速率限制。

AER使用DEFAULT_RATELIMIT_BURST(10個事件)在DEFAULT_RATELIMIT_INTERVAL(5秒)內的預設速率限制。

速率限制以sysfs屬性的形式公開並可配置。請參閱ABI file testing/sysfs-bus-pci-devices-aer

8.2.5. AER統計/計數器

當捕獲到PCIe AER錯誤時,計數器/統計資訊也以sysfs屬性的形式公開,這些屬性已記錄在ABI file testing/sysfs-bus-pci-devices-aer中。

8.3. 開發者指南

為了啟用錯誤恢復,軟體驅動程式必須提供回撥函式。

為了更好地支援AER,開發者需要了解AER的工作原理。

PCIe錯誤分為兩類:可糾正錯誤和不可糾正錯誤。這種分類基於這些錯誤的影響,可能導致效能下降或功能失效。

可糾正錯誤對介面功能沒有影響。PCIe協議無需任何軟體干預或資料丟失即可恢復。這些錯誤由硬體檢測並糾正。

與可糾正錯誤不同,不可糾正錯誤會影響介面的功能。不可糾正錯誤可能導致特定事務或特定PCIe鏈路不可靠。根據這些錯誤條件,不可糾正錯誤進一步分為非致命錯誤和致命錯誤。非致命錯誤導致特定事務不可靠,但PCIe鏈路本身功能完全正常。另一方面,致命錯誤導致鏈路不可靠。

當啟用PCIe錯誤報告時,裝置在捕獲到錯誤時會自動向其上方的根埠傳送錯誤訊息。根埠在接收到錯誤報告訊息後,會在其AER能力結構中內部處理並記錄錯誤訊息。記錄的錯誤資訊包括將錯誤報告代理的請求者ID儲存到錯誤源識別暫存器中,並相應地設定根錯誤狀態暫存器的錯誤位。如果在根錯誤命令暫存器中啟用了AER錯誤報告,則根埠在檢測到錯誤時會生成中斷。

請注意,如上所述的錯誤與PCIe層次結構和鏈路相關。這些錯誤不包括任何裝置特定錯誤,因為裝置特定錯誤仍會直接傳送到裝置驅動程式。

8.3.1. 提供回撥函式

8.3.1.2. PCI錯誤恢復回撥函式

PCIe AER根驅動程式使用錯誤回撥函式,在執行錯誤恢復操作時,與相關層級中關聯的下游裝置驅動程式進行協調。

資料struct pci_driver有一個指向err_handler的指標,該指標指向由多個回撥函式指標組成的pci_error_handlers。AER驅動程式遵循PCI錯誤恢復中定義的規則,除了PCIe特定部分(例如reset_link)。有關回調函式的詳細定義,請參閱PCI錯誤恢復

以下章節詳細說明了何時呼叫錯誤回撥函式。

8.3.1.3. 可糾正錯誤

可糾正錯誤對介面功能沒有影響。PCIe協議無需任何軟體干預或任何資料丟失即可恢復。這些錯誤不需要任何恢復操作。AER驅動程式會相應地清除裝置的可糾正錯誤狀態暫存器並記錄這些錯誤。

8.3.1.4. 不可糾正(非致命和致命)錯誤

如果錯誤訊息指示一個非致命錯誤,則無需在上游執行鏈路復位。AER驅動程式呼叫error_detected(dev, pci_channel_io_normal) 來通知相關層次結構中的所有驅動程式。例如:

Endpoint <==> Downstream Port B <==> Upstream Port A <==> Root Port

如果上游埠A捕獲到AER錯誤,則該層次結構包括下游埠B和終端裝置。

驅動程式可以返回PCI_ERS_RESULT_CAN_RECOVER、PCI_ERS_RESULT_DISCONNECT或PCI_ERS_RESULT_NEED_RESET,具體取決於它是否可以恢復,或者AER驅動程式接下來是否呼叫mmio_enabled。

如果錯誤訊息指示一個致命錯誤,核心將向相關層次結構中的所有驅動程式廣播error_detected(dev, pci_channel_io_frozen)。然後,必須在上游執行鏈路復位。由於不同型別的裝置可能使用不同的方法來複位鏈路,因此AER埠服務驅動程式需要透過pcie_do_recovery()函式的callback引數提供復位鏈路的功能。如果reset_link不為NULL,則恢復函式將使用它來複位鏈路。如果error_detected返回PCI_ERS_RESULT_CAN_RECOVER且reset_link返回PCI_ERS_RESULT_RECOVERED,則錯誤處理進入mmio_enabled。

8.3.2. 常見問題

如果PCIe裝置驅動程式沒有提供錯誤恢復處理程式(pci_driver->err_handler等於NULL),會發生什麼?

附著在該驅動程式上的裝置將無法恢復。如果錯誤是致命的,核心將列印警告訊息。更多資訊請參考第3節。

如果上游埠服務驅動程式未提供回撥函式reset_link,會發生什麼?

如果錯誤是由附著在服務驅動程式上的上游埠報告的,則致命錯誤恢復將失敗。

8.4. 軟體錯誤注入

除錯PCIe AER錯誤恢復程式碼非常困難,因為很難觸發真實的硬體錯誤。基於軟體的錯誤注入可用於模擬各種PCIe錯誤。

首先,您應該在核心配置中啟用PCIe AER軟體錯誤注入,即您的.config中應該有以下項:

CONFIG_PCIEAER_INJECT=y 或 CONFIG_PCIEAER_INJECT=m

重啟新核心或插入模組後,應建立一個名為/dev/aer_inject的裝置檔案。

然後,您需要一個名為aer-inject的使用者空間工具,可以從以下地址獲取:

有關aer-inject的更多資訊可以在其原始碼文件中找到。