DPDK源碼分析之(1)libmbuf模塊
Author:OnceDay Date:2024年7月2日
漫漫長路,有人對你笑過嘛…
全系列文檔可參考專欄:源碼分析_Once-Day的博客-CSDN博客
參考文檔:
- DPDK download
- Getting Started Guide for Linux — documentation (dpdk.org)
- Sample Applications User Guides — documentation (dpdk.org)
- 14. Mbuf Library — Data Plane Development Kit 24.07.0-rc1 documentation (dpdk.org)
- dpdk/lib/mbuf at main · DPDK/dpdk · GitHub
- TCP/IP Illustrated, Volume 2: The Implementation (kohala.com)
文章目錄
- DPDK源碼分析之(1)libmbuf模塊
- 1. 概述
- 1.1 mbuf介紹
- 1.2 mbuf設計概念
- 1.3 mbuf使用mempool
- 1.4 mbuf對象池構造過程
- 2. mbuf對象定義
- 2.1 mbuf數據結構
- 2.3 mbuf操作函數定義
1. 概述
1.1 mbuf介紹
mbuf
(消息緩沖區)庫提供了分配和釋放緩沖區(mbufs)的功能,這些緩沖區可以被DPDK應用程序用來存儲消息。消息緩沖區存儲在一個稱為mempool(內存池)的結構中,而這個內存池是通過Mempool庫來管理的。
通常情況下,rte_mbuf
結構體用于承載網絡數據包緩沖區,但實際上它可以存儲任何類型的數據(例如控制數據、事件等)。為了提高性能,rte_mbuf
頭部結構被設計得盡可能小,目前只使用了兩個緩存行(cache line),并且最常用的字段被放在第一個緩存行中。
-
內存池(Mempool)管理:內存池庫通過預先分配大量固定大小的內存對象(如mbufs),來提高內存分配和釋放的效率。這種方法避免了頻繁的動態內存分配,從而減少了內存碎片和分配開銷。
-
緩存行優化:緩存行是CPU緩存中存儲數據的最小單位。將頻繁訪問的數據字段放在同一個緩存行中,可以減少CPU緩存未命中(cache miss)的次數,從而提高數據訪問速度。
-
靈活性:
rte_mbuf
不僅能承載網絡數據包,還能用于其他用途,如存儲控制信息或事件消息。這使得它在各種DPDK應用程序中都能發揮作用。
1.2 mbuf設計概念
為了存儲數據包(包括協議頭部),考慮了兩種方法:
- 在單個內存緩沖區中嵌入元數據結構,后面跟一個固定大小的區域用于存儲數據包。優點是只需要一次操作即可分配/釋放整個數據包的內存表示。
- 使用獨立的內存緩沖區分別存儲元數據結構和數據包。更靈活,允許元數據結構的分配與數據包緩沖區的分配完全分離。
DPDK選擇了第一種方法,元數據包含控制信息,如消息類型、長度、數據起始位置的偏移量以及指向其他mbuf結構的指針,從而實現mbuf鏈的功能。
用于承載網絡數據包的消息緩沖區可以處理mbuf鏈,即需要多個緩沖區來保存完整數據包的情況。例如,巨型幀(jumbo frames)由多個通過next字段鏈接在一起的mbufs組成。
對于新分配的mbuf,數據的起始位置位于緩沖區開始后RTE_PKTMBUF_HEADROOM
字節處,該位置是緩存對齊的。消息緩沖區可以用于在系統的不同實體之間傳遞控制信息、數據包、事件等。
消息緩沖區還可以使用其緩沖區指針指向其他消息緩沖區的數據部分或其他結構,稱為間接mbuf,類似于上面的第二種方法。
總結mbuf的設計:
- 單一內存緩沖區,DPDK選擇了在單一內存緩沖區中嵌入元數據結構的設計,簡化了分配和釋放的操作。
- 元數據包含控制信息,元數據結構中包含消息類型、長度、數據起始位置的偏移量以及用于緩沖區鏈的指針。
- 緩沖區鏈,支持緩沖區鏈,允許多個mbufs鏈接在一起,特別適用于需要多個緩沖區來保存完整數據包的情況(如巨型幀)。
- 緩存對齊,新分配的mbuf的數據起始位置經過緩存對齊,位于RTE_PKTMBUF_HEADROOM字節之后,優化了性能。
- 多用途,消息緩沖區不僅用于傳輸數據包,還可以在系統中傳遞控制信息、事件等,具有很高的靈活性。
- 完全標準的mbuf操作函數集合,遵循常見標準和原則的mbuf操作函數實現。
下面是單個段組成的mbuf,一個mbuf持有整個報文的數據:
下面是多個段組成的mbuf,一個主mbuf+多個子mbuf共同持有整個報文的數據:
mbuf的構成如下:
| rte_mbuf | ==> rte_mbuf priv size<== | rte_pktmbuf_headroom | data(Packet data) |
| ==> struct mbuf <== ↓ Headroom(128) | dataroom(2176) |buf.addr ----> data_offset| MBUF_RX_SIZE=2176 |
這是一個帶有私有應用數據的mbuf,其默認headroom是128字節,數據空間是2176字節,rte_mbuf是控制元數據,兩個cache line共128字節。
1.3 mbuf使用mempool
mbuf緩沖區管理器(Buffer Manager)使用內存池庫(Mempool Library)來分配緩沖區。因此,它確保數據包頭在不同的通道和內存組(ranks)之間以最佳方式交錯排列,以便L3緩存處理。
一個mbuf包含一個字段,用于指示其來源的內存池。當調用rte_pktmbuf_free(m)
時,mbuf會返回到其原始的內存池中。
(1) 內存池概述:
- 內存池是一種用于管理固定大小對象集合的高效機制,專門設計用于減少動態內存分配和釋放的開銷。
- 在DPDK中,內存池庫(Mempool Library)負責管理這些內存池,提供快速的對象分配和釋放功能。
(2) 內存池的創建和使用:
- 內存池在初始化時分配一組固定大小的內存塊。這些內存塊可以被反復使用,以提高性能和減少內存碎片。
- 應用程序通過調用
rte_mempool_create()
函數來創建一個新的內存池,并指定每個對象的大小、對象數量以及其他參數。
(3) mbuf和內存池的關系:
- 一個mbuf包含一個字段
pool
,用于指示該mbuf來源的內存池。 - 當分配新的mbuf時,實際上是從指定的內存池中取出一個空閑的內存塊。
- 當釋放mbuf時,通過調用
rte_pktmbuf_free(m)
函數,mbuf會被歸還到其原始的內存池中,這樣可以被再次使用。
(4) 優化性能:
- 內存池的設計考慮了緩存的優化,確保對象分配和釋放操作盡可能地緩存友好,從而提高整體性能。
- 數據包頭在不同的內存通道和組之間交錯排列,有助于優化L3緩存的處理。
(5) 共享和多用途:
- 內存池可以在多個核心之間共享,支持并行處理。
- 除了用于網絡數據包的存儲,內存池還可以用于其他需要高效內存管理的場景,如事件處理和控制信息存儲。
1.4 mbuf對象池構造過程
在DPDK中,消息緩沖區(mbuf)的構造過程由API提供的構造函數完成。以下是詳細的構造過程:
(1) 內存池的創建,首先,需要創建一個內存池(mempool),用于存儲mbuf對象。通過調用rte_mempool_create()
函數來創建內存池。在創建內存池時,可以傳遞一個回調函數,用于初始化每個mbuf對象。
(2) mbuf的初始化,DPDK提供了一個默認的mbuf初始化函數rte_pktmbuf_init()
。
這個函數在創建內存池時作為回調函數傳遞給rte_mempool_create()
,用于初始化每個mbuf對象。rte_pktmbuf_init()
函數會初始化mbuf結構中的一些字段,這些字段一旦設置就不會被用戶修改。具體初始化的字段包括:
- mbuf類型(mbuf type)
- 來源的內存池(origin pool)
- 緩沖區的起始地址(buffer start address)
- 其他一些需要初始化的字段
void rte_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg, void *_m, unsigned i) {struct rte_mbuf *m = _m;memset(m, 0, mbuf_size);/* start of buffer is after mbuf structure and priv data */m->priv_size = priv_size; //mbuf應用數據空間大小,在私有應用數據之后才是報文數據存儲空間m->buf_addr = (char *)m + sizeof(struct rte_mbuf) + priv_size; rte_mbuf_iova_set(m, rte_mempool_virt2iova(m) + mbuf_size);m->buf_len = (uint16_t)buf_len; //mbuf數據空間大小, 包括headroom和tailroom/* keep some headroom between start of buffer and data */m->data_off = RTE_MIN(RTE_PKTMBUF_HEADROOM, (uint16_t)m->buf_len);/* init some constant fields */m->pool = mp;m->nb_segs = 1;m->port = RTE_MBUF_PORT_INVALID;rte_mbuf_refcnt_set(m, 1);m->next = NULL;
}
2. mbuf對象定義
2.1 mbuf數據結構
相關字段如下:
字段 | 大小 | 描述 |
---|---|---|
cacheline0 | ||
buf_addr | 8 bytes(void *) | 報文數據的起始地址(虛擬地址) |
buf_iova | 8 bytes(rte_iova_t) | 報文數據的起始地址(物理地址),總是對齊8字節 |
rearm_data | 在RX描述重裝時會自動清除接下來8個字節的數據 | |
data_off | 2 bytes(uint16_t) | 報文數據的偏移量(相對于buf_addr) |
refcnt | 2 bytes(uint16_t) | mbuf引用計數, 用于廣播報文零拷貝 |
nb_segs | 2 bytes(uint16_t) | mbuf的分段sbuf鏈節點數目,對于一個mbuf不夠的報文有效 |
port | 2 bytes(uint16_t) | 報文的輸入/輸出端口ID(port) |
ol_flags | 8 bytes(uint64_t) | 網卡硬件卸載特性 |
rx_descriptor_fields1 | ||
packet_type | 4 bytes(uint32_t) | 報文數據類型(L2/L3/L4層和隧道信息) |
l2_type(4 bits) | 外層報文的L2類型信息 | |
l3_type(4 bits) | 外層報文的L3類型信息 | |
l4_type(4 bits) | 外層報文的L4類型信息 | |
tun_type(4 bits) | 隧道類型信息 | |
inner_esp_next_proto(8 bit) | inner_esp_next_proto(隧道內層信息) | |
inner_l2_type(4 bit) | 內層報文的L2類型信息 | |
inner_l3_type(4 bit) | 內層報文的L3類型信息 | |
inner_l4_type(4 bit) | 內層報文的L4類型信息 | |
pkt_len | uint32_t(4 byte) | 整個報文長度(包括所有關聯mbuf的數據長度之和) |
data_len | uint16_t(2 byte) | 當前mbuf的報文數據長度(只計算當前mbuf的數據空間) |
vlan_tci | uint16_t(2 type) | (cpu order)VLAN ID,如果RTE_MBUF_F_RX_VLAN存在 |
hash | 8 bytes(聯合體) | 報文hash相關信息 |
rss(4 byte) | 網卡RSS哈希的結果 | |
fdir(8 byte) | 網卡FDIR的標識信息 ,包括lo(hash+id) + hi | |
sched( 8byte) | 調度隊列信息(queue id/traffic class/color) | |
txadater(8 bytes) | dpdk事件設備(eventdev)的關聯發送隊列(txq) | |
vlan_tci_outer | uint16_t(2 bytes) | (cpu order)外層VLAN ID,如果RTE_MBUF_F_RX_QINQ存在 |
buf_len | uint16_t(2 bytes) | 當前mbuf的數據空間大小(初始化時給定值) |
pool | struct rte_mempool*(8 bytes) | 當前mbuf所屬的內存池 |
cacheline1 | 0 byte | |
next | struct rte_mbuf *(8 bytes) | 長報文的分段mbuf鏈表,最后一個節點next需要為零 |
tx_offload | uint64_t (8 bytes) | 發送網卡硬件卸載信息 |
l2_len | L2 (MAC) Header Length for non-tunneling pkt。 Outer_L4_len + … + Inner_L2_len for tunneling pkt | |
l3_len | L3 (IP) Header Length. | |
l4_len | L4 (TCP/UDP) Header Length. | |
tso_segsz | TCP TSO segment size | |
outer_l3_len | Outer L3 (IP) Hdr Length | |
outer_l2_len | Outer L2 (MAC) Hdr Length | |
shinfo | 12 bytes | struct rte_mbuf_ext_shared_info,mbuf關聯的外部數據信息。 |
priv_size | uint16_t(2 bytes) | mbuf私有數據大小,作為外層應用的mbuf的實際大小來使用。 |
timesync | uint16_t(2 bytes) | Timesync flags for use with IEEE1588 |
dynfield1 | 9 * 4 bytes | 動態使用字段 |
2.3 mbuf操作函數定義
相關操作函數和宏定義如下:
操作名稱 | 描述 |
---|---|
rte_pktmbuf_mtod_offset | 返回在指定偏移量處的指定類型指針,使用需要注意mbuf數據地址的連續性(是否都在一個mbuf里),即mbuf->buf_addr + mbuf->data_off + offset 位置。 |
rte_pktmbuf_mtod | 返回偏移量0處指定類型指針,即mbuf->buf_addr + mbuf->data_off 位置。 |
rte_pktmbuf_iova_offset | 與rte_pktmbuf_mtod_offset類似,但返回的是物理地址(而不是虛擬地址)。 |
rte_pktmbuf_iova | 與rte_pktmbuf_mtod類似,但返回的是物理地址(而不是虛擬地址)。 |
rte_get_rx_ol_flag_name | 獲取Rx offload標識的字符串化表示,一次一個。 |
rte_get_rx_ol_flag_list | 獲取Rx offload標識的字符串化表示,可以多個標識。 |
rte_get_tx_ol_flag_name | 獲取Tx offload標識的字符串化表示,一次一個。 |
rte_get_tx_ol_flag_list | 獲取Rx offload標識的字符串化表示,可以多個標識。 |
rte_mbuf_prefetch_part1 | L1緩存預取mbuf第一個cache line的數據 |
rte_mbuf_prefetch_part2 | L1緩存預取mbuf第二個cache line的數據 |
rte_mbuf_iova_get | 獲取mbuf數據的IOVA(虛擬IO地址,IOMMU管理和映射)(mbuf->buf_iova)。 如果RTE_IOVA_IN_MBUF未使能,則等于虛擬地址(mbuf->buf_addr)。 |
rte_mbuf_iova_set | 設置IOVA地址,如果RTE_IOVA_IN_MBUF使能,改變mbuf->buf_iova,否則無操作。 |
rte_mbuf_data_iova | 獲取mbuf報文數據的起始IOVA地址,加上mbuf->data_off。 |
rte_mbuf_data_iova_default | 返回默認的mbuf報文數據的起始IOVA地址,固定data offset為RTE_PKTMBUF_HEADROOM(128) |
rte_mbuf_from_indirect | 從一個indirect mbuf的bufffer addr獲取其direct(源) mbuf的首地址(指針偏移得到)。 |
rte_mbuf_buf_addr | 從mbuf的地址和mempool對象獲取mbuf buffer addr |
rte_mbuf_data_addr_default | 從mbuf的地址和mempool對象獲取mbuf buffer addr + RTE_PKTMBUF_HEADROOM地址 |
rte_mbuf_to_baddr | 獲取mbuf buffer addr,從mbuf地址+mempool對象里的mbuf私有數據空間大小算出 |
rte_mbuf_to_priv | 返回mbuf私有數據空間的起始地址 |
rte_pktmbuf_priv_flags | 返回mbuf私有數據的flags,這是mbuf提供的一種標準私有數據定義。 |
rte_mbuf_sanity_check | mbuf合規檢測,通常用于debug模式,有問題直接panic。 |
rte_mbuf_check | mbuf合規檢測,通常用于debug模式,有問題返回錯誤原因字符串。 |
__rte_mbuf_raw_sanity_check | 原始mbuf合規檢測(refcnt=1, next=null, nb_segs=1,通常用于debug模式,有問題直接panic。 |
rte_mbuf_refcnt_read | 讀取mbuf引用計數,relaxed松散內存序。 |
rte_mbuf_refcnt_set | 寫入mbuf引用計數,relaxed松散內存序。 |
__rte_mbuf_refcnt_update | 更新mbuf引用計數,獲取-釋放內存序(acquire &release ) |
rte_mbuf_ext_refcnt_read | 讀取mbuf擴展共享數據的引用計數,relaxed松散內存序。 |
rte_mbuf_ext_refcnt_set | 設置mbuf擴展共享數據的引用計數,relaxed松散內存序。 |
rte_mbuf_ext_refcnt_update | 更新mbuf擴展共享數據的引用計數,獲取-釋放內存序(acquire &release ) |
rte_mbuf_raw_alloc | 原始方式從mempool申請一個mbuf,buf_addr/buf_iova/buf_len/refcnt=1/nb_segs/next/pool/priv_size等信息應該為重置值。 |
rte_mbuf_raw_free | 原始方式釋放一個mbuf到mempool,不建議使用,除非優化性能。 |
rte_pktmbuf_init | mempool創建時的初始化函數,用于初始化mbuf全局默認值。 priv_size/buf_addr/buf_iova/buf_len/data_off/pool/nb_segs/port/refcnt/next 其中data_off/nb_segs/port/refcnt/next屬于會change的值,需要釋放時reset。 |
rte_pktmbuf_pool_init | 初始化mempool中私有數據,主要是mbuf的數據空間和私有應用數據空間的大小。 |
rte_pktmbuf_pool_create | 創建一個mbuf mempool,提供mbuf數目,私有應用數據和報文數據空間大小等參數。 |
rte_pktmbuf_pool_create_by_ops | 與rte_pktmbuf_pool_create類似,但是可以指定mempool ops name。 |
rte_pktmbuf_pool_create_extbuf | 與rte_pktmbuf_pool_create類似,但是mbuf的數據存放于外部memory空間。 |
rte_pktmbuf_data_room_size | 獲取mbuf的數據空間大小(包括RTE_PKTMBUF_HEADROOM) |
rte_pktmbuf_priv_size | 獲取mbuf的私有應用數據空間大小,在rte_mbuf和報文數據之間。 |
rte_pktmbuf_reset_headroom | 重置mbuf的data_off到默認的headroom起始位置。 |
rte_pktmbuf_reset | 重置mbuf的數據,next/pkt_len/tx_offload/vlan_tci/vlan_tci_outer/nb_segs/ port/ol_flags/packet_type/data_off/data_len已初始化。 |
rte_pktmbuf_alloc | 從內存池中申請一個mbuf,然后使用rte_pktmbuf_reset進行重置 |
rte_pktmbuf_alloc_bulk | 一次從內存池申請多個mbuf,然后使用rte_pktmbuf_reset進行重置 |
rte_pktmbuf_ext_shinfo_init_helper | 初始化mbuf的外部共享信息數據結構體,數據需要滿足對齊關系。 |
rte_pktmbuf_attach_extbuf | 初始化mbuf的外部共享數據,改變buf_addr/buf_iova/buf_len/data_len/data_off=0/ol_flags/shinfo。 修改完成之后,可以調用rte_pktmbuf_reset_headroom/rte_pktmbuf_adj來修復data_len和data_off的值。 |
rte_pktmbuf_detach_extbuf | 與rte_pktmbuf_detach一致。 |
rte_mbuf_dynfield_copy | 拷貝rte_mbuf的動態字段dynfield的值。 |
__rte_pktmbuf_copy_hdr | 拷貝rte_mbuf的頭部數據,port/vlan_tci/vlan_tci_outer/tx_offload/hash/packet_type。 調用rte_mbuf_dynfield_copy拷貝動態空間數據。 |
rte_pktmbuf_attach | 將一個mbuf attach到另外一個mbuf上,這種mbuf成為indirect mbuf。 indirect mbuf在attach之前,必須是direct mbuf,其refcnt計數必須為1。 目標mbuf是extbuf,則增加shared info的引用計數,且拷貝ol_flags和shinfo。 目標mbuf是indirect mbuf,增加其源mbuf的引用計數,和普通mbuf一樣,拷貝priv_size和ol_flags。 調用**__rte_pktmbuf_copy_hdr**拷貝頭部數據。 拷貝data_off/data_len/buf_iova/buf_addr/buf_len/next/pkt_len/nb_segs=1。 |
__rte_pktmbuf_free_extbuf | 釋放mbuf的extbuf,通過shinfo信息,如果shinfo引用計數為0,則釋放extbuf。 |
__rte_pktmbuf_free_direct | 減少direct mbuf的引用數目,如果引用計數為0,則直接釋放掉direct mbuf。 next/nb_segs=1/refcnt=1, 然后放回mempool |
rte_pktmbuf_detach | 解除一個indirect mbuf的attach狀態。 如果mbuf存在extbuf,對于Pinned類型直接Pass。對于其他類型,則調用 __rte_pktmbuf_free_extbuf 。如果不存在extbuf,直接調用 __rte_pktmbuf_free_direct ,釋放對應的direct mbuf。重置priv_size,buf_addr,buf_iova,buf_len,data_off,data_len,ol_flags。 |
__rte_pktmbuf_pinned_extbuf_decref | mbuf釋放過程的pinned extbuf處理,重置ol_flags = RTE_MBUF_F_EXTERNAL。 如果引用計數為1,則直接結束。如果不為1,則先減去1,最后操作返回值為0的線程再重置為1。 |
rte_pktmbuf_prefree_seg | 減少mbuf引用計數,并且判斷是否可以free mbuf segment。 mbuf引用計數為1,如果mbuf是indirect mbuf,調用rte_pktmbuf_detach。 對于indirect mbuf且存在pinned extbuf,如果extbuf refcnt為1,則需要釋放mbuf segment。 mbuf釋放操作:next=null,nb_segs=1,返回mbuf(可以回收和釋放)。 mbuf引用計數不為1,則減一后為0的線程繼續上述釋放操作,并且重置mbuf引用計數為1。 |
rte_pktmbuf_free_seg | 通過rte_pktmbuf_prefree_seg判讀mbuf segment是否可以釋放,通過rte_mbuf_raw_free來釋放。 |
rte_pktmbuf_free | 釋放mbuf到mempool池中,支持chain mbuf釋放操作。 |
rte_pktmbuf_free_bulk | 批量釋放mbuf到mempool池中,相當于可以臨時緩存mbuf。 |
rte_pktmbuf_clone | 基于已有mbuf創建一個clone mbuf,每個mbuf segment都會attach,原mbuf會變成只讀mbuf。 |
rte_pktmbuf_copy | 基于已有mbuf創建一個全量復制的mbuf,但是private data不會拷貝,兩個mbuf將是獨立存在的。 可以指定拷貝的報文數據長度,調用**__rte_pktmbuf_copy_hdr**來copy頭部。 拷貝會去掉RTE_MBUF_F_INDIRECT和RTE_MBUF_F_EXTERNAL,拷貝后mbuf具有完整的數據。 拷貝mbuf不是逐個mbuf segment拷貝,而是會重新整合數據,盡量填充每個mbuf segment。 |
rte_pktmbuf_refcnt_update | 更新mbuf的每個mbuf segment的引用計數。 |
rte_pktmbuf_headroom | 獲取mbuf的headroom長度,來自data_off。 |
rte_pktmbuf_tailroom | 獲取mbuf的tailroom長度,來自buf_len - data_off - data_len。 |
rte_pktmbuf_lastseg | 獲取mbuf的最后一個lastseg。 |
rte_pktmbuf_pkt_len | 獲取mbuf的報文長度。 |
rte_pktmbuf_data_len | 獲取mbuf的數據長度。 |
rte_pktmbuf_prepend | mbuf報文數據向前擴展指定字節,即嘗試減少headroom空間,所以最大上限是headroom大小(data_off=0)。 |
rte_pktmbuf_append | 在mbuf后面添加指定字節的數據,嘗試減少tailroom,如果空間不足,返回NULL。 |
rte_pktmbuf_adj | 移動mbuf的報文數據指針,即data_off,只在第一個mbuf segment移動,不能超過data_len。 |
rte_pktmbuf_trim | 裁剪mbuf的尾部數據,裁剪數據長度不能超過最后一個mbuf segment的數據長度(data_len)。 |
rte_pktmbuf_is_contiguous | 檢查mbuf的數據空間是否連續,即mbuf->nb_segs==1。 |
__rte_pktmbuf_read | 在mbuf指定偏移處讀取指定長度的數據。 |
rte_pktmbuf_read | 如果目標數據是連續的,那么直接返回對應地址的指針,如果非連續,則拷貝到用戶buffer中。 |
rte_pktmbuf_chain | 將兩個mbuf連接起來。 |
rte_mbuf_tx_offload | 基于給定的offload參數生成tx_offload值。 |
rte_validate_tx_offload | 檢查tx_offload的正確性和完整性(ol_flags)。 |
rte_pktmbuf_linearize | 將mbuf的數據連續化,要求單個mbuf能放下數據,并且原來的多個mbuf segment被free掉了。 |
rte_pktmbuf_dump | 可以dump mbuf的數據。 |
rte_mbuf_sched_queue_get | 獲取mbuf調度隊列的ID。 |
rte_mbuf_sched_traffic_class_get | 獲取mbuf的traffic class id。 |
rte_mbuf_sched_color_get | 獲取mbuf的color字段ID。 |
rte_mbuf_sched_get | 獲取mbuf的queue_id/traffic_class/color的值。 |
rte_mbuf_sched_queue_set | 設置mbuf的隊列ID。 |
rte_mbuf_sched_traffic_class_set | 設置mbuf的class ID。 |
rte_mbuf_sched_color_set | 設置mbuf的color ID。 |
rte_mbuf_sched_set | 設置mbuf的queue_id, traffic_class and color。 |