DPDK之什麼是imissed、ierrors、rx_nombuf

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的大小。

Tags: