摘 要:mbuf全稱為“memory buffer”,主要用于保存進程和網絡接口間互相傳遞的用戶數據,也用于保存源與目標地址,套接字選項等。本文基于TCP/IP協(xié)議棧中mbuf的設計思想,設計了一種簡化的mbuf,提供給應用軟件能方便的操作可變長緩存、在緩存的頭部和尾部添加協(xié)議頭數據、從緩存中移除數據,同時通過內存的零拷貝技術,有效地提高CPU的利用率、節(jié)省存儲空間的占用,并且可移植性強,具有較高的實用價值。
關鍵詞:TCP/IP;mbuf;零拷貝;嵌入式
中圖分類號:TP3.0 文獻標識碼:A
1 引言(Introduction)
在有數據通信需求的軟件系統(tǒng)中,數據包的存儲結構,以及傳遞方式直接影響到整個軟件系統(tǒng)的處理性能。有效的數據包存儲管理可以實現內存的“零拷貝”(zero-copy)。零拷貝技術可以減少數據拷貝和共享總線操作的次數,消除通信數據在存儲器之間不必要的中間拷貝過程,從而有效地提高通信效率[1]。存儲器管理最經典的當屬TCP/IP協(xié)議棧中的mbuf。mbuf全稱為“memory buffer”,主要用途是保存在進程和網絡接口間互相傳遞的用戶數據,但也用于保存其他各種數據,如源地址和目標地址、套接字選項等[2,3]。使用mbuf進行報文的傳輸,接收報文并把報文上送上層應用的過程中,報文傳輸是“零拷貝”,即不需要拷貝報文內容,只需要傳送mbuf地址。
TCP/IP協(xié)議棧的復雜性決定了mbuf設計的復雜性,而在我們的更多數據通信軟件應用中,其實僅需要精簡的mbuf支持,比如能方便的操作可變長緩存,能在緩存的頭部和尾部添加協(xié)議頭數據(如下層封裝來自上層的協(xié)議數據)、能從緩存中移除數據(如上層解封裝來自下層的協(xié)議數據),能實現內存的零拷貝[4]?;诖诵枨?,本文秉承TCP/IP協(xié)議棧的mbuf設計思想,重新設計了一種簡化的mbuf庫,將其組織成鏈表的形式裝載數據報文,采用零拷貝技術在協(xié)議棧各層間進行傳遞。
2 mbuf數據庫設計(Design of mbuf database)
本文中設計的mbuf庫,采用mbuf頭部管理信息和數據存儲區(qū)進行分開管理的思想,這樣的設計優(yōu)點是,在申請的數據空間不夠時,可以動態(tài)的獲取更大的數據存儲空間。為mbuf庫設計兩種數據庫資源,一種是mbuf節(jié)點資源池,mbuf節(jié)點用于存放mbuf管理信息;一種是mbuf數據區(qū)資源池,mbuf數據區(qū)資源用于存放真正的應用數據。
2.1 mbuf節(jié)點
mbuf節(jié)點即提供給用戶申請使用的mbuf資源,主要存放一些管理信息,mbuf節(jié)點的數據區(qū)用于存放用戶應用數據,在mbuf資源申請時進行動態(tài)分配,mbuf節(jié)點數據結構主要字段設計如圖1所示。
2.2 mbuf節(jié)點資源池
mbuf節(jié)點資源池由“mbuf空閑鏈表”進行管理,“mbuf空閑鏈表”是一個雙向鏈表,所有未使用的mbuf節(jié)點,均通過自身的node雙向指針掛接到“mbuf空閑鏈表”中,mbuf節(jié)點資源池在初始化時一次申請多個mbuf,申請的mbuf個數和長度由用戶指定,如圖2所示。
2.3 mbuf數據區(qū)
mbuf數據區(qū)用于存放真正的應用數據,數據結構主要字段設計如圖3所示。其中首尾部魔術字用于意外踩內存時的協(xié)助定位,mbuf節(jié)點的結構與linux內核協(xié)議棧的skb_buf相似[5],在保存報文的內存塊前后分別保留headroom和tailroom,以方便應用解封報文,headroom默認128字節(jié),可以通過宏進行調整。數據區(qū)即真正存放用戶數據的區(qū)域,大小不小于申請的size的長度。
2.4 mbuf數據區(qū)資源池
mbuf數據資源池,由“mbuf數據區(qū)資源池數組”進行管理,每一類mbuf數據區(qū)資源池中,均通過雙向鏈表list掛接所有具有相同字節(jié)長度的數據資源,如圖4所示。
3 mbuf功能(Function of mbuf)
3.1 mbuf初始化
使用mbuf庫的應用軟件應根據自身的使用需求進行mbuf資源配置,即要使用的每一類mbuf的字節(jié)長度,以及對應的mbuf個數,如表1所示。
3.2 mbuf申請
mbuf申請時,從“mbuf空閑鏈表”尾部獲取出一個空閑的mbuf節(jié)點資源,然后依次遍歷mbuf數據資源池,查找一個最小的大于申請字節(jié)長度的數據資源,并掛接到mbuf節(jié)點資源的數據區(qū)指針上,申請成功的mbuf節(jié)點資源如圖5所示。
申請成功后的mbuf節(jié)點資源與mbuf數據區(qū)資源建立了一定的鏈接關系,mbuf節(jié)點資源中的data指針將指向mbuf數據資源頭。mbuf節(jié)點資源中head字段指向當前數據區(qū)頭,tail字段指向當前數據區(qū)尾,初次申請成功,head和tail均指向數據頭部。
3.3 mbuf釋放
mbuf釋放時,需要釋放兩類資源,首先將mbuf數據資源釋放到對應字節(jié)長度的mbuf數據資源池中,然后清除mbuf節(jié)點資源中的管理信息[5],并將mbuf節(jié)點資源釋放到mbuf空閑鏈表中。mbuf釋放時,只減引用計數,只有當引用計數為零時,才真正釋放mbuf資源:
3.4 mbuf數據存儲
為了增加應用程序的使用靈活性,應用程序向mbuf中存放應用數據時,提供兩種方式存儲。一種是使用mbuf提供的接口進行安全存儲,還有一種是直接提供mbuf的數據區(qū)指針給用戶,由用戶自行操作mbuf數據區(qū)指針,這種方式就要求自行控制寫入的數據長度,避免越界。
3.4.1 mbuf頭部數據追加
使用TCP/IP協(xié)議棧[6]向網絡上發(fā)送報文時,當本層協(xié)議接收到上層協(xié)議報文后,將在報文頭部封裝本層協(xié)議頭,比如從IP層到數據鏈路層再到物理層,至上而下,逐層進行協(xié)議封裝,基于此應用場景,此功能提供給用戶,在當前mbuf數據區(qū)首部追加指定長度的數據。如圖6所示。
頭部數據追加使用的是頭部預留空間,當頭部預留空間不足時,總空間足夠時,首先會將數據整體向后移動,在頭部留出足夠的空間擴展數據。當頭部預留空間不足,并且用空間也不足時,此時將重新為mbuf節(jié)點申請一個更大的數據資源,然后在頭部追加指定長度的數據,同時舊的數據資源將被釋放掉。
3.4.2 mbuf尾部數據追加
此功能提供給用戶,將當前數據拷貝到mbuf數據區(qū)尾部,實現原理同頭部空間追加,尾部空間擴展時,如果尾部預留空間不足而用空間足夠時,同樣會將數據整體向前移動,然后再將數據追加到尾部。如果尾部空間不足且總空間也不足,此時會申請更大的數據區(qū)資源,然后再進行尾部數據追加,同時舊的數據區(qū)資源將被釋放掉[7]。
3.4.3 mbuf頭部數據移除
使用TCP/IP協(xié)議棧從網絡上接收報文時,當本層協(xié)議接收到下層協(xié)議報文后,將從報文頭部摘除本層協(xié)議頭,比如從物理層到數據鏈路層再到IP層,至下而上,逐層進行協(xié)議解封裝,基于此應用場景,此功能提供給用戶,在當前mbuf數據區(qū)首部移除指定長度的數據。
3.4.4 mbuf尾部數據移除
此功能提供給用戶,從mbuf數據區(qū)尾部移除指定長度的數據。
3.5 mbuf拷貝
3.5.1 mbuf深拷貝
重新申請一個跟當前mbuf一樣size的mbuf,并將原有mbuf中的數據和管理信息一一拷貝到新申請的mbuf中,此時新申請的mbuf是一個新的資源,地址不一樣。
3.5.2 mbuf淺拷貝
在實際使用中,有可能出現一個mbuf報文需要上送給多個應用使用,每一個應用處理完之后自行釋放mbuf,此種應用場景提供mbuf淺拷貝機制mbuf資源使用同一個資源,地址不變,在一次淺拷貝時只增加mbuf的引用計數,當每一個應用處理完畢釋放mbuf時,會將引用計數減1,直到最后一個使用mbuf的應用釋放mbuf時,引用計數為零,才真正執(zhí)行釋放mbuf相關資源的動作。
3.6 mbuf安全設計
在使用mbuf的系統(tǒng)中,難以避免使用了mbuf之后沒有釋放或釋放不及時而導致的資源泄漏[7,8],嚴重的將會引起整個系統(tǒng)mbuf耗盡,所以安全性設計是mbuf設計中重點需要考慮的。有效的調試手段,可以準確地定位到代碼中哪一行沒有釋放mbuf。
3.6.1 查看mbuf節(jié)點資源池
在使用mbuf庫的應用軟件中最常見的錯誤使用方法是申請mbuf后未釋放而導致的資源泄露,如果資源泄露的地方較多,最終將導致mbuf資源耗盡。mbuf庫提供的調試命令可隨時查看,監(jiān)控mbuf資源池的使用情況[8]。圖8是以一個測試應用程序申請mbuf后未釋放的情況為例,展示了在測試程序的運行過程中,通過在shell窗口下面敲入mbuf調試命令,查看到的mbuf節(jié)點資源池使用情況及未釋放mbuf的文件名和列號。
3.6.2 查看mbuf數據資源池
圖9也是以測試程序為例,在shell窗口下查看mbuf數據資源池命令使用情況,通過顯示的詳細信息,可以通過地址查看數據內容,通過首尾魔術字判斷mbuf資源是否被踩內存。
4 結論(Conclusion)
本文設計的簡化mbuf庫,目前已較為廣泛的應用于內部使用的嵌入式軟件中,支持ARM、PPC、DSP各個處理器,同時PC機軟件也支持使用。本文中對mbuf的簡化設計策略,即滿足了應用軟件的方便的操作可變長緩存的使用需求,同時也基于零拷貝的思想,有效地提高CPU的利用率、節(jié)約存儲空間的占用,并且可移植性強,具有較高的實用價值。
參考文獻(References)
[1] Lu Hai,LiqingLi,Xudong.Mbuf Optimizing Implementation Applied in Embedded System[J].IEEE International Conference on Network Infrastructure and Digital Content,2014,4(3):503-506.
[2] W.Richard Stevens.TCP/IP詳解,卷2:實現[M].北京:人民郵電出版社,2016.
[3] Chengcheng Yang,Peiquan Jin.Efficient Buffer Management for Tree Indexes on Solid State Drives[J].International Journal of
Parallel Programming,2016,44 (1):5-25.
[4] Daru Pan,Zhaohua Ruan.A comprehensive-integrated buffer management strategy for opportunistic networks[J].EURASIP Journal on Wireless Communications and Networking,2013(1):1-10.
[5] 左文杰.基于高端路由器IRF堆疊系統(tǒng)的設計與實現[D].中國優(yōu)秀碩士學位論文全文數據庫信息科技輯,2017(12):136-566.
[6] 周末. DPDK結構下類Socket接口研究與設計[D].中國優(yōu)秀碩士學位論文全文數據庫,信息科技輯,2017(2):137-165.
[7] 喬麗.EI內核中Mbuf的簡化研究[J].商丘師范學院學報,2015,
31(9):72-76.
[8] 翟東海,李力.mbuf的實現原理剖析及其在網絡編程中的應用[J].計算機工程與應用,2014(8):104-106.
作者簡介:
張雪鋒(1979-),男,碩士,工程師.研究領域:計算機,電學.