|
TCP/IP Offload Engine (TOE) for SOC system 成功大學電通所
指導教授:陳中和
學生:詹博凱、余承燁
|
| | |
設計動機 網際網路已成為現今生活十分重要的環節,100Mbps的網路系統在學校或公司網路已十分普遍,1Gbps更常被應用在擁有多台主機的伺服器網路中,例如大型的入口網站和SAN(Storage Area Network)等。儲存元件的網路化更是網際網路發展的趨勢之一,Internet SCSI (iSCSI)傳輸協定為一新興起的網路儲存技術標準。然而當這些應用使用高速網路時,會造成伺服器處理的極大負荷。近年來研究指出,要處理1Gbps頻寬的TCP協定,需要100% 的PentiumIII 1GHz處理器效能,或30% 的Pentium4 2.4GHz,所以利用額外的硬體加速網路的處理減輕主CPU的負擔是一個值得研究的課題。
對於擁有網路功能的嵌入式系統來說更是如此,網路通訊協定的處理是一個跟記憶體高度相關的工作,記憶體存取次數的多寡跟資料數量成為決定性的關鍵。例如做Check Sum時,因為需要讀取整筆資料來運算,就需要很多的記憶體存取,造成效能的瓶頸。另外,網路卡(Network Interface Controller, NIC)在接收時由於協定的限制,資料量大時資料會被切成許多小片段,造成大量的中斷影響CPU效能,如果可以將協定處理用額外的硬體來做實現,再加上加強的記憶體管理機制,便可以減少以上的問題。 |
|
|
系統概述 下頁<圖一>是標準的TCP/IP協定堆疊,在一般的嵌入式系統架構中,若要實現TCP/IP,除了要有PHY和MAC(Media Access Controller)來提供實體層(Physical Layer)和資料連接層(Data-link Layer)的處理外,便要在其上安裝簡單的嵌入式作業系統來負責第三層(Network layer, IP layer)和第四層(Transport layer, TCP layer)的執行,以純軟體的方案處理所有TCP/IP的協定。<圖二>則是將網路協定用TOE取代掉以後的系統架構,利用硬體模組來執行協定,並利用驅動程式和上層的使用者空間還有作業系統溝通。

<圖三>是將我們的設計實現在FPGA裡的系統概圖,系統匯流排採用Avalon System Bus。其上除了TOE本體外、還有系統主記憶體、Nios 處理器、系統DMA、還有LAN91C111這塊PHY/MAC晶片的控制器。TOE的本體將會在後面”主要功能與區塊”章節詳細描述。
在這個系統裡面,Nios處理器所扮演的角色是系統的主控制器,負責MAC←→TOE←→Main memory三者的資料搬移。接收時,在MAC接收到訊框後透過韌體將之送至TCP/IP Offload Engine的資料緩衝區,並在處理完畢送至主記憶體。傳送時則相反,將欲傳送的資料送至TOE內部資料緩衝區,並在附加完標頭後搬移到MAC並控制MAC將準備好的資料傳送出去。

會使用Nios處理器的動機,其實是因為我們的系統需要的周邊,PCI interface與SDRAM,在Altera的PCI development board上都有提供,雖然在這次比賽沒有辦法完成到最後的目標(利用SDRAM作為Data buffer以支援更多連線;利用PCI Interface與上層作業系統作溝通),但為了將來本系統發展的擴充性,選擇了這塊發展版進而選擇了Altera的發展環境。 |
|
|
主要功能與區塊 <圖一>表示完整的TCP/IP Stack,然而因為整個網路協定過於複雜,所以我們只實現了最常被使用到TCP/IP協定的功能,<圖一>裡白色的部分才有被實現在設計裡,亦即ARP, ICMP,IP,UDP, 還有TCP,本設計共擁有三個主要功能: 1. 擁有發出ping並回應別人的echo request封包(ARP & ICMP)的能力 2. 提供同時最多8條連線的UDP傳輸能力。 3. 提供同時最多8條TCP連線的建立與管理(未完成)。
<圖三>的硬體概略圖中,TOE的本體則包括以下的模組: 1. 4塊SRAM(alt_syncram): a. 兩塊64KB大小的SRAM作為資料緩衝區,是接收端和傳送端封包的暫存記憶體 (Rx & Tx data buffer)。 b. 兩塊16K大小的SRAM作為接收端和傳送端的連線控制資訊(Connection Control Information, CCI)儲存區塊,這兩個區塊會紀錄資料緩衝區的狀態,還有協定處理子模組的佇列(queue)資訊,基本上,只要是除了封包資料外其他的資料都儲放在此CCI內部。
2. 兩大協定處理區塊: a. Rx協定處理模組。 b. Tx協定處理模組。 這兩個協定處理模組是由更多小模組所構成,每個小模組是負責特定協定層的部份邏輯功能。
3. Register files(TOE的內部暫存器): 大致分成以下幾種: a. CPU控制位元 b. TOE狀態 c. 傳送端條目增加控制暫存器(CPU用來起始一個傳送工作的命令暫存器組) d. 接收端條目增加控制暫存器(CPU用來起始一個接收工作的命令暫存器組) e. ARP Table控制暫存器 f. UDP Control Block控制暫存器 g. TCP Control Block控制暫存器(未完成) h. Protocol Modules控制暫存器 i. 協定處理子模組的佇列基底以及條目數量控制暫存器 |
|
|
所需效能評估 1. 100Mbps wire-speed 在Ethernet,TCP的MSS(Max Segment Size)通常被設為1460 bytes,而IP的MTU(Maximum Transfer Unit)為1500 bytes,所以一個訊框的大小通常為1518 bytes(MAC header有14bytes,CRC有4 bytes),另外,MAC在傳送有效訊框時,會有前導資料(preambles)8 bytes所以接收一個訊框需要1526*8*10ns = 122080ns = 0.12179 ms,亦即我們必須在0.12208ms或12208 clock cycles完成一個frame的處理。
2. 1Gbps wire-speed 是上面的結果的1/10,即我們必須在12.2 us或1220.8 clock cycles完成一個frame的處理。 實際效能分析: 測試環境 TOE:工作時脈為40MHz 發封包的電腦:1GHz的linux 跑udp程式 量測封包數量:2GHz的winxp跑ethereal
圖表說明 下圖爲對於不同大小的封包,TOE每秒鐘所能處理的封包數目。Rx-Tx代表TOE每收到一個封包,就發一個相同大小的回應封包,因此所處理的封包數目為Rx封包加上Tx封包。Rx代表每收到1000個封包才發出一個回應封包,因此所處理的封包數目為Rx封包。所有的資料複製都是由nios cpu來處理。

1. 在Rx-Tx這個測試項目中,當封包大小為60 Byte時,TOE每秒鐘處理的封包數目為封包大小1514 Byte的12倍,會造成這樣的結果是因為TOE從接收到傳送會經過3次資料複製,第一次是由MAC buffer複製到TOE RxBuffer,第二次是由TOE RxBuffer複製到TOE TxBuffer,最後一次是由TOE TxBuffer 複製到MAC。
2. 在Rx這個測試項目中,當封包大小為60 Byte時,TOE每秒鐘處理的封包數目為封包大小1514 Byte的8.7倍,而在Rx-Tx這個測試項目中兩者相差為12倍,這是因為減少一次TOE RxBuffer複製到TOE TxBuffer的時間。
3. 在Rx-Tx這個測試項目中,當封包大小為60 Byte時,TOE每秒鐘處理的封包數目為12000,也就是所接收的封包數目大約為6000。而同樣的封包大小,在Rx這個測試項目中,TOE每秒鐘接收的封包數目為10664。會造成這個結果是因為cpu同時要處理Rx封包與Tx 封包的資料複製。
4. 在Rx-Tx這個測試項目中,當封包大小為60 Byte時,TOE每秒鐘處理的封包數目為12000,也就是所接收的封包數目大約為6000,如果扣除資料複製的時間,也就是假設封包為1514 Byte,則每秒鐘所能接收的資料量為:6000*1514/1000000=9.084MByte。
5. 在Rx這個測試項目中,當封包大小為60 Byte時,TOE每秒鐘處理的封包數目為10664,如果扣除資料複製的時間,也就是假設封包為1514 Byte,則每秒鐘所能接收的資料量為:10664X1514/1000000=16.145MByte。
6. 由以上的分析可知TOE的效能瓶頸在於資料的複製,如果減少資料的複製次數和增加資料複製的速度,本TOE是有能力處理100Mbps的網路速度。要處理1Gbps則需要提升處理器時脈到達:1Gbps/16.145MByte=7.8,40Mhz*7.8=312MHz。
|
|
|
TOE硬體系統設計概念

如<圖四>:首先,我們將堆疊分成兩大模組:接收(Rx module)和傳送(Tx module)模組,它們都是ASIC並掛在同一個系統匯流排上,所以它們可以被同一顆Embedded CPU所控制,並擁有一塊共享的記憶體。除了TCP在作full-duplex mode之下需要跟輸入模組做溝通(例如Sliding Window 大小受ACK reply的影響)外,兩大模組可以完全的獨立運作,這樣設計的好處是傳送跟接收兩個動作可以平行處理,只要在模組需要抓取資料或將完成的資料送到記憶體時利用適當韌體操作便可。

<圖五>表示模組與buffer的連接關係,因為在處理完一層的協定後要將處理過的資料丟到下一層去,為避免過多的memory to memory搬移,每一個通訊協定的處理模組應該要能讀寫一塊共享的記憶體(Shared memory)。如此,當一個協定的模組處理完時,只需要告知下一個模組一個位於共享記憶體的指標,那麼處理流程就可以以最小的記憶體搬移數量來得到資料,當然實際上無法找到大於3個Access port的記憶體可以使用,所以這些模組與buffer連接時,應該要經過仲裁器(arbiter)來判斷誰要先讀寫buffer,至於此仲裁機制對於不同的應用或是不同數量的連線數是否有所相關,是一個可以深入探討的問題。

本作品三大功能的實現(TCP、UDP、Ping),是參考Behrouz A. Forouzan, Sophia Chung Fegan 所著TCP/IP Protocol Suite一書,並根據TCP/IP stack的軟體模組來做設計,利用硬體電路來完成每一個軟體模組的邏輯功能(使用multi-cycle based, Finite State Machine分階段性的去實現單一模組的功能),再將邏輯電路連接到Shared memory以做溝通(<圖五>),整個TCP/IP stack 可以被劃分成數個模組如<圖六>所示,以期望達到平行處理的可能性,如同前面所提,這樣的設計可以在處理傳送封包時,仍有能力接收封包。另外,當一個封包正在處理TCP協定時,可以接受另一個封包佔用IP處理模組來執行IP層的協定工作。而每個協定模組會跑如<圖七>的狀態機:

簡單的說,這些子模組是利用multi-cycle的邏輯電路來實作軟體模組的行為,負責接收的模組群依序分析存在資料緩衝區中訊框的標頭欄位,對此筆資料作處理,傳送的模組群則依據使用者(驅動程式,系統韌體)所下的命令替準備要傳送的資料區段加上網路標頭。 |
|
|
處理模組間的溝通佇列-Buffer Tables, Connection Control Information(CCI) <圖六>所展示的處理模組,彼此之間的溝通是用佇列(Queue)來達成,在我們的設計裡,是用buffer table這個資料表來實現。Buffer table是由一個個的指標和處理封包所需資訊組成,存放在一塊稱為CCI(Connection Control Information)的SRAM中,指向在data buffer的一塊儲放完整封包的記憶體區塊。每一個處理模組都跟至少兩個table有關係,一個代表需要處理的資料所在的指標,另一個則是在模組處理完畢後告知下一層模組所需資料的指標。<圖六>位於線上的字,代表的就是table的名字。我們觀察圖六中ARP這個模組,可以發現它會去ARP_Rx 這個table中抓取需要做ARP協定處理的資料區塊,經過運算之後將完成的資料指標存入Tx_L3_done table中等待MAC_Tx模組讀取指標並將資料送出。<圖八>是邏輯上buffer table與Data Buffer的示意圖,在我們的設計裡,每個資料指標有4個欄位:如<圖九>所示,欄位說明會在解釋完資料緩衝區設計後一倂說明。

|
|
|
資料緩衝區設計 為了方便管理,64KB的資料緩衝區被分成數個Slot,每一個Slot只能被一個訊框佔用,但較大的訊框,可以佔用多個的Slot。在我的設計裡,Slot的數量是可以在Compile硬體電路時作設定的,現在驗證的版本先只做128個Slot,亦即每個Slot 512Byte,因為這樣的版本複雜度較小,需要的CCI也較小。
<圖九>資料指標的欄位的解釋如下: 1. In Rx buffer? :1 bit,指示此資料位於接收端緩衝區或傳送端緩衝區。 2. Slot No.:這筆資料所佔用的第一個Slot編號。 3. Data start offset:代表有效資料的起始差量。 4. Data length:資料長度
值得注意的是,第二項跟第三項合起來,就是一個16Bit的資料緩衝區位址,指向此筆資料的起始點。
邏輯上,data buffer會將所有的訊框內容放置在一整塊記憶體內,然而,實體上因為封包不一定是依序處理完畢,所以會有一個利用連結串列(linked list)的機制,將可以使用的小空間合併成串連的記憶體區塊,以求資料緩衝區使用的效率。但若一個Frame在要求資料緩衝區時可以拿到一整塊的連續空間,那麼linked list的機制就不會啟動,而是將連續的空閒區塊分派給該frame。

如<圖十>所示,資料緩衝區中,因為亂序完成的關係,所空出的空間並不連續,最好的管理機制,就是將這些空的區塊,用linked list連接起來,除了搬移整筆封包資料的機制(例如: 將訊框從MAC搬移到TOE,或是從TOE搬到主記憶體)需要支援linked list外,封包標頭的處理並不需要,因為一個Slot的大小被設定為遠遠大於所有協定標頭的長度總合,所以封包標頭處理時不會跨Slot。
<圖十>中我們可以看到為了支援這種機制需要兩塊空間,我們將這兩塊空間放置在CCI中,所以CCI的記憶體分配如<圖十一>所示。第一塊我們稱為Status bits,在這塊空間裡共有128bit的資料位元,每一個bit都代表資料緩衝區中一個slot的狀態,1為被佔用,0為空閒。第二塊我們稱為linking ptrs (linking pointers),這個區塊的主要目的是紀錄被佔用的data slot互相連結的狀況。本區塊中共有128個單位,每個單位有32個Bits,一個單位對應到一個Slot。如圖所示,最高位元的2bit代表這個Slot的狀態,2’b00代表這個Slot是一筆未被分割的資料的一部分,2’b10代表這個slot是linked list 的一個node,2’b11代表這個slot是linked list的最後一個node;接下來有兩個7bit的欄位,分別代表這個slot中有效資料的開始和結束的偏移量;最後9bit為指向下一個data slot的指標。
要特別注意的是,這種Linked list機制是靠Nios處理器來管理的,在硬體處理標頭時不會動用到Linked list的機制,因為一個Slot的大小。當有資料要送進TOE時,Nios處理器會查閱TOE中的Status bits來尋找空閒的Slot,若有必要則啟動linked list機制將資料存進TOE中。在資料要移出TOE時則會確認是否有linked list的存在,將處理完畢的資料重新串連並送至目的地。

|
|
|
處理流程 傳送封包

圖片說明:<圖十二>以及後面的<圖十三>分別代表傳送以及接收的流程圖,在圖片中被圓形圈起來的部份(流程的開頭與最底部)的部份就是Nios CPU用軟體所負責處理的,方塊部分則是硬體的協定處理模組所負責。流程旁邊用虛線與粗體箭頭連接的方塊,則是硬體處理模組溝通佇列中單一條目的資料結構,我們可以看到TCP_Tx模組傳給IP_Tx模組時,需要如下圖所示的兩個資訊,資料指標以及封包種類。

請回顧”功能說明”的資料緩衝區設計<圖十>及<圖十一>,接收端和傳送端的資料緩衝區在CCI(連線控制資訊, Control Connection Information)有兩塊欄位用來記錄資料緩衝區的狀況:Status bits 和Linking pointers,Status bit以0與1來紀錄Slot空閒與否,Linking pointers則是紀錄每個slot間互相連接的狀況。將資料搬進TOE時,CPU除了控制資料搬移的DMA engine外,還需要去更改這些記錄資料緩衝區狀況的資料結構,以便正確控制處理模組的操作。
<圖十二>為傳送封包的流程圖。 1. 當要傳送的封包在主記憶體裡,cpu會去檢查slot status table裡的status bits看看是否有足夠的空間 ,這時有三種情況發生: a. 足夠的連續空間: 將要使用的空間相對應的status bit 設定為1。 將被要求的Slot相對應的Linking_ptrs 的status bit 設定為00。 b. 足夠的不連續空間: 將要使用的空間相對映的status bit 設定為1。 相對應的Linking_ptrs中的每個欄位都要設定。 c. 沒有足夠的空間:cpu不斷的去檢查,直到有足夠的空間為止
2. CPU呼叫DMA將資料從主記憶體搬到Tx_data_buffer。
3. 在Tx_data_req加入一個條目,告知tcp/ip offload engine 有資料要傳送。 4. 在tcp/ip offload engine裡面每個模組都有相對應的table,資料處理的程序為:上層模組將資料處理完,就將指向資料所在位址的指標加入下層模組的table。因此每個模組只要去查看其table,就知道要處理哪些資料。
5. tcp/ip offload engine 最後一層arp_tx處理完之後,發出中斷訊號,CPU呼叫DMA將資料從Tx_data_buffer搬到MAC buffer,完成封包傳送的動作。
接收封包

1. 當要傳送的封包在主記憶體裡,cpu會去檢查slot status table裡的status bits看看是否有足夠的空間 ,這時有三種情況發生: a. 足夠的連續空間:將要使用的空間相對映的status bit 設定為1,相對應的Linking_ptrs 的status bit 設定為00 b. 足夠的不連續空間: 將要使用的空間相對映的status bit 設定為1,相對應的Linking_ptrs中的每個欄位都要設定 c. 沒有足夠的空間:cpu不斷的去檢查,直到有足夠的空間為止
2. CPU呼叫DMA將資料從MAC buffer搬到Rx_data_buffer
3. 在frame_table加入一個條目,告知TCP/IP offload engine 有接收到資料
4. 在TCP/IP offload engine裡面每個模組都有相對應的table,資料處理的程序為:上層模組將資料處理完,就將指向資料所在位址的指標加入下層模組的table。因此每個模組只要去查看其table,就知道要處理哪些資料。
5. TCP/IP offload engine 最後一層Tcp_rx和udp_rx處理完之後,發出中斷訊號,cpu呼叫dma將資料從Rx_data_buffer搬到主記憶體,完成封包接收的動作。

圖十三為整個系統的架構圖。其中包含了幾個主要元件: 1. Nios cpu, 2. DMA engine, 3. 由Altera sync SRAM 建構成的Main memory(將來考慮使用開發板上的DDR SDRAM配合SDRAM controller作為main memory) 4. Tri-state bridge for Lan91c111 PHY/MAC 5. Custom ASIC TCP/IP Offload Engine
以上元件的連接是由SOPC builder來建立系統,使彼此之間透過Avalon system bus 傳遞資料。我們自行設計的TOE(TCP/IP Offload Engine),總共有5條對外通道,分別是: 1. 接收端CCI系統存取通道、 2. 傳送端CCI系統存取通道、 3. 接收端資料緩衝區系統存取通道、 4. 傳送端資料緩衝區系統存取通道、 5. Register File存取
這些通道是透過sopc builder內的interface to user logic來與avalon system bus 連接,為slave裝置,並透過適當的位址解碼機制,使Nios能透過這個介面來存取TOE的5個通道。
整個系統是由Nios cpu控制,cpu執行放置在main memory裡的程式,這個程式會初始化lan91c111和TOE,接著就等待裝置的interrupt,然後去執行相對應的ISR(Interrupt Service Routing)。本系統有以下幾種ISR: ·Lan91c111 PHY/MAC ISR: 當處理完的封包放在MAC buffer,會發出interrupt,cpu會做以下事情: 1. 檢查slot status table中的status bits來尋找rx_buffer中是否有足夠的空間來放置封包 2. 呼叫DMA將封包從MAC buffer搬到rx_buffer 3. 在Rx_frame中加入一個條目
·LTOE ISR: cpu檢查TOE_status_reg看是TOE的哪一種interrupt 1. 接收封包的interrupt:cpu呼叫dma將處理完成的封包搬到main memory 2. 傳輸封包的interrupt: cpu呼叫dma將處理完成的封包搬到MAC buffer
·L DMA ISR: cpu會去檢查slot status table中的status bits來尋找Tx_buffer中是 否有足夠的空間來放置封包 1. 呼叫DMA將封包從Rx_buffer搬到Tx_buffer 2. 在Tx_frame中加入一個條目
我們的作品有以下的特點: 1. 如果只單純用nios的cpu來處理TCP/IP網路協定,將無法達到100Mbps的速率,但是如果用nios cpu加上TOE這樣的的架構來處理TCP/IP網路協定,就能達到100Mbps的速率。 2. 我們的架構是將每個協定模組化,每個模組都根據各自的表格來做動作,因此可以很容易的加入新的協定,架構上具有很大的彈性。 3. 傳送和接收的模組是分開的,可以平行處理訊框。 4. 支援最多同時8條UDP連線。 5. 硬體ARP table。 6. 硬體UDP連線管理機制。 7. 處理模組在處理訊框時,只互相傳遞訊框所在地指標,減少記憶體的資料搬移。 8. 因為網路功能被硬體實作,在有網路需求的嵌入式系統應用時,可以大大的減低網路動作所佔的Host CPU資源。 9. 資料緩衝區的設計是分成一塊一塊的Slot來管理,簡化資料連結與管理的機制,並且可以簡單的藉由更改設計中的參數,來改變Slot大小的配置以符合不同需求。 10. 我們的系統的目標是用在網路儲存設備上,所以目前設計的參數設定是對儲存網路應用的最佳化。 11. 若只計算MAC接收完畢到存於目的主記憶體上的時間。本系統可以處理100Mbps網路速度的封包。 |
|
|
總結 我覺得對設計系統的人來說,最困難的部份就是做成可觸碰的硬體來實際的做測試,要實作一個擁有CPU、DMA、主記憶體、PCI Bridge、周邊裝置互相連接的系統匯流排的測試,Altera的PCI development board提供了這樣的環境。利用SOPC builder可以很簡單的架構一個這樣的系統,將自己的IP與版子上的周邊相連接,例如本系統就使用了MAC和PHY做為網路裝置,並在上面用熟悉的C語言發展韌體,讓我們透過SOPC builder去架設我們的測試環境,把重心放在硬體處理核心的發展上,只要實做完自己的IP,透過SOPC builder就能實測出效能,大大降低 IP的開發時間。可惜的是,雖然這塊板子提供足夠的I/O,但IP通常不是很便宜,實驗室的資源不夠的話必須花很多時間去補足不夠的子模組,造成美中不足,例如在我們的設計裡,因為沒有適合的DDR SDRAM controller和PCI的橋接器,讓我們的設計無法完全的達到預期的成果,若能提供試用版本的IP或是模擬環境,那對我們的系統開發者真是一大福音。 |
|
|