尋找開源100G NIC Corundum中的隱藏BUG_第1頁
尋找開源100G NIC Corundum中的隱藏BUG_第2頁
尋找開源100G NIC Corundum中的隱藏BUG_第3頁
尋找開源100G NIC Corundum中的隱藏BUG_第4頁
尋找開源100G NIC Corundum中的隱藏BUG_第5頁
已閱讀5頁,還剩2頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

尋找開源100GNICCorundum中的隱藏BUGCorundum是一個基于FPGA的開源NIC原型平臺,用于高達100Gbps及更高的網(wǎng)絡接口開發(fā)。Corundum平臺包括一些用于實現(xiàn)實時,高線速操作的核心功能,包括:高性能數(shù)據(jù)路徑,10G/25G/100G以太網(wǎng)MAC,PCIegen3,自定義PCIeDMA引擎以及本機高精確的IEEE1588PTP時間戳。背景我們基于Corundum這個靈活且強大的平臺開發(fā)了一款網(wǎng)絡加速器。如圖所示,我們的設計(位于APP黃色部分)需要和原生數(shù)據(jù)流量共用一套DMAIF和主機HOST進行通信。紫色數(shù)據(jù)路徑為用于DMA操作的自定義分段內存接口,連接著Corundum的高性能DMA引擎和分段存儲器。在我們的設計中,需要頻繁的進行DMA讀寫操作。DMA操作大致有兩種類型,一種是小數(shù)據(jù)包的DMA,長度在16B-64B之間,內容為硬件和主機通信的描述符,存放于Descfetch和Cplwrite模塊內的描述符分段存儲器;一種是大數(shù)據(jù)包的DMA,長度大于1kB,內容為傳輸數(shù)據(jù),存放于APP下的數(shù)據(jù)分段存儲器。我們的設計通過了大量仿真,確認開發(fā)設計功能無誤,隨后開始上板測試。問題我們的PCIe鏈路速率gen3*8,PCIe理論帶寬為64G。在上板時出現(xiàn)了很奇怪的現(xiàn)象。每次測試發(fā)送小數(shù)量級的請求時(<10000次,每次代表一次小數(shù)據(jù)包的DMA和一次大數(shù)據(jù)包的DMA),估算PCIe帶寬在25G-35G左右。這種測試情況下不會發(fā)生錯誤,測試順利通過。當測試請求數(shù)量進一步增大時(>10萬次),預估PCIe帶寬在35G~40G。此時測試就會發(fā)生問題,整個系統(tǒng)癱瘓。定位進一步定位問題,主機和FPGA還可以通過MMIO進行寄存器訪問,但是DMA已經(jīng)完全卡死。在DMAIF下設置計數(shù)器用于統(tǒng)計DMARead請求的個數(shù)和響應:if(s_axis_read_desc_valid&&s_axis_read_desc_ready)begindma_read_req_cnt<=dma_read_req_cnt+1'b1;endif(m_axis_read_desc_status_valid)begindma_read_status_cnt<=dma_read_status_cnt+1'b1;end上板debug信號,每次測試癱瘓后請求的個數(shù)總是大于響應的個數(shù)。在Corundum中,DMA引擎是這樣工作的:DMA引擎接收來自用戶的DMARead請求,然后將DMARead請求轉換為PCIeNon-Posted類型的memread請求TLP包,然后等待memread的Cpld返回報文,解析Cpld報文,將數(shù)據(jù)通過自定義分段內存接口存儲至各級模塊下的分段存儲器中,存儲完成后將回復DMARead響應至用戶。結合對DMA引擎的理解,可以推測有以下幾個可能導致響應個數(shù)不夠PCIeIP錯誤導致rdtlp或cpld丟失;DMA引擎因返回cpld攜帶錯誤而丟棄cpld;DMA引擎因PCIe流控發(fā)生不可預知的錯誤,隨機丟棄數(shù)據(jù)包;其他原因;分析原因:PCIeIP為XilinxUltraScale+IntegratedBlock(PCIE4C)forPCIExpress,成熟的商用IP經(jīng)過了大規(guī)模驗證和使用一般不會出現(xiàn)問題,可以暫且排除因素1。抓取相關的錯誤信號(rx_cpl_tlp_error、status_error_cor、status_error_uncor),結果表明PCIe并未發(fā)生可糾正/不可糾正的錯誤類型,表示通信雙方鏈路正常,并沒有因為錯誤而丟棄報文導致響應的數(shù)量不夠,可以排除因素2。首先Corundum是一款100Gbps速率的網(wǎng)卡設計,經(jīng)過了大量驗證和上板測試;其次測試的PCIe理論帶寬為64Gbps。而此時的測試帶寬35G~40G遠遠不足s設計帶寬或是鏈路帶寬上限,應該不會觸發(fā)流控機制。這里因素三也需要被排除。求助AlexForencich最了解自己設計的一定是作者本人。我隨后在Zulip上求助了作者,希望他可以幫我想一想導致此問題其他有可能的因素。Alex很熱心,對每個問題都會做出回復。他表示這種問題很難定位,需要精確的定位“案發(fā)現(xiàn)場”才有可能定位問題。我可以確保每次DMA操作的地址和長度都是合理的,并且由于memreadtlp為Non-Posted類型,因此需要等待一定的PCIe鏈路時延才能得到返回報文。這兩項特質決定了很難定位至發(fā)生錯誤的DMA操作,無法恢復到錯誤發(fā)生的那一時刻。他告訴了我一種定位的手段:設置足夠深的ILA緩沖,用計數(shù)器擴展以檢測掛起:基本上,在每個周期遞增,但如果計數(shù)一致或有響應,則重置;然后將該計數(shù)器輸入ILA;并觸發(fā)各種計數(shù)器值。注意:觸發(fā)器位置靠近緩沖器末端。基于此思路,我做出了以下設置:設置ILA深度至8192,并且調整每次DMARead的長度為4K,確保能夠在ILA深度內抓到完整的DMA操作。dma_read_cycle_cnt作為需要觸發(fā)的計數(shù)/時器,每收到一個DMARead請求開始隨時鐘周期自增,收到DMARead請求響應清零;dma_read_cycle_max_cnt用來記錄正常情況下Non-Posted完成的最大計數(shù)值。將觸發(fā)條件設置為dma_read_cycle_cnt>dma_read_cycle_max_cnt,這樣就可以觸發(fā)到模塊出錯的時刻。調整dma_read_cycle_max_cnt觸發(fā)條件,逐步逼近出錯時刻。if(m_axis_read_desc_status_valid)begindma_read_cycle_cnt<=32'b0;endelseif(s_axis_read_desc_valid&&s_axis_read_desc_ready)begindma_read_cycle_cnt<=32'b1;endelseif(dma_read_cycle_cnt>=1'b1)begindma_read_cycle_cnt<=dma_read_cycle_cnt+1'b1;endelsebegindma_read_cycle_cnt<=dma_read_cycle_cnt;endif(m_axis_read_desc_status_valid&&(dma_read_cycle_cnt[23:0]>dma_read_cycle_max_cnt))begindma_read_cycle_max_cnt<=dma_read_cycle_cnt;endelsebegindma_read_cycle_max_cnt<=dma_read_cycle_max_cnt;end同時,在ILA內抓取一些相關的重要信號:基本的握手信號和相關流控信號。外加統(tǒng)計readtlp的請求數(shù)據(jù)長度累計和返回cpld的數(shù)據(jù)長度累計。定位“案發(fā)現(xiàn)場”按照觸發(fā)設置,終于在ILA中捕獲到“案發(fā)現(xiàn)場”。某個時刻,握手信號rx_cpl_tlp_ready不再置1,但rx_cpl_tlp_valid還存在。表明DMA引擎出現(xiàn)了問題,無法再接收返回的cpld報文。也就是從此刻開始,DMARead請求的個數(shù)在一直增加,但是DMARead響應的個數(shù)卻不再增長。定位到了出錯時刻,此時便可以對模塊內的重點信號展開分析。原因分析前文已經(jīng)去除掉了面向HOST的種種因素,因此最有可能出問題的地方只能是面向用戶的用于DMA操作的自定義分段內存接口。這里的分段內存接口是Corundum獨特的體系結構的一種,對于PCIe上的高性能DMA,Corundum使用自定義分段存儲器接口。該接口被分成最大512位的段,并且整體寬度是PCIe硬IP內核的AXI流接口寬度的兩倍。例如,將PCIeGen3x16與PCIe硬核中的512位AXI流接口一起使用的設計將使用1024位分段接口,該接口分成2個段,每個段512位。與使用單個AXI接口相比,該接口提供了改進的“阻抗匹配”,從而消除了DMA引擎中的對齊和互連邏輯中的仲裁,從而消除了背壓,從而提高了PCIe鏈路利用率。具體地說,該接口保證DMA接口可以在每個時鐘周期執(zhí)行全寬度,未對齊的讀取或寫入。此外,使用簡單的雙端口RAM(專用于在單個方向上移動的流量)消除了讀寫路徑之間的爭用。在自定義分段內存接口中,使用ram_wr_cmd_sel路由和復用。基于單獨的選擇信號而不是通過地址解碼進行路由的。此功能消除了分配地址的需要,并允許使用可參數(shù)化的互連組件,這些組件以最少的配置適當?shù)芈酚刹僮鳌utputwire[RAM_SEG_COUNT*RAM_SEL_WIDTH-1:0]ram_wr_cmd_sel,outputwire[RAM_SEG_COUNT*RAM_SEG_BE_WIDTH-1:0]ram_wr_cmd_be,outputwire[RAM_SEG_COUNT*RAM_SEG_ADDR_WIDTH-1:0]ram_wr_cmd_addr,outputwire[RAM_SEG_COUNT*RAM_SEG_DATA_WIDTH-1:0]ram_wr_cmd_data,outputwire[RAM_SEG_COUNT-1:0]ram_wr_cmd_valid,inputwire[RAM_SEG_COUNT-1:0]ram_wr_cmd_ready,inputwire[RAM_SEG_COUNT-1:0]ram_wr_done,DMARead引擎使用分段內存的寫入接口,將獲取的cpld數(shù)據(jù)寫入分段存儲器中。使用ram_wr_cmd_sel決定寫入哪個分段存儲器,使用ram_wr_cmd_addr決定寫入分段存儲器的地址,使用ram_wr_done判斷寫入操作完成。同樣為分段內存接口設置計數(shù)器,用于統(tǒng)計分段內存接口的寫入和寫入完成操作。if(ram_wr_cmd_valid[0]&&ram_wr_cmd_ready[0])begindpram_wr_cmd_cnt0<=dpram_wr_cmd_cnt0+1'b1;endif(ram_wr_cmd_valid[1]&&ram_wr_cmd_ready[1])begindpram_wr_cmd_cnt1<=dpram_wr_cmd_cnt1+1'b1;endif(ram_wr_done[0])begindpram_wr_done_cnt0<=dpram_wr_done_cnt0+1'b1;endif(ram_wr_done[1])begindpram_wr_done_cnt1<=dpram_wr_done_cnt1+1'b1;end問題就出現(xiàn)在這里:在“案發(fā)時刻”之后,分段內存接口處不再有寫入完成信號ram_wr_done??梢宰C明問題就出在這里,不再有內存寫入完成信號,導致DMAIF遲遲無法確認數(shù)據(jù)操作完成,進而導致無法接收新的Cpld報文數(shù)據(jù)(防止數(shù)據(jù)覆蓋)。進一步分析“案發(fā)時刻”之前分段內存接口的所有波形,終于在某個時刻找到了異樣。在此時刻,分段存儲器的地址不再是線性增加,發(fā)生了跳變,執(zhí)行完0地址的寫入之后再恢復正常。與DMARead操作關聯(lián)起來,并且充分考慮到Non-Posted操作的PCIe鏈路時延,從“案發(fā)時刻”之前的13次DMARead刪選出出錯的那一次DMARead操作。首先進行了一個4kB的大DMARead操作;隨后便是一個64B的小DMARead操作:所以按理來說,分段內存應該先執(zhí)行完4kB的數(shù)據(jù)寫入操作之后,再進行64B的數(shù)據(jù)寫入操作。但抓取到的波形卻顯示數(shù)據(jù)寫入操作地址發(fā)生了跳變,0x5fc->0x000->0x5fd。而這正是觸發(fā)測試錯誤的條件:兩次memrdtlp的cpld碰巧發(fā)生了交織,或者說發(fā)生了亂序。小數(shù)據(jù)包的cpld超越了部分大數(shù)據(jù)包的cpld,先一步通過PCIe鏈路傳送至硬件。這種完成報文之間的亂序恰巧是PCIe協(xié)議所允許的,用于保證生產(chǎn)者/消費者模型的正確運轉,防止死鎖的發(fā)生。如果完成報文與之前的完成報文的TransactionID不同,該報文可以超越之前的完成報文;如果相同,則不能超越。這里恰巧是兩個連續(xù)的不同DMARead操作,TransactionID的tag必不相同,所以亂序是會發(fā)生的。在仿真中恢復案發(fā)現(xiàn)場在仿真中,將“案發(fā)時刻”前后的波形文件csv導入仿真環(huán)境,或者直接使用force-release強制激勵即可恢復案發(fā)現(xiàn)場。通過在仿真中檢查,很快便定位到是最近一級的dma_mux模塊出現(xiàn)了問題,它會在這種情況下丟棄1-2個ram_wr_done。這有可能是每個分段存儲器的寫入路徑時延不同,導致done信號同時到達mux模塊或者是mux模塊因為被占用而無法處理某一個分段存儲器的寫入完成,導致done信號丟失。修改BUG隨后詢問了Alex我的想法是否正確:他表示編寫mux時使用fifo和計數(shù)器來捕獲所有的done脈沖信號,并按正確的順序轉發(fā),但似乎存在一個bug。隨后也證明確實是dma_ram_demux_wr這個模塊存在問題:Alex隨后進行了BUG修改。對輸入dma_ram_demux_wr的完成的done信號

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論