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