【58】PCIe錯誤處理機制是如何工作的

  向我最喜歡的對沖基金大佬-達里奧致敬,模仿《經濟機器是如何運行的》寫了一篇《PCIe錯誤機制是如何工作的》。文章主要介紹了主流的OS Native Model AER是怎麼工作的。至於另外一種模式:Firmware First Model,其實沒有啥好介紹的(主要是技術含量低,沒啥好說的),可以參考《【19】怎麼禁止PCIEAER的firmware first mode》。
公衆號分成4篇介紹,背景更詳細一些
https://mp.weixin.qq.com/s/hEK_b8l4VktwWeyqQNxF4A
https://mp.weixin.qq.com/s/Q2Nca9gLzunYLZMpMlG_Tw
https://mp.weixin.qq.com/s/NZT6CtKFyCRkTZ36r51fvA
https://mp.weixin.qq.com/s/2cWf-emOjWNzfnoWY2uQKA

1、 錯誤分類
在這裏插入圖片描述
  PCIe的錯誤可以分成兩類:不可修復錯誤和可修復錯誤,其中不可修復錯誤又可以細分爲致命和非致命兩種。
  可修復錯誤由硬件修復不需要軟件參與,並且修復行爲不會導致任何信息的丟失。軟件可以記錄錯誤發生的頻率。
  不可修復致命錯誤是鏈路或者硬件不可靠導致的,對於不可修復致命錯誤需要復位鏈路上的組件。不可修復致命錯誤,沒有統一的修復方法,每家都有自己的處理方法。平臺設計者需要根據硬件設計不同,PCIe器件承擔的作用不同,業務流程不同進行不同的處理,原則上都需要復位鏈路上的組件。
  不可修復非致命錯誤通常是事務層不可靠但是鏈路滿足要求導致的。
2、 錯誤上報
  PCIe Spec規定了3種錯誤上報機制:完成包狀態,帶內錯誤message,錯誤轉發(例如data poisoning)
(1) 完成包狀態
  只要完成包的狀態不是SC,就代表對應的請求失敗了。對於Non-posted的請求,只要completion包沒有返回,請求就沒有完成。
在這裏插入圖片描述
(2) 帶內error message
  Error message起源於Root Port或者Root Port下面的設備,最終路由到對應的Root Port。
在這裏插入圖片描述
在這裏插入圖片描述
  如果RootPort支持AER,RC從message中提取RequesterID字段,並記錄的Root port的Error Source Identification寄存器中,這個BDF號就是出錯的設備。不過很多時候這個BDF是捕獲不到的,或者出現多個錯誤,RC只能提取第一個錯誤的RequesterID。因此,需要driver遍歷Root Port下的所有設備,檢查哪些設備出現了錯誤。
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
  如果Root Port支持AER,則收到error message(根據error code可以分爲ERR_COR/ERR_NONFATAL/ERR_FATAL)或者Root port自己檢查到對應錯誤時,會記錄到Root Port的Root Error Status寄存器。
在這裏插入圖片描述
(3) 錯誤轉發(data poisoning)
  出現Data poisoning時,TLP的EP比特會置1。
在這裏插入圖片描述
3、 Error message控制
  Error message從PCIe設備產生到路由到對應Root Por涉及一系列的控制寄存器和狀態寄存器。
在這裏插入圖片描述
  Root Port下面的設備或Root Port本身發生PCIe錯誤想產生MSI中斷話,需要關注哪些寄存器呢?
A. 整條鏈路上所有bridge的Bridge ctrl reg的SERR# bit
  如果該bit沒有使能,則bridge不會往上游轉發下游的設備上報的error message。如果是Root port本身產生的錯誤的則不需要關注該bit。
在這裏插入圖片描述
B. 整條鏈路上支持DPC的設備(DP和RP)是否使能了DPC
  如果使能了DPC trigger enable,下游設備發送的ERR_FATAL或ERR_NONFATAL的error message會被DPC攔截。

在這裏插入圖片描述
C. 整條鏈路上的所有PCIe設備的Device ctrl reg的對應bit是否使能
  Device ctrl reg的低4bit是一個比較大的控制開關,分佈控制ERR_COR message、ERR_NONFATAL message、ERR_FATAL message和Unsupported
Request的發送。
在這裏插入圖片描述
D. Root port的Root error command reg對應bit是否爲1
  如果Root error command reg對應bit爲1,則Root port本身或者Root port收到下游設備上報錯誤時纔會產生中斷。
在這裏插入圖片描述
E. Root Port的Root ctrl reg對應bit是否清零
  如果Root ctrl reg對應bit沒有清零,則會走左邊的分支產生system error,對X86而言這是一條帶外的pin。
在這裏插入圖片描述
F. 整個鏈路上的PCIe設備error mask reg是否置1
  如果error mask reg爲1,則產生對應錯誤時,只會更新PCIe CAP的error status寄存器,不會產生error message。
在這裏插入圖片描述
在這裏插入圖片描述
G. Command寄存器的memory space enable bit和bus master enable bit是否爲1,interrupt disable是否爲1
  MSI中斷本質上是一個memory write請求,Command寄存器的memory space enable bit和bus master enable bit負責MSI中斷的產生和轉發。
Interrupt disable是禁止INTx中斷。由於,INTx優先級比MSI中斷要高,該bit需要禁止。
在這裏插入圖片描述
H. Root Port的MSI enable是否爲1
  Error message會路由到Root Port,如果想產生MSI中斷,root port的MSI enable bit需要爲1。
在這裏插入圖片描述
I. 一些特殊的reg
  由於每款芯片實現不一樣,有些芯片還有一些特殊的reg控制使用MSI中斷或者其他的中斷。根據具體芯片設置,這裏就不討論了。
4、 Linux kernel的AER是怎麼工作的
在這裏插入圖片描述
在這裏插入圖片描述
  Aer server和其他的PCIe server一樣,都是註冊給pci port bus driver。Port bus driver會調用aer_probe,aer_probe函數註冊了中斷服務函數和中斷線程,然後調用aer_enable_rootport來使能中斷。aer_enable_rootport其實就是清除error status reg,並且使能第3部分“Error message控制”提到的相關控制寄存器。
在這裏插入圖片描述
  中斷服務函數aer_irq就是讀取AER CAP中的status和source id 寄存器來確定是否產生了AER,收到的第一個錯誤message的id是多少,把status和id推到fifo中,然後就啓動線程。
在這裏插入圖片描述
在這裏插入圖片描述
  線程aer_isr從Root Port 開始walk_bus遍歷該root port下面的所有PCIe設備,讀取設備aer status寄存器和aer mask寄存器,如果status對應bit爲1且mask 對應bit爲0,則加入struct aer_err_info *e_info的數據結構中等待處理。
  由於kernel需要爲大多數使用者負責,追求通用性,導致aer的處理乏善可陳,就不在這裏介紹了。
  AER處理方面,需要考慮產品可靠性要求不同、單板設計不同、芯片在系統中承擔的角色等方面,通用性和可靠性不可兼得。Kernel要爲所有硬件服務,因此選擇了通用性。系統要想提高可靠性,就要適當犧牲通用性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章