2020年5月25日 星期一

原理PCI Express: Advanced Error Reporting(AER)

Advanced Error Report(簡稱AER)為PCIe 較為強健的錯誤回報機制,在PCI Express®Base Specification Revision 3.0 的6.2節"Error Signaling and Logging"章節有詳細的介紹整個AER的logging與repoting機制,由於工作上常常遇到Linux Kernel log中,出現AER error訊息,所以又把spec拿出來翻一翻,藉此寫一篇關於AER的機制,方便以後查詢,以下就是我對於spec的理解與淺見,如果有誤的地方還望指正。



 Error Classification

PCIe的error主要可以分為Uncorrectable ErrorsCorrectable Errors,Uncorrectable Errors又可以進一步分為類為FatalNon-Fatal
  1. Correctable Errors: 這類的errors表示hardware可以自我修復,且不需要軟體的介入。舉例來說,當Receiver接收到TLP封包後,會在Data Link Layer進行LCRC檢查,當檢查發生錯誤,Receiver會initial NAK DLLP來告知Transmitter,此時Transmitter會再重新傳送發生錯誤的TLP,這就是透過retry機制來recover PCIe link。
  2. Uncorrectable Errors: 這類的errors分為為Fatal和Non-Fatal,Fatal Error表示hardware無法自我修復,此時必須reset整個link回到最初的狀態,重新link training。Non-Fatal則是提供給System software,有機會不透過reset link來recover error。


 Error Signaled

Error 傳送的方法可以分為三種 (1) Completion status, (2) Error Message和 (3) Error Forwarding,由於以下篇幅都是介紹第二種方法居多,1和3就不再贅述。

Error Message是透過Transaction Layer章節裡面所定義的Message Request的形式來傳送(如下圖)。


Error Message分為ERR_COR, ERR_NONFATALERR_FATAL,分別對應Correctable Error、Non-Fatal Uncorrectable Error和Fatal Uncorrectable Error。而這些message要怎麼分別呢?主要由Code欄位和Routing欄位來區分,根據下圖每一個error message都有固定的code encoding,然後routing欄位固定為000b,代表這些message的都是Routed to Root Complex


■ Error logging

如果device沒有support AER capability,產生error只會記錄在Device Status register來代表有error被偵測到。如果有support AER capability,則會將error記錄在Uncorrectable Error Status registerCorrectable Error Status register上,這兩個status register可以提供software去更精準的分辨問題種類和嚴重程度(severity) 。這兩個register分別都有對應的Mask register,可以更細部的去控制任何一種error type是否往上report Error Message。








■ Error Source Identification

如果是Root Port 或是 Root Complex Event Collector這類的device會收集他分支下面的device所產生的errors,就必須要有Error Source Identification register來記載這這些device的source id(由bus, device, function number所組成),如下圖所示,bit 0-15為Root Port(or Root Complex)第一次接收到correctable error的device source id,bit 16-31則為第一次接收到uncorrectable error的device source id。


另外Root Port或Root Complex Event Collector 如果support AER的話,就必須要實做"Root Error Status register",這個register用來顯示是否有接收到device產生或自己內部產生的correctable和uncorrectable error。


■ Interrupt Generation

Root Error Command Register 可以用來控制Uncorrectable Error和Correctable Error的reporting是否要產生Interrupt


而產生interrupt的方式有兩種,一種是透過I/O APIC,另外一種則是透過MSIMSI-X

當透過I/O APIC產生interrupt必須要滿足兩個條件,
  1. PCI Configuration Space裡的Command registerInterrupt Disable bit必須為0(表示enable intx)
  2. Root Error Command register裡面有任何一個bit被設置為1(表示接收到底下的device所傳送error message)
當透過MSI、MSI-X來產生interrupt,也必須滿足兩個條件,
  1. 所使用的Interrupt Vector並沒有被masked,而MSI/MSI-X所使用的interrupt vector會被program在Root Error Status register[31:27]
  2. Root Error Command register裡面有任何一個bit被設置為1

當以上兩種方法的兩個條件都符合後,Root Port會在error發生時產生interrupt送給CPU,然後執行Error Report的ISR(Interrupt Service Routine)。

■ Advisory Non-Fatal Error Logging

在某些情況下,偵測到error的device並不適合去決定這個error是否沒有辦法被recover。舉例來說,當system software發起了一個configuration read給不存在的device,這個request會得到completion(TLP) with Unsupported Request (簡稱UR) bit set,並且發起error通知system software,但是software並不需要為了這種情況發起ERR_NONFATAL的message,而且在某些platform發起ERR_NONFATAL可能會造成系統崩潰。

因此,PCIe spec定義了Advisory Non-Fatal Error的logging機制,讓某些ERR_NONFATAL的情況,使用ERR_COR替代。

要如何才能符合Advisory Non-Fatal Error Logging的條件,主要有三點:
  1. Uncorrectable Error的severity必須要是non-fatal,也就是對應的Uncorrectable Error Severity register bit要為0(如下圖)
  2. Error的case必須符合6.2.3.2.4 Advisory Non-Fatal Error Case的其中一個,由於case太多就沒有一一介紹
  3. Correctable Error Status registerAdvisory Non-Fatal Error Status bit被設為1,表示有Advisory Non-Fatal Error的產生,且Mask bit in Mask register沒有被設置,這樣就能符合Advisory Non-Fatal Error Logging的條件

■ Device Error Signaling and Logging 流程圖:

下圖為整個Error Reporting的機制,主要分為三個部份來介紹,


1. 藍色框框所框起來的區域,代表如果沒有support AER Capabilities,那error僅僅會記錄在Device Status Register

2.圖中紅色箭頭的部份,為Uncorrectable Error的流程
  • (1)查詢這個error在Uncorrectable Error Severity register對應的bit被設定為fatal或non-fatal,並且將Device Status Register的fatal或non-fatal bit設為1,表示error的發生。
  • (2)如果error符合advisory non-fatal error case章節的case的話,則使用ERR_COR message替代掉ERR_NONFATAL來report error。
  • (3)如果error是Unsupported Request(UR),則在Device Status Register的UR bit設為1來代表UR的發生。
  • (4) 設置對應的Error Status bit到Uncorrectable Error Status register
  • (5) 如果Uncorrectable Error Mask register對應的bit被設置,代表不會往上回報error message TLP。
  • (6) 這個步驟有幾個開關必須要被打開,才會啟動report機制,
    • 首先為Device Control registerUnsupported Request Reporting Enable bit,這個bit只有控制UR的report or not。
    • 第二為Command Register的SERR# Enable bit。
    • 第三為Device Control register的fatal error report enable bit和non-fatal error report enable bit。
3. 圖中橘色箭頭的部份,為Correctable Error的流程
  • (1)如果沒有support AER capabilities,則只會設置Device Status register的Correctable Error Detect bit來代表偵測到error的發生。
  • (2) 在advisory non-fatal error case章節有提到,有些case會report UR為advisory non-fatal error,如果是這類error,則在Device Status register設置UR bit。
  • (3)如果support AER,設置對應的Error Status bit到Correctable Error Status register 來代表偵測到error的發生。
  • (4)如果Correctable Error Mask register對應的bit被設置,代表不會往上回報error message TLP。
  • (5) 這個步驟有幾個開關必須要被打開,才會啟動report機制,
    • 首先為Device Control registerUnsupported Request Reporting Enable bit,這個bit只有控制UR的report or not。
    • 第二為Device Control registerCorrectable Error Reporting Enable bit。

 Find out the offset of AER Capability:

尋找AER Capability offset之前,要先從PCIE Extended Capability開始講起。

PCIE Extended Capability通常從Configuration Space的offset 100h開始,然後以Extended Capability header做為開頭(如下圖)。
  • [15:0]為Extended Capability ID,Capability種類如下面表格所展列
  • [19:16]代表版本號,
  • [31:20]為下一個Capability的offset。



Extended Capability ID
Capability Type
 0001h
Advanced Error Reporting Extended Capability
 0002h
Virtual Channel Extended Capability implemented in a device without an MFVC structure
 0003h
Serial Number Extended Capability
 0004h
Power Budgeting Extended Capability
 0005h
Root Complex Link Declaration Extended Capability
 0006h
Root Complex Internal Link Control Extended Capability
 0007h
Root Complex Event Collector Endpoint Association Extended Capability
 0008h
Multi-Function Virtual Channel (MFVC) Extended Capability
 0009h
Virtual Channel Extended Capability implemented in a Multi-Function device with an MFVC structure
 000Ah
RCRB Header Extended Capability
 000Bh
Vendor-Specific Extended Capability


下圖為尋找Capability的範例,我們使用lspci來dump 03:00.0這個device的registers,由圖中可以看出第一個Extended Capability (100h的位置) 為Advanced Error Reporting Extended Capability(ID為 0001h),然後下一個Extended Capability的offset為13Ch,由13Ch的ID 0003h可以得知它是Serial Number Extended Capability,以此類推。



當找到AER Capability,可以由下圖找到它對應的register的offset,如Uncorrectable Error Status Register offset為04h,Uncorrectable Error Mask Register為08h,以此類推。

以上圖為例,可以看到110h的地方為Correctable Error Status Register,且bit13為1,表示device有發生過Advisory Non-Fatal Error。





Reference: PCI Express®Base Specification Revision 3.0 November 10, 2010



解答區:
(1)


(2)
此trace為我們故意讓device所發的memory read TLP收不到root port回覆的completion TLP,因此device會同時偵測到Uncorrectable Error的"Completion Timeout"和"ECRC Error Status"並且反應到Uncorrectable Error Status register,接著device就會發出ERR_NONFATAL的message TLP給上一層的root port,rounting欄位為To Root Complex





26 則留言:

  1. Blog主,你好,小弟最近也在處理AER的Error,
    但我看這篇文章有點看不懂,有幾個問題想請教:
    1.100h指的是指圖片中f0下面的100嗎?
    2.為什麼下一個Extended Capability的offset是13ch?
    3.110h是指圖片中的110嗎?(f0→100→110,直的看)
    4.接上一個問題,如果是,bit13又是在哪裡?
    我看110這一行都是00 20 00 .....a0...00,
    我沒看到1這個數字,還請您解釋一下

    回覆刪除
    回覆
    1. 你好,
      問題1&3: 你指的應該黑色圖片中,用lspci dump的configuration space,100h是圖片中的100位置沒錯,lspci這工具沒標示而已,h只是用來表示說是16進制(Hexadecimal),所以應該如下
      f0h:
      100h:
      110h:
      ...
      ...
      1f0h:
      200h:

      問題2: 因為x86系統的memory擺放方式是little endian,也就是低位元低放,所以如文章中的Figure7-31對應到黑色圖,應該要把register反過來看(如下)

      100h: 01 00 c1 13
      => 13c10001 h

      Capability ID為bit 0~15 = 0001h
      Capability version為bit 16~19 = 1h
      Next Capability Offset為bit 20~31= 13ch

      問題4:
      如文中Figure7-32,Correctable Error Status Register為offset 10h,但由於AER base是用100h開始,所以正確位置為100h+10h=110h,那如問題3所解釋little endian(如下)

      110h: 00 20 00 00
      => 00002000h <- (bit 13為1)

      刪除
    2. 補充一下,16進制要轉成2進制看,用結尾b代表2進制
      110h: 00 20 00 00
      => 00002000h <- (bit 13為1)
      => 0000 0000 0000 0000 0010 0000 0000 0000b

      刪除
    3. Blog主,你好,感謝你的解釋,
      但我基礎不太好,所以有點跟不上,
      我現在的理解是configuration space是要從右至左切成兩個兩個來看(不改變順序),
      所以00|20|00|00要閱讀,就變成00|00|20|00

      那接下來的2進制轉換就看不太懂,
      我將00002000轉為十進位,其數字為8192,
      再將8192轉為2進位為10000000000000,
      請問這個轉換的計算是要怎麼做才對?

      刪除
    4. Hi L.J. ,
      你2進制算出來結果跟我一樣,我只是分成4bit來看,而且我是以32bit為單位(因為Correctable Error Status register為32bit),所以高位元的0我也寫出來而已,比較好看

      => 00002000h
      10進制=> 8192
      16進制=> 00000000000000000010000000000000b <- (bit 13為1)

      刪除
    5. Blog主,你好,我突然理解你說的東西,
      所以是Figure 7-32裡的04h~18h,其Register都是32 bit,
      lspci 展示的十六位元(110h)只能秀出16bit,所以剩下的16bit都是填入0,
      我這樣的理解對嗎?

      如果是這樣的話,那我還有幾個問題:
      那Figure 7-32 裡的0Ch,是要在lscpi 裡的110h之後還是之前?
      因為c在十六進制的代表是12,
      012h跟10h的比較的話,012h又大於10h,
      為什麼Figure 7-32的順序要這樣排呢?
      為什麼要把大的排在小的前面?

      刪除
    6. Hi L.J. ,
      我覺得你有點混淆了,故事可能要先從計算機概論講起。
      十六進制為4個bit為一個單位,所以假設有一組2進制的數字如下(b表示為2進制)
      11010011b
      那麼他的十六進制必須要四個為一單位轉換(h表示為16進制)
      1101 0011 b
      ↓ ↓
      = D 3 h

      ---分隔線------------------------------------------------------
      那現在回到AER Capability registers,lspci數字兩個兩個為一單位(剛好8 bits,也就是一個byte),所以Correctable Error Status Register為32 bits(4 bytes),所以Correctable Error Status Register為黑色圖中的110h~113h(4 bytes),參考我在文章最後新增的圖片,也就是黃色框框所框起來的4 bytes。

      刪除
    7. Blog主,謝謝你的回答,我已經理解了

      刪除
  2. 遇到這個 MESSAGE, 是指發生什麼狀況?
    [ 100.016115] pcieport 0001:00:00.0: PCIe Bus Error: severity=Corrected, type=Physical Layer, (Receiver ID)
    [ 100.025678] pcieport 0001:00:00.0: device [1957:8d90] error status/mask=00000001/00006000
    [ 100.034024] pcieport 0001:00:00.0: [ 0] RxErr (First)

    回覆刪除
  3. 其實就是Correctable Error中的Receiver Error(RxErr),根據Gen3 spec裡的"Table 6-3:Physical Layer Error List"有提到四種case,總結大致上應該就是訊號有問題,有Protocol Analyzer的話,可以錄看看LTSSM是否有跑進去Recovery。


    1.Disparity是在8b/10b decode中用來平衡電氣訊號的,也就是0和1均勻的打散,應該就是避免雜訊之類的。如以下描述,當有不正確的running disparity或者是收到的Symbol與running disparity table對不起來的話,就是RxErr

    ■ Section 4.2.1.1.3
    If a received Symbol is found in the column corresponding to the incorrect running disparity or if the Symbol does not correspond to either column, the Physical Layer must notify the Data Link Layer that the received Symbol is invalid. This is a Receiver Error, and is a reported error associated with the Port

    2.像是以下這些case,也是屬於 RxErr
    ■ Section 4.2.1.2
    TLP開頭不是STP Symbol,結尾不是END Symbol or EDB Symbol
    DLLP開頭不是SDP Symbol,結尾不是END Symbol
    當TX處於Logical Idle,發現lane有非00h值的data
    x1 lane以上的 link,TLP STP Symbol必須放置Lane0
    x1 lane以上的 link,DLLP SDP Symbol必須放置Lane0
    Receivers may optionally check for violations of the rules of this section. These checks are independently optional (see Section 6.2.3.4). If checked, violations are Receiver Errors

    3. 如下描述,8b/10b的部分,像是Framing錯誤、失去Symbol Lock等等,都屬於RxErr。128b/130b的部分,像是失去Block Alignment、Elasticity Buffer overflow等等,都屬於RxErr。

    ■ Section 4.2.4.7
    8b/10b decode errors must be checked and trigger a Receiver Error in specified LTSSM states (see Table 4-14), which is a reported error associated with the Port (see Section 6.2). Triggering a Receiver Error on any or all of Framing Error, Loss of Symbol Lock, Lane Deskew Error, and Elasticity Buffer Overflow/Underflow is optional

    128b/130b Framing errors must be checked and trigger a Receiver Error in the LTSSM states specified in Table 4-14. The Receiver Error is a reported error associated with the Port (see Section 6.2). Triggering a Receiver Error on any of all of loss of Block Alignment, Elasticity Buffer Overflow/Underflow, and loss of Lane-to-Lane de-skew is optional

    4. 或者是當LTSSM正在的Configuration State和Recovery State的時候發生了Link Error,RxErr也會被report
    ■ Section 4.2.6
    Allowing Receiver Errors to be set while in Configuration or Recovery is intended to allow implementations to report Link Errors that occur while processing packets in those states. For example, if the LTSSM transitions from L0 to Recovery while a TLP is being received, a Link Error that occurs after the LTSSM transition can be reported.

    回覆刪除
  4. 版主你好,
    不好意思,向您請教一下,假設host端是跑VBox虛擬機在intel的cpu上,就算ep端已經設定多組的MSI,host是不是無法分配出超過一組的MSI來用,感謝。

    回覆刪除
    回覆
    1. 抱歉,我看不太懂你的意思,你的意思是說,你有一台Host OS跑在intel CPU上,且你在這台Host OS又安裝了VBox且開啟了VM,然後你將endpoint passthrough進去VM是嗎?

      刪除
    2. 您好,我們實驗場景是ep跑在Synopsys的zebu驗證系統上,並且以VBOX的虛擬機作host對接,
      然後我在driver中,使用 pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI )初始和配置MSI,
      但是發現 return 為1,不接受多組的MSI,所以才在想是否是VB的關係,還是有需要改動Kernel的設定?
      感謝。

      刪除
    3. 目前聽起來device chip還在FPGA(zebu)階段, 而且這個device是pcie裝置,接在VBOX host上(聽起來是Linux OS)。
      pci_alloc_irq_vectors看了一下kernel code,主要是分配interrupt vector,最小1個最大32個,但我現在不知道你的device是使用msi or msi-x,而且這兩個support的interrupt個數也不一樣,你能先用lspci -s xx:xx.x -vvv看一下device capabilities嗎,應該可以找到像下面的資訊

      ========================================================
      ...
      ...
      Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit-
      Address: fee0a000 Data: 4021

      Capabilities: [b0] MSI-X: Enable- Count=8 Masked-
      Vector table: BAR=2 offset=00000000
      PBA: BAR=2 offset=00010000

      ...
      ...
      ========================================================

      刪除
    4. lspci 後是有支援到32 MSI,但Host 沒辦法給我第二組MSI 對應的address 和data

      Capabilities: [40] Power Management version 3
      Flags: PMEClk- DSI- D1+ D2- AuxCurrent=375mA PME(D0+,D1+,D2-,D3hot+,D3cold+)
      Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
      Capabilities: [50] MSI: Enable+ Count=1/32 Maskable- 64bit+
      Address: 00000000fee00000 Data: 402e
      Capabilities: [70] Express (v2) Endpoint, MSI 00
      感謝。

      刪除
    5. 真的滿奇怪的,看起來Multiple Message Capable有設成32,只能查看看dmesg或者直接在driver print log了

      刪除
  5. 版主你好,請問你有研究過SERR#嗎? 從spec看起來似乎只要有打開Device Control中的error reporting就可以report error了,不知道是不是SERR#這個bit的重要性

    回覆刪除
    回覆
    1. 更正:版主你好,請問你有研究過Bridge Control - SERR#嗎? 從spec看起來似乎只要有打開Device Control中的error reporting就可以report error了,不知道SERR#這個bit的重要性

      刪除
    2. 詢問一下,你現在想看有沒有report AER message的設備是device或root port或root complex?

      因為文章中的Figure 6-3中其實左邊有標示範圍,所以只有Root Port和Virtual PCI Bridge才需要設置Bridge Control的SERR# bit來打開AER message的report。

      然後Figure 6-3的條件都要全部符合才會發出AER message,以Root Port為例,Root Port要符合的條件最多,(1) Bridge Control register - SERR# bit設1,(2) Command register - SERR# bit要設1,(3) Device Control register的Error Reporting Enable bit要設1,滿足這3個條件才會送出AER message(ERR_COR, ERR_FATAL, ERR_NONFATAL)

      刪除
    3. 我好像講錯了,Root Port的話只要符合(1)跟(3)就可以了,(2)Command register - SERR# bit是用來決定要不要發System Error通知OS,通常應該是發SMI interrupt(System Managment interrupt),不過會不會發SMI可能也要在BIOS裡面開啟

      Device的部分看圖應該只要(3)有設1就可以了

      刪除
    4. 版主你好,抱歉現在才看到你回覆。
      我現在是在看BIOS code時發現,為何有的需要設定SERR#,所以才有這個疑問,總覺得只要有(3) Device Control register的Error Reporting Enable bit,似乎就可以了。

      你提到的 "(2)Command register - SERR# bit是用來決定要不要發System Error通知OS",我有點有個小疑問,以Root Port來說,是不是不需要(2)呢?

      因為要通知OS or FW的話,看起來是由Figure 6-3 最上方的 System Error (Platform specific) 來通知FW / Error Interrupt (INTx or MST) 來通知OS

      刪除
    5. Root Port要設定(1)(3),你看的SERR#是在Bridge Control register還是在Command register裡面呢?,看圖6-3 Root Port(1)(3)都要設定才會發AER message,(2)是用來發SMI interrupt給CPU的,不影響發AER message

      (1) Bridge Control register - SERR# bit設1
      (3) Device Control register的Error Reporting Enable bit要設1

      刪除
    6. 我看的是設定在RP端的Bridge Control register.
      OK,所以(2) 沒有設定的話, 就不會有SMI發生嗎

      刪除
    7. 對,(2)的那個SERR沒有設1的話,不會發SMI,就不會進BIOS code裡面的SMI handler

      刪除
  6. Hi Dantong , It will be much useful if you can give me an 3 example flows, like my endpoint device detected a correctable, uncorrectable-fatal, non fatal error .how my end point will report it to RC and how RC will react for the corresponding issue.(like in which flow the config reg are read/written by each device through Error message or some other mechanism )

    回覆刪除
    回覆
    1. Hi Prabu, I answered at the bottom of the article. But currently I only have one example for uncorrectable non-fatal error case and the trace just can show the behavior between Root Port and Device. I don't know how Root Port routing the ERR_NONFATAL message to Root Complex

      刪除

解析 NVM Express - 透過Linux OS 解析M.2 NVMe SSD

在之前,我撰寫了三篇有關NVMe的文章 ,分別是" 原理NVM Express - NVMe Submission Queue & Completion Queue (SQ & CQ) "、" 原理NVM Express - Admi...