DPDK ring簡單說明


1.ring提供的接口

對於一個模塊而言,其對外提供的接口直接表明了它所提供的功能,也是我們分析一個模塊最初的入口。ring是一個環形無鎖隊列,支持多生產者多消費者操作,所以對於隊列的操作構成了模塊的主要接口。ring的實現在文件rte_ring.crte_ring.h中。

rte_ring_create() //ring的創建

rte_ring_init() //ring的初始化

rte_ring_lookup() //ring的查找

rte_ring_free() //ring的釋放

rte_ring_dump() //獲取ring的使用信息

rte_ring_set_water_mark() //設置ring的水標

以上的幾個大的接口提供了ring的開始和結束以及查找。同時對於一個隊列來說,還有更多的入隊,出隊操作。如函數

rte_ring_mp_enqueue_burst()//多生產者批量入隊

此處就省略其他很多單(多)生產者,單(多)消費者的操作函數接口了。

2.ring的創建及初始化

rte ring的創建是通過rte_ring_create()函數來實現的,這個函數的原型struct rte_ring * rte_ring_create(const char *name, unsigned count, int socket_id,unsigned flags)

這里需要注意的是socket_idflags,在多個進程同時訪問同一個ring時,要改善性能,可以創建多個ring,同時要注意多個進程綁定在同一個socket上。另一個參數flags則是表明創建的ring是否安全支持多生產者多消費者模型。接下來就來看看創建及初始化中的一些細節。

首先找到ring_listring_list是掛接在隊列中的,根據ring不跨socket的原則,推斷是每個socket都維護有一個這樣的隊列,具體就不去摳代碼了,先主后次。

接下來就是兩個准備操作:

  • 獲取創建的ring的空間大小,為后面分配空間做准備。

  • 分配一個struct rte_tailq_entry *te;結構,在創建完成ring后,掛接這個隊列元素到隊列中去。此時不妨先看一下這個結構體的定義。

    struct rte_tailq_entry {
    	TAILQ_ENTRY(rte_tailq_entry) next; 
    	/**< Pointer entries for a tailq list */
    	void *data; /**< Pointer to the data referenced by this 	tailq entry */
    };
    

其中的data指針就指向了創建的ring的地址。

然后就是為新創建的ring分配內存空間咯,使用了rte_memzone_reserve()函數分配,這個函數在內存部分詳細說明,但是需要注意:

rte_memzone_reserve()只能用於primary進程中內存分配,也暗含了對於多生產者多消費者使用的ring,其ring的創建要在 primary進程中。

最后就是把分配的ring初始化-rte_ring_init(),並填充te元素,把te掛接在隊列中。

3.ring的出入隊

ring的出入隊操作,我們重點來關注幾個接口:

__rte_ring_mp_do_enqueue()
__rte_ring_sp_do_enqueue()
__rte_ring_mc_do_dequeue()
__rte_ring_sc_do_dequeue()

無論使用的哪個上層接口,最終調用的就是這4個函數。在使用多生產者多消費者時,函數中會有rte_pause()的操作,里面使用了__mm_pause()指令,看注釋意思是避免忙等待,主要應用在短時的loops。至於具體的頭和尾指針的移動,可以參考prog_guide中的ring一節,圖文並茂。

4.ring的使用范圍以及潛在問題

  • 1.ring的調試信息在non_EAL線程中是不支持獲取的。

  • 2.ring支持多生產者入隊和多消費者出隊,但是都是不可搶占的。不可搶占的意思是:

    • 一個線程在做多生產者入隊操作,此時,禁止被另一個做多生產者入隊的線程搶占。
    • 一個線程在做多消費者出隊操作,此時,禁止被另一個做多消費者出隊的縣城搶占。

    這意味着如果兩個線程在同一個core上操作,那么2th線程則必須等到1th線程調度后才能訪問,因此,盡量不要在同一個core上對同一個ring做多生產者同時入隊或者出隊。更詳細的說明,請參考 prog_guide 3.3.4章節。

5.關於水標的使用

在初始化ring的時候,可以設置對應的水標位置,但感覺它並未提供設置接口,用的地方不是很多。比如,當入隊已經達到水標位置時,就可以返回對應的錯誤值,上層調用就可以做些處理。

x.關於無鎖隊列的鏈接:

無鎖隊列頂層設計

無鎖隊列到底有沒有鎖


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM