DPDK之什麼是imissed、ierrors、rx_nombuf
在採用DPDK進行網路抓包時常常會通過rte_eth_stats_get
函式獲取當前網路卡的丟包狀態,首先看一下該函式的宣告:
// 函式宣告(dpdk-stable-19.11.3/lib/librte_ethdev/rte_ethdev.h)
int rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats);
// rte_eth_stats 結構體(dpdk-stable-19.11.3/lib/librte_ethdev/rte_ethdev.h)
struct rte_eth_stats {
uint64_t ipackets; /**< Total number of successfully received packets. */
uint64_t opackets; /**< Total number of successfully transmitted packets.*/
uint64_t ibytes; /**< Total number of successfully received bytes. */
uint64_t obytes; /**< Total number of successfully transmitted bytes. */
uint64_t imissed;
/**< Total of RX packets dropped by the HW,
* because there are no available buffer (i.e. RX queues are full).
*/
uint64_t ierrors; /**< Total number of erroneous received packets. */
uint64_t oerrors; /**< Total number of failed transmitted packets. */
uint64_t rx_nombuf; /**< Total number of RX mbuf allocation failures. */
可以看到rte_eth_stats
結構體中包含imissed、ierrors、rx_nombuf三個與抓包效能相關的統計量,以下內容將對其進行展開介紹。
DPDK 資料包處理流程
在對以上三個統計量進行展開介紹之前有必要介紹一下DPDK對資料包的處理流程,這將對理解這三個統計引數具有較好的幫助。
- 物理網路卡監聽物理鏈路上的資訊號,解析得到資料包,並將其存放在物理網路卡上的RX FIFO中;
- 物理網路卡上的DMA將資料包寫入到記憶體中的rte_rx_queue;
- 應用程式通過PMD的形式輪詢從rte_rx_queue讀取資料包。
三個引數解析
imissed
imissed發生在上述DPDK抓包流程的第二步,表示rte_rx_queue已經塞滿了資料包,所以該包被丟失。此時該包存在於物理網路卡的RX FIFO中,但是不會存在於記憶體中的rte_rx_queue中。
ierrors
ierrors發生在上述第一步中,表示該資料包存在錯誤,被網路卡丟棄。此時該包不會存在於物理網路卡的RX FIFO中,更不會存在於記憶體中的rte_rx_queue中。
// dpdk-stable-19.11.3/drivers/net/ixgbe/ixgbe_ethdev.c:3369
stats->ierrors = hw_stats->crcerrs +
hw_stats->mspdc +
hw_stats->rlec +
hw_stats->ruc +
hw_stats->roc +
hw_stats->illerrc +
hw_stats->errbc +
hw_stats->rfc +
hw_stats->fccrc +
rx_nombuf
rx_nombuf記錄在讀取資料包時分配mbuf錯誤的次數,一般情況下不會影響網路卡的丟包(imissed、ierrors)。該變數的維護在dpdk-stable-19.11.3/drivers/net/ixgbe/ixgbe_rxtx.c:1651:rx_recv_pkts中。
解決方法
上面講了那麼多,那麼如何才能降低丟包呢?
imissed
如上所述imissed
表示從網路卡到記憶體寫入資料包時的丟包個數,因此需要從以下2個方面進行除錯:
1. PCIe是否存在瓶頸?
因為報文從網路卡到系統是經過PCIe匯流排來傳輸的,PCIe匯流排的吞吐將直接影響資料包從網路卡拷貝到記憶體的速率。通過lspci -s 03:00.1 -vv | grep Lnk
可以檢視當前網路卡的PCIe速率,其中03:00.1是網路卡的PCIe地址,可通過lspci -v|grep Ethernet
查到。
由上圖可以看到網口能力是傳輸速率5GT/s,匯流排寬頻x8(LnkCap),實際使用的是傳輸速率5GT/s,匯流排寬頻x8(LnkSta),工作正常。如果傳輸速率和匯流排頻寬下降,則需要除錯PCIe相容性問題。一般是伺服器與網路卡相容性問題,可以更換網路卡或者更換伺服器。如果有條件,可以找伺服器廠商從bios等方面進行詳細定位解決相容性問題。
2. rte_rx_queue中的資料包沒有及時消費掉?
檢查CPU執行模式,
cpupower frequency-info
如果當前執行在powersave模式下,可以將其修改為performance,提升CPU頻率,cpupower frequency-set -g performance
。程式效能不佳,無法及時消耗掉
rte_rx_queue
中的資料包。
ierrrors
這個就沒得辦法了,畢竟本身資料包就有錯誤,接收了也沒啥意思。如果實在想接收,可通過rte_eth_rxconf
的offloads
成員進行設定。
rx_nombuf
直接增大mempool
的大小。