DPDK之什麼是imissed、ierrors、rx_nombuf

WingPig發表於2020-07-23

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對資料包的處理流程,這將對理解這三個統計引數具有較好的幫助。

DPDK抓包流程

  1. 物理網路卡監聽物理鏈路上的資訊號,解析得到資料包,並將其存放在物理網路卡上的RX FIFO中;
  2. 物理網路卡上的DMA將資料包寫入到記憶體中的rte_rx_queue;
  3. 應用程式通過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中的資料包沒有及時消費掉?

  1. 檢查CPU執行模式,cpupower frequency-info 如果當前執行在powersave模式下,可以將其修改為performance,提升CPU頻率,cpupower frequency-set -g performance

  2. 程式效能不佳,無法及時消耗掉rte_rx_queue中的資料包。

ierrrors

這個就沒得辦法了,畢竟本身資料包就有錯誤,接收了也沒啥意思。如果實在想接收,可通過rte_eth_rxconfoffloads成員進行設定。

rx_nombuf

直接增大mempool的大小。

相關文章