沿一次回報保存錯誤證據

選擇步驟後,圖中對應的元件與下方解說會加上重點標示。完整圖與所有解說會持續顯示;也可用方向鍵切換步驟。

先走左上到右下的正常回報路徑,再看下方遮罩分支。DPC(Downstream Port Containment,下游連接埠隔離)在後文另行放大,不把兩條路徑畫成連續操作。

來源記錄狀態,符合條件時向 Root 回報;軟體先保存有效證據,再依規則清除。來源記錄狀態,符合條件時向 Root 回報;軟體先保存有效證據,再依規則清除。來源 Function:記錄錯誤狀態個別 Mask、Severity及適用回報控制Root:通知與來源紀錄Error Message →軟體保存兩端證據核對有效性與事件關聯狀態可保留,但本次不送訊息Log 是否更新依各自規則本例被 Mask 的錯誤

作者依本章案例繪製的證據關係圖。訊息來源識別與實體故障原因需依其他證據繼續判讀。

AER(Advanced Error Reporting,進階錯誤回報)提供錯誤狀態、回報控制及相關紀錄。本章先走正常的錯誤回報路徑,再解釋遮罩與 DPC 隔離如何改變軟體看到的資訊。

DPC
Downstream Port Containment,下游連接埠錯誤隔離

前情提要:Chapter 5 的交易識別用來解讀有效的 Header Log;Chapter 7 的通知概念用來理解 Root 端如何把事件交給軟體。

規格路線:Figure 6-1 的分類 → Status/Mask/Severity → Figure 6-3 的回報路徑 → Root 紀錄 → 保存與清除 → DPC 分支。

  1. 先核對結構版本及錯誤類別

    本章的主要算例使用非 Flit、無 Prefix 的條件;不能因 Base 版本較新而改套別種 Capability 布局。

    確認 AER Extended Capability 的版本與欄位布局,再依錯誤類型讀相關 Status。

    AER
    Advanced Error Reporting,進階錯誤回報

    Base 6.0 §6.2.1–§6.2.3/Figure 6-1,pp.669–673;Figure 7-154/Table 7-134,p.1112。

  2. 沿控制條件判斷這次回報

    這是本章特定錯誤案例的回報路徑;Unsupported Request、Advisory Non-Fatal 等另有規則。

    在本例中依 Status、個別 Mask、Severity 與回報 Enable 追蹤訊息。被遮罩的狀態仍有自己的保存規則。

    Base 6.0 §6.2.3.2.2、§6.2.6/Figure 6-3,pp.673、685;Figures 7-155–7-157,pp.1113–1117。

  3. 把來源端與 Root 紀錄配起來

    回報的 Requester ID 是定位線索;只有 Log 非零,尚不足以確認它屬於這次事件。

    保存 Root Error Status/Source ID,再回到來源 Function 的 Status 與有效紀錄;用 First Error Pointer 等欄位確認關聯。

    Base 6.0 §7.8.4.7–§7.8.4.11/Figures 7-160–7-164,pp.1121–1127。

  4. 先保存,再處理清除與隔離分支

    RW1C 表示讀取可得值、寫 1 清除相應狀態;清除前先保留需要的證據。DPC 的觸發與恢復依其專屬條件。

    保存相關狀態、Header Log、控制值及時間資訊,再依 RW1C 等存取規則清除已處理狀態。接著比較啟用 DPC 時的不同觀察。

    Base 6.0 §6.2.4.2/§6.2.7.1,pp.679–681、691;§6.2.11、§7.9.14,pp.694–697、1245–1254。

圖中元件

Root 端的回報紀錄

本圖從 Root 端通知連回來源 Function 的狀態與紀錄。

基本責任

錯誤分類、來源識別、有效紀錄與故障原因是沿途要核對的資訊,不能只用一個識別值概括。

1. 一個錯誤訊息,能告訴我們多少事情?

Correctable Error 表示協定可自行恢復的錯誤,仍可能降低效能;Uncorrectable Error 則影響功能,並分為 Non-Fatal 與 Fatal。Non-Fatal 不等於工作已成功,Fatal 也不是「一定已損壞某顆晶片」的硬體診斷。這些分類提供回報與處理政策所需的嚴重程度。

由近到遠整理錯誤證據
紀錄位置回答的問題證據限制
Function 的 Device Status/AER Status這個 Function 記錄了哪類偵測結果?不保證訊息已送達,也不是事件次數。
AER Mask/Severity/Device Control偵測時如何記錄與回報?事後讀值不一定等於事發當時設定。
Root Error Status/Source IDRoot Port 收到哪些類別,第一個回報者是誰?回報者不一定是造成根本問題的元件。
Header Log/First Error Pointer目前保存的錯誤對應哪個交易內容?有有效性、容量、封包模式與錯誤種類限制。
DPC Status是否已隔離下游,觸發原因是什麼?不能替應用工作判定成功或復原完成。

Advanced Error Reporting(AER)是在基本錯誤回報之外,提供個別錯誤狀態、遮罩、嚴重程度與相關紀錄的 Extended Capability。即使沒有找到 AER,也不能直接說「裝置沒有任何錯誤回報能力」。

分類與回報模型

§6.2.1–§6.2.4(pp.669–679);Figure 6-1(p.670)整理分類。個別錯誤的處理與預設分類要再讀 Tables 6-4、6-5(pp.685–691),不能只從名稱猜行為。

2. Status 有兩個 bit,為什麼只回報一個錯誤?

先依 Chapter 2 的 Extended Capability 清單找 ID=0x0001,再用 Figure 7-154 解 Header。下面是 Endpoint 03:00.0 的快照;AER base 剛好是 0x100,不是固定位置。假設先前紀錄已清理、設定自事件前保持不變,期間沒有其他錯誤,且沿途的錯誤訊息轉送已正確啟用。

Endpoint AER 的教學讀值
欄位與位置值閱讀入口
Header,0x100,32 bits0x00020001Figure 7-154
Uncorrectable Error Status,0x104,32 bits0x00044000Figure 7-155
Uncorrectable Error Mask,0x108,32 bits0x00040000Figure 7-156
Uncorrectable Error Severity,0x10C,32 bits0x00040000Figure 7-157
Advanced Error Capabilities and Control,0x118,32 bits0x0000100EFigure 7-160
Device Control,PCIe base+0x08=0x78,16 bits0x2816Figure 7-25

Header 表示 ID=0x0001、Version=2、Next=0;即使讀的是 Base 6.0,也不能自行套用只適合較新 Capability/Flit 的佈局。本例沒有 Flit 或 Prefix,因此 Version=2 符合條件。

Status 的 bit 14=1 是 Completion Timeout;bit 18=1 是 Malformed TLP。Mask bit 18=1、bit 14=0,因此這兩個已記錄的錯誤中,只有 Completion Timeout 未被遮罩:0x00044000 & ~0x00040000 = 0x00004000。這個運算只挑出本例的未遮罩狀態,還不是完整的回報判定演算法。

TLP
Transaction Layer Packet,交易層封包

個別錯誤被 Mask 時,Status 仍可設起來;但不會為該次錯誤發出 Error Message,也不會把它存進 Header Log、TLP Prefix Log 或 First Error Pointer。不能把「Mask=1」解成「沒有發生」,也不能把 Severity=Fatal 解成「無論 Mask 為何都必須送出 Fatal 訊息」。

本例 Severity bit 14=0,Completion Timeout 被設定為 Non-Fatal;bit 18=1,Malformed TLP 被設定為 Fatal,但後者已 Mask。Device Control bit 1=1 允許 Non-Fatal 回報,所以在本例前提下,Completion Timeout 產生 ERR_NONFATAL。Device Control bit 2 也開啟 Fatal 回報,仍不會解除個別 Malformed TLP Mask。這是明確設定後的快照,不宣稱 Severity 值是重設預設值。

完整通知還要經過沿途 Bridge 的轉送條件、Root Port primary interface 的傳送允許,以及 Root 端的中斷設定。實際查詢時,從 Figure 6-3 沿來源到 Root 的路徑檢查;不能只讀 Endpoint 的一個 Enable 就結案。Unsupported Request、Advisory Non-Fatal 等類型另有規則,不宜把本例簡化式照搬過去。

Status → Mask → Severity → 回報路徑

Figures 7-154–7-157/Tables 7-134–7-137(pp.1112–1117);Figure 7-25/Table 7-21(pp.958–962)。Mask 行為見 §6.2.3.2.2(p.673),回報路徑見 §6.2.6/Figure 6-3(p.685)、§6.2.8.1(p.692);Advisory Non-Fatal 另見 §6.2.4.3(p.682)。

4. Root Port 記錄 03:00.0,是否代表它就是故障來源?

先區分「送出錯誤訊息的 Function」與「造成根本問題的元件」。Root Error Source Identification 記錄第一個相應類別訊息的 Requester ID;例如 Endpoint 等不到讀取回覆而回報 Timeout,Root 看到 Endpoint 的 ID 並不奇怪。

Root Port 收到單一 Non-Fatal 訊息的快照
Root AER base=0x100 的位置值判讀
Root Error Command,0x12C0x00000002開啟 Non-Fatal 中斷回報。
Root Error Status,0x1300x00000024bit 2、bit 5=1;Multiple、Fatal、Correctable 均未設。
Error Source Identification,0x1340x03000000高 16 bits=0x0300,是第一個 Uncorrectable 訊息的 Requester ID。

(0x03000000 >> 16) & 0xFFFF = 0x0300,依一般 BDF 編碼解為 03:00.0。本例 Root AER 的中斷向量編號設為 0,因此完整 Status 的高位沒有額外數值。Root primary interface 的傳送條件也已滿足;若要斷言 CPU 實際收到中斷,還要確認 MSI/MSI-X 或 INTx 的傳送與平台路由,不能只憑 0x24。

BDF
Bus/Device/Function,匯流排、裝置與功能識別
MSI
Message Signaled Interrupt,訊息中斷
MSI-X
Message Signaled Interrupts Extension,表格式訊息中斷

Root Error Status 的更新不受 Root Error Command 或 Root Control 的值控制,但仍有前述 primary interface 傳送允許條件。假如後來又收到另一個 Uncorrectable Message,Multiple bit 會設起來,第一個 Source ID 仍保留;這個欄位不是完整的回報者清單。

Root 端的圖表路徑

Figure 7-162/Table 7-142(pp.1123–1124)→ Figure 7-163/Table 7-143(pp.1124–1126)→ Figure 7-164/Table 7-144(pp.1126–1127)。先看類別有效狀態,再決定要讀 Source ID 的哪半邊。

5. 為什麼不能一開始就把所有 Status 寫 1 清掉?

因為清除不只是讓畫面乾淨。當軟體清掉 FEP 所指的錯誤時,硬體可能更新下一筆 Header 與 FEP;若先清除再讀 Log,就可能把兩個時間點的資料拼成同一個事件。

  1. 先記下管理對象、時間與當時設定;保存相關 AER Status、Mask、Severity、FEP、有效 Log,以及 Root/DPC 的對應證據。
  2. 依 FEP 與能力確認 Log 的格式及有效範圍;若資料可能並行變動,重新核對關聯,不能假定多個 Register 的讀取是原子快照。
  3. 完成該筆紀錄處理後,才對相應 RW1CS bit 寫 1。若啟用 Multiple Header Recording,依 FEP 逐筆處理,再重新讀狀態。

前兩步是作者整理的蒐證方式;第三步的硬體清除語意來自規格。Base 6.0 建議在多筆 Header 記錄啟用且 FEP 有效時,不要清除 FEP 以外的 Status bit;規格也列有確定沒有 Header 紀錄的 masked error 例外。它不是一條「所有錯誤情境都一次寫固定遮罩」的操作口訣。

另外,清 PCI Status 不會連帶清 AER Status,反方向也一樣。對照不同紀錄時,須記下是哪個 Register 在什麼時候被清除。

清除會改變哪些證據

§6.2.4.2(pp.679–681,含註腳 108)說明多筆記錄與清除順序;§6.2.7.1(p.691)說明 PCI Status 與 AER Status 的獨立性。

6. 如果啟用 DPC,為什麼 Root 可能看不到原本的 ERR_NONFATAL?

以下換成另一個事件案例。02:01.0 的 DPC Extended Capability 位於 0x300;這是一個 Switch Downstream Port,不使用 Root Port Extensions。Downstream Port Containment(DPC)可在觸發後停止下游 PCIe 流量,使問題先被限制在受影響的分支。

DPC 的獨立事件快照
欄位與位置值由欄位得知的狀態
Header,0x300,32 bits0x0001001DID=0x001D、Version=1、Next=0。
DPC Control,0x306,16 bits0x000ATrigger Enable=10b;Interrupt Enable=1。
DPC Status,0x308,16 bits0x000BTrigger Status=1;Reason=01b;Interrupt Status=1。
DPC Error Source ID,0x30A,16 bits0x0300觸發訊息的 Requester ID。

Trigger Enable=10b 表示 Port 自己偵測到未遮罩的 Uncorrectable Error,或收到 ERR_NONFATAL/ERR_FATAL 時可觸發。Reason=(0x000B >> 1) & 3 = 1,所以本次原因是收到 ERR_NONFATAL;此時 Source ID 才具有這裡要用的意義。若 Reason=00b 表示 Port 自己偵測到錯誤,就不能照用 Source ID 猜來源。

觸發 DPC 的這個 ERR_NONFATAL 會被 Port 丟棄,不再往上游轉送。DPC 可另外以中斷或 ERR_COR 通知管理者,但本例 DPC ERR_COR Enable=0,只啟用 DPC 中斷;中斷是否到達仍要看向量與平台設定。因此不能要求 Root AER 一定同時出現上一節的 0x24 快照。

清掉通知後,Link 為什麼還沒有回來?

Figure 7-300 把 DPC Trigger Status 放在 bit 0,DPC Interrupt Status 放在 bit 3。兩者都能寫入 1 清除,但作用不同:bit 3 處理中斷狀態;bit 0 維持隔離,清除後才允許 LTSSM離開 Disabled,回到 Detect 嘗試建立 Link。

LTSSM
Link Training and Status State Machine,鏈結訓練與狀態機

【模擬資料】以下資料為教學用途建立,不代表特定硬體或平台。延續上方獨立的 DPC 事件:02:01.0 已收到來自 03:00.0 的 ERR_NONFATAL,DPC Status 讀為 0x000B。本例選擇先保存證據、只清中斷,再等待解除隔離的條件。到 Switch 的上游管理路徑仍可用,軟體經由這條路徑讀寫 Port 的設定空間;本次停用的是 02:01.0 到 03:00.0 的 Link。假設過程中沒有新的 DPC 事件,也沒有其他軟體同時寫入這個 Register。

同一 DPC Status 的兩次寫入,分別處理通知與隔離
動作與位置DPC Interrupt Status,bit 3DPC Trigger Status,bit 0後續行為
讀取 0x308,得到 0x000B11已記錄中斷與隔離事件;Reason=01b。
保存證據後,以 16-bit 寫入 0x0008 到 0x308清為 0維持 1本例再讀為 0x0003,Port 仍在 DPC。
符合釋放條件後,以 16-bit 寫入 0x0001 到 0x308本例維持 0清為 0回到 Detect 嘗試訓練;Reason 已無效,不指定整個 Register 的固定讀值。

這裡刻意拆成兩次寫入,讓通知與隔離的差別容易看清楚;規格沒有要求每套軟體都採這個拆法。真正必須遵守的是釋放條件。也因此,不能把讀出的 0x000B 原樣寫回,當成只清中斷的操作:那會同時對 bit 3 與 bit 0 寫 1,連隔離也一起釋放。

下圖的等待分支接到 §6.2.11:軟體必須先讀到 Link Status 的 Data Link Layer Link Active=0,才能釋放 DPC;若過早清除,結果為 undefined(規格未定義)。本例是 Switch Downstream Port,DPC RP Busy 不適用;支援 RP Extensions 的 Root Port 則還須等待該 bit 為 0。

先處理 DPC 中斷,再等 Link 停止後解除隔離本例先保存證據,只清 Interrupt Status。Link Active 仍為 1 時,Trigger Status 維持 1,繼續等待。讀到 Link Active 為 0 且軟體決定恢復後,才清 Trigger Status。Link 回到 Detect 嘗試訓練,裝置恢復仍在後面。保存 DPC 狀態與相關錯誤證據本例管理 Switch Downstream Port 02:01.0對 DPC Status 寫入 0x0008只清中斷狀態,Trigger Status 仍為 1讀取 Link Active是 0 還是 1?對 DPC Status 寫入 0x0001解除隔離,LTSSM 回到 Detect觀察 Link 重建,完成適用的就緒等待再恢復設定與裝置服務Link Active 仍為 1維持 Trigger Status=1等待後再讀取0,且軟體決定恢復1
作者整理的 Switch Port 軟體處理流程,並非 LTSSM 原始狀態圖。右側分支繼續等待;向下才會解除隔離。若換成支援 RP Extensions 的 Root Port,還須確認 DPC RP Busy=0。
LTSSM
Link Training and Status State Machine,鏈結訓練與狀態機

隔離期間又來一筆 Memory Read,誰回覆?

接著讀 §2.9.3 Transaction Layer Behavior During Downstream Port Containment。假設 Root Complex 送來一筆新的、格式合法的 Memory Read,原本應由 02:01.0 轉送到 03:00.0 的 BAR;它在 Port 已處於 DPC 時才提交給下游傳送路徑。這筆 Request 由 Port 丟棄,並由 Port 產生錯誤 Completion(交易回覆)。

BAR
Base Address Register,基底位址暫存器

為了知道回覆哪種錯誤,回到 Figure 7-299/Table 7-263:本例 DPC Control=0x000A,bit 2 的 DPC Completion Control=0,因此回覆 Completer Abort(CA,完成端中止);若該 bit=1,才改回 Unsupported Request(UR,不支援的要求)。此 Completion 的 Completer ID 是 Downstream Port 02:01.0,因為這次由它終止 Request;前面 DPC Error Source ID 的 03:00.0 則是觸發隔離訊息的回報者。

在這個情境中收到 CA,是 Port 依 DPC 規則產生的結果,無法據此宣稱 Endpoint 已接受或執行該次讀取。若換成隔離前就已送出的 Request,且 DPC 使 Completion 無法回來,本例沒有 Root Port Extensions 的代回覆機制,Requester 仍可能遇到 Completion Timeout。新的 Request 如何被終止,與舊 Request 是否已完成,要分別追蹤。

解除隔離後,還有哪些恢復工作?

Table 7-264 說明,清除 DPC Trigger Status 後,Port 離開 DPC,LTSSM 必須回 Detect。這只是重新嘗試訓練;接著還要觀察 Link 與 Data Link 恢復,並依 §6.6.1 遵守 Conventional Reset(一般重設)之後首次 Configuration Read 的適用時序,才能繼續恢復設定與驅動程式。等待條件連回 Chapter 9,不在這裡重複全部 Reset 流程。

解除隔離也會改變紀錄的判讀條件:DPC Trigger Status=0 後,DPC Trigger Reason 已不再有效,應使用先前保存的快照分析本次事件。規格允許在釋放要求已滿足後清除 Trigger Status,不必等所有相關錯誤 Status 都變成 0;因此,清空整片錯誤紀錄並不是恢復的必要前提。裝置如何重建工作、處理先前在途資料及恢復應用服務,則仍須裝置、驅動與平台的恢復程序。

從欄位、隔離中的交易,到釋放條件

依據 PCI Express Base Specification Revision 6.0。Figure 7-300 DPC Status Register/Table 7-264、§7.9.14.4(PDF/印刷 pp.1252–1253)定位 Trigger Status、Interrupt Status、Reason 有效條件與適用的 RP Busy。接 §6.2.11 Downstream Port Containment (DPC)(p.694),閱讀必須等 Link Active=0 才可釋放的要求;DPC 中斷條件見 §6.2.11.1 DPC Interrupts(p.697)。隔離期間 Request 的處理依 §2.9.3 Transaction Layer Behavior During Downstream Port Containment(p.262),再回 Figure 7-299 DPC Control Register/Table 7-263、§7.9.14.3(pp.1250–1251)查 DPC Completion Control。訊息來源欄位依 Figure 7-301/Table 7-265、§7.9.14.5 DPC Error Source ID Register(pp.1253–1254)。釋放後首次設定存取依 §6.6.1 Conventional Reset(pp.721–723)。上述 PDF 與印刷頁碼相同;本例的軟體處理順序是作者示範。

7. 先保存,再逐項解讀錯誤

AER Status=0,是否足以證明從開機至今都沒有錯誤?

不足。紀錄可能已被清除或重設,部分欄位也取決於實作與偵測條件。應先確認蒐證時間範圍與清除紀錄。依據:§6.2.4.2、Table 7-135。

FEP=14,但 Status bit 14 已清除,仍可把 Header Log 當成最新 Timeout 嗎?

不可以。FEP 此時無效;Log 看起來合理並不能補足有效性條件。依據:§6.2.4.2、Table 7-140。

DPC Source ID=03:00.0,能否斷言 03:00.0 的硬體必須更換?

不能。先確認 Trigger Reason 允許解讀 Source ID;即使有效,也只識別觸發訊息的回報者。還需交易、相鄰元件與平台證據才能判斷原因。依據:Table 7-265。