作者:高志凱
一次常規(guī)調(diào)試中發(fā)現(xiàn)上電后交換機(jī)多個(gè)口同時(shí)打流會(huì)導(dǎo)致卡死的現(xiàn)象,最后一步步分析問(wèn)題出現(xiàn)的原因是位寬不夠?qū)е碌囊绯觥_@讓我回想起團(tuán)隊(duì)已經(jīng)量產(chǎn)的某款芯片,也是因?yàn)槟硞€(gè)寄存器位寬設(shè)置過(guò)小的原因,導(dǎo)致組播組設(shè)置的時(shí)候不能超過(guò)31,否則就會(huì)溢出,只能想辦法通過(guò)軟件來(lái)解決這個(gè)問(wèn)題。這次出現(xiàn)問(wèn)題的交換機(jī)是基于共享緩存的架構(gòu),希望后面引以為戒,設(shè)計(jì)每個(gè)小的寄存器時(shí)都要考慮全面。
背景
在使用verilog進(jìn)行程序設(shè)計(jì)時(shí),尤其需要注意數(shù)據(jù)位寬問(wèn)題。當(dāng)我們將程序燒入fpga的時(shí)候電路已經(jīng)固定,不能像C語(yǔ)言那樣動(dòng)態(tài)改變數(shù)組長(zhǎng)度,因此數(shù)據(jù)位寬設(shè)計(jì)不恰當(dāng)會(huì)引入意想不到的問(wèn)題。例如我們使用二進(jìn)制進(jìn)行計(jì)數(shù)時(shí),位寬為5的數(shù)據(jù)表示范圍為0-31,當(dāng)數(shù)據(jù)為32時(shí)由于位寬不夠,實(shí)際顯示則為0,如果此時(shí)你需要對(duì)這個(gè)數(shù)進(jìn)行大小判斷,那么可能會(huì)得到錯(cuò)誤的結(jié)果。筆者在交換機(jī)功能調(diào)試、解決bug的過(guò)程中對(duì)此深有體會(huì)。
首先我們來(lái)看一下交換機(jī)對(duì)數(shù)據(jù)的處理流程,網(wǎng)絡(luò)測(cè)試儀發(fā)出的數(shù)據(jù)首先經(jīng)過(guò)接口進(jìn)入分流模塊,我們的交換機(jī)支持TT業(yè)務(wù)(時(shí)間觸發(fā))和ET業(yè)務(wù)(普通以太網(wǎng)),本文就ET業(yè)務(wù)進(jìn)行分析。以太網(wǎng)幀進(jìn)入MAC核進(jìn)行CRC校驗(yàn),
并將8位輸入數(shù)據(jù)轉(zhuǎn)32位輸出,轉(zhuǎn)換模塊將數(shù)據(jù)轉(zhuǎn)換為128位總線數(shù)據(jù),并支持反壓。接著數(shù)據(jù)經(jīng)過(guò)輪詢(xún)進(jìn)入分組處理模塊,分組處理模塊一方面將數(shù)據(jù)幀傳入接收總線,另一方面根據(jù)幀信息提取結(jié)果和流分類(lèi)信息將接受幀信息傳入入隊(duì)模塊進(jìn)行邏輯入隊(duì),邏輯入隊(duì)模塊管理著一個(gè)虛擬的存儲(chǔ)塊,每一個(gè)虛擬的存儲(chǔ)塊對(duì)應(yīng)著真實(shí)的物理數(shù)據(jù),也就是數(shù)據(jù)幀。緩存管理模塊根據(jù)入隊(duì)和出隊(duì)情況更新存儲(chǔ)塊信息,同時(shí)更新的還有隊(duì)列的長(zhǎng)度等信息。數(shù)據(jù)幀出隊(duì)時(shí)首先由邏輯預(yù)出隊(duì)模塊根據(jù)優(yōu)先級(jí)輪詢(xún)隊(duì)列,并給出出隊(duì)號(hào),邏輯出隊(duì)模塊根據(jù)端口號(hào)查詢(xún)出隊(duì)信息,然后控制總線發(fā)送數(shù)據(jù),數(shù)據(jù)經(jīng)過(guò)轉(zhuǎn)換模塊轉(zhuǎn)32位然后經(jīng)mac核輸出。
粗略了解了交換機(jī)的結(jié)構(gòu),言歸正傳,數(shù)據(jù)溢出為什么會(huì)導(dǎo)致交換機(jī)“假性卡死”?
現(xiàn)象
首先我們需要深入了解一下邏輯出隊(duì)預(yù)出隊(duì)模塊,這個(gè)模塊會(huì)產(chǎn)生出隊(duì)號(hào),并將出隊(duì)號(hào)傳入schedule_dequeue模塊,然后schedlue_dequeue模塊根據(jù)出隊(duì)號(hào)獲得出隊(duì)幀首地址,并查詢(xún)虛擬塊地址,從而獲得數(shù)據(jù)的物理存儲(chǔ)地址,進(jìn)行數(shù)據(jù)搬移。
現(xiàn)在我們說(shuō)一下現(xiàn)象,上板時(shí),交換機(jī)4個(gè)口接到testcenter,每個(gè)口打1Gbps數(shù)據(jù)流,固定幀長(zhǎng)為64Bytes,其中1、2口打?qū)α鳎?、4口打?qū)α?。?dāng)testcenter準(zhǔn)備好后直接給交換機(jī)4個(gè)口同時(shí)打數(shù)據(jù)流,這時(shí)有兩個(gè)口正常工作,但是另外兩個(gè)口卡死,沒(méi)有幀出來(lái)。如果在一開(kāi)始將數(shù)據(jù)流速率控制在90%,打一陣流之后在將4個(gè)口速率提升到100%,則不會(huì)出現(xiàn)上述卡死現(xiàn)象。我們經(jīng)過(guò)分析,認(rèn)為交換機(jī)是能夠處理每個(gè)端口1Gbps速率的數(shù)據(jù)流,否則另外兩個(gè)正常工作的隊(duì)列便無(wú)法解釋。那么問(wèn)題出在哪里了?
我們根據(jù)經(jīng)驗(yàn),首先對(duì)入隊(duì)和出隊(duì)關(guān)于幀長(zhǎng)信息的更新,入隊(duì)與出隊(duì)產(chǎn)生沖突時(shí)隊(duì)列頭部和尾部信息的更新等等進(jìn)行了檢查,經(jīng)過(guò)仿真和對(duì)比更新數(shù)據(jù),確實(shí)發(fā)現(xiàn)了一些小bug,本以為這就是最終bug,結(jié)果興沖沖的跑了一版程序去上板測(cè)試,發(fā)現(xiàn)還是上述現(xiàn)象!這說(shuō)明我們沒(méi)有找到關(guān)鍵點(diǎn)。
發(fā)現(xiàn)問(wèn)題
這里要為大家介紹一種調(diào)試代碼的方法,就是計(jì)數(shù)法。為了找出問(wèn)題出在哪里,我們對(duì)邏輯入隊(duì)、物理入隊(duì)的各隊(duì)列幀數(shù)進(jìn)行統(tǒng)計(jì),將其與邏輯出隊(duì)、物理出隊(duì)的各隊(duì)列幀數(shù)進(jìn)行對(duì)比。這時(shí)我們發(fā)現(xiàn),邏輯入隊(duì)和物理入隊(duì)幀數(shù)目一致,
邏輯出隊(duì)和物理出隊(duì)幀數(shù)目一致,但是入隊(duì)和出隊(duì)數(shù)目不一致,兩者相差256,但是隊(duì)列里顯示有255個(gè)幀,這是由隊(duì)列門(mén)限決定的,那么其實(shí)有經(jīng)驗(yàn)的你就能大概猜到這個(gè)差值256有點(diǎn)問(wèn)題。是的沒(méi)錯(cuò),問(wèn)題就出在這里。
我們查看代碼發(fā)現(xiàn),
這里的port_state_data_in_b會(huì)根據(jù)優(yōu)先級(jí)更新相應(yīng)隊(duì)列的幀數(shù)目,顧名思義,它的低8位代表的是優(yōu)先級(jí)為0幀的數(shù)目。當(dāng)入隊(duì)的隊(duì)列號(hào)為00并且入隊(duì)成功后,其低8位會(huì)加1,出隊(duì)成功則減1,上圖展示的便是出隊(duì)時(shí)的代碼。但是我們要知道,優(yōu)先級(jí)為0的隊(duì)列最多有8個(gè),因?yàn)殛?duì)列號(hào)是由{端口號(hào),優(yōu)先級(jí)}的形式組成的,也就是說(shuō)一個(gè)優(yōu)先級(jí)對(duì)應(yīng)8個(gè)端口號(hào)。前面我們說(shuō)了一個(gè)隊(duì)列的門(mén)限是256,也就是0-255。那么當(dāng)優(yōu)先級(jí)為0的a隊(duì)列已滿(mǎn),這時(shí)優(yōu)先級(jí)為0的b隊(duì)列再來(lái)一個(gè)幀,port_state_data_out_b的值就會(huì)達(dá)到256,由于其只有8位,所以port_state_data_out_b的值其實(shí)是0!這就很麻煩了,因?yàn)闄C(jī)器不夠智能,只能夠按照你的代碼按部就班的執(zhí)行。
所以卡死的原因出來(lái)了,由于port_state_data_out_b溢出置0,導(dǎo)致pri_val一直為0,所以狀態(tài)機(jī)一直在進(jìn)行一個(gè)循環(huán),不能完成正常跳轉(zhuǎn)!而這個(gè)模塊提供了出隊(duì)號(hào),當(dāng)其沒(méi)有提供出隊(duì)號(hào)時(shí),schedule_dequeue模塊就無(wú)法產(chǎn)生出隊(duì)指令,總線也沒(méi)辦法進(jìn)行數(shù)據(jù)搬移,從而對(duì)外顯示為“卡死狀態(tài)”。
解決問(wèn)題
發(fā)現(xiàn)了問(wèn)題,解決起來(lái)就很簡(jiǎn)單了,我們只需要將優(yōu)先級(jí)對(duì)應(yīng)的隊(duì)列計(jì)數(shù)器計(jì)數(shù)上限設(shè)置到八個(gè)端口的最大值2048即可,也就是12位的數(shù)據(jù)位寬。如下圖:
寫(xiě)在最后,往往最微不足道的問(wèn)題最不容易讓人發(fā)現(xiàn)。這個(gè)位寬不足所導(dǎo)致的問(wèn)題筆者找了很久,檢查過(guò)很多模塊,雖然這其中發(fā)現(xiàn)了一些其他bug,但是解決這個(gè)大bug的過(guò)程卻是費(fèi)時(shí)費(fèi)力的,但是設(shè)計(jì)者在設(shè)計(jì)代碼時(shí)只需要認(rèn)真考慮承載功能所需要的位寬,便能為后續(xù)調(diào)試減輕許多麻煩!原我們都養(yǎng)成一個(gè)良好的習(xí)慣。
編輯:hfy
-
以太網(wǎng)
+關(guān)注
關(guān)注
41文章
5866瀏覽量
178607 -
交換機(jī)
+關(guān)注
關(guān)注
23文章
2842瀏覽量
103302 -
Verilog
+關(guān)注
關(guān)注
30文章
1368瀏覽量
113544 -
C語(yǔ)言
+關(guān)注
關(guān)注
183文章
7634瀏覽量
143922
發(fā)布評(píng)論請(qǐng)先 登錄
緩存之美:萬(wàn)文詳解 Caffeine 實(shí)現(xiàn)原理(上)

高性能緩存設(shè)計(jì):如何解決緩存偽共享問(wèn)題

MCU緩存設(shè)計(jì)
Nginx緩存配置詳解

nginx中強(qiáng)緩存和協(xié)商緩存介紹
帶緩存與不帶緩存的固態(tài)硬盤(pán)有什么區(qū)別
緩存對(duì)大數(shù)據(jù)處理的影響分析
HTTP緩存頭的使用 本地緩存與遠(yuǎn)程緩存的區(qū)別
Web緩存的類(lèi)型及功能分析
緩存技術(shù)在軟件開(kāi)發(fā)中的應(yīng)用
什么是緩存(Cache)及其作用
上位機(jī)系統(tǒng)架構(gòu)分析 上位機(jī)與下位機(jī)的區(qū)別
緩存之美——如何選擇合適的本地緩存?

智算中心網(wǎng)絡(luò)交換機(jī)需要什么樣的緩存架構(gòu)

Sallen-Key架構(gòu)分析

評(píng)論