DPDK疑难杂症之网卡Imiss/ierror/i-nombuf问题

DPDK疑难杂症之网卡Imiss/ierror/i-nombuf问题目录问题分析网卡初始化与收包整体流程收包队列的构造网卡启动收包流程入队出队总结参考问题分析网卡初始化与收包整体流程一个网络报文从网卡接收到被应用处理 中间主要需要经历两个阶段 阶段一 网卡通过其 DM

大家好,欢迎来到IT知识分享网。

问题

基础

imiss 的定义

在这里插入图片描述

参考:dpdk api eth_stats

如上:ixgbe 驱动的网卡的 oerror 一直是0

其他统计

rx-errors/ierrors

在这里插入图片描述
ierrors: 表示该数据包存在错误,被网卡丢弃。此时该包不会存在于物理网卡的RX FIFO中,更不会存在于内存中的rte_rx_queue(ring buffer)中。
比如:packets with incorrect checksum, runts, giants etc.

rx-nombuf

在这里插入图片描述
rx_nombuf记录在读取数据包时分配mbuf错误的次数,一般情况下不会影响网卡的丢包(imissed、ierrors)。
比如:RX packet was drop due to lack of free mbufs in the mempool.

  • 解决
    直接增大mempool的大小。

rx_discards_phy

在这里插入图片描述
SW: software
按照上面的理解:
rte_eth_stats_get 指的是软件的技术,那么imiss就是ring buffer满的统计;
rte_eth_xstats_get 展示了物理端口的一些统计计数(通过寄存器),rx_discards_phy 的统计应该是网卡的硬件缓存满或者PCIe 总线阻塞导致无法把包发送给内核的内存中。



在这里插入图片描述
Mellanox 网卡的 ethtool统计分类

我的理解

Most drivers interchange their use of the counters rx_missed_errors, rx_fifo_errors, and rx_over_errors, but they typically set one or more of these counters to the MPC (missed packet count) counter, which is incremented when a packet arrives and is lost because the card's FIFO queue is full. 

上面这段话就是说,ethtool的输出中,不同网卡,不同固件版本,其输出可能都不一样,有rx_dropped,rx_fifo_error, rx_missed_errors, rx_discards_phy 等等。这些MPC (missed packet count) counter都应该代表的是网卡的Rx FIFO queue满了。

对于Ixgbe网卡:

$ grep rx_missed_errors drivers/net/ixgbe/* drivers/net/ixgbe/ixgbe_ethtool.c: {"rx_missed_errors", IXGBE_STAT(net_stats.rx_missed_errors)}, drivers/net/ixgbe/ixgbe_main.c: adapter->net_stats.rx_missed_errors = total_mpc; 
  • 理解一:rx_fifo error就理解为硬件的队列满了
  • 理解二:ethtool查看队列大小以及队列个数,可能就是ring buffer的大小以及个数。

实际上多队列的网卡硬件队列和ring buffer应该也有一个映射关系吧。可能是多个队列对应一个ring buffer。或者一个硬件的接收缓冲区,然后通过RSS、FDIR给映射到指定的 内核的 ring buffer中。

查看 # ethtool -g eth0 Ring parameters for eth0: Pre-set maximums: RX: 18811 RX Mini: 0 RX Jumbo: 0 TX: 2560 Current hardware settings: RX: 10486 RX Mini: 0 RX Jumbo: 0 TX: 192 设置 # ethtool -G eth0 rx 18000 tx 2500 

AIGC回复

intel 82599 10G网卡的统计: # ethtool -S eth03 | grep -i -e miss -e out_of -e disca -e fifo fdir_miss: 0 rx_fifo_errors: 0 rx_missed_errors: 0 tx_fifo_errors: 0 Mellanox Cx4-Lx 25G网卡的统计: # ethtool -S eth03 | grep -i -e disc -e fifo -e out_of rx_out_of_buffer: 0 rx_out_of_range_len_phy: 0 rx_discards_phy:  tx_discards_phy: 0 rx_prio0_discards:  rx_prio1_discards: 0 rx_prio2_discards: 0 rx_prio3_discards: 0 rx_prio4_discards: 0 rx_prio5_discards: 0 rx_prio6_discards: 0 rx_prio7_discards: 0 

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

PCIe版本以及速率

为什么需要Pcie

在电脑里,不同的设备要想交互数据,就必须要经过一定的通道。

  • 总线
    总线就是计算机里,用于走数据的“路”。
  • 内部总线
    CPU核心和cache缓存交互数据的时候,使用的就是内部总线,这个总线只在CPU内交互数据。
  • 外部总线
    但是CPU不可能就自己在那空算数吧,他总要和其他设备交互数据,就需要用到外部总线了,CPU会通过外部总线和其他的设备比如硬盘,网卡,声卡,USB设备沟通,我们这个文章想要介绍的PCI-E就是外部总线的一种。
  • pcie的作用
    在这里插入图片描述
    PCI-E既是通道,也是接口,当他以接口形式存在的时候,就是我们主板上那长长的槽。

  • pcie 通道
    PCIe用于系统中的不同模块之间的通信。 网络适配器(网卡)需要与CPU和内存(以及其他模块)进行通信。 这意味着为了处理网络流量,应正确配置PCIe为不同设备进行通信。 将网络适配器连接到PCIe时,它将自动协商网络适配器和CPU之间支持的最大功能。
  • pcie 接口
    目前的声卡和网卡都是主板集成了,不需要我们额外再插,所以PCI-E接口目前最大的作用就是插显卡,除了显卡还有无线网卡,万兆有线网卡这些高带宽设备,除了这些,PCI-E接口也可以转接成很多接口,比如USB3.0,Type-c。
    在这里插入图片描述

pcie属性之宽度

# lspci -s 04:00.0 -vvv | grep Width LnkCap: Port #0, Speed 8GT/s, Width x8, ASPM not supported, Exit Latency L0s unlimited, L1 unlimited LnkSta: Speed 8GT/s, Width x8, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt- 

pcie属性之速度

# lspci -s 04:00.0 -vvv | grep PCIeGen [V0] Vendor specific: PCIeGen3 x8 

pcie 速率表

  • 查看主板上的PCI插槽’
# dmidecode | grep -i "PCI" 

在这里插入图片描述

  • 不同PCIe版本对应的传输速率
    在这里插入图片描述
    传输速率为每秒传输量GT/s,而不是每秒位数Gbps,因为传输量包括开销位; 比如 PCIe 1.x和PCIe 2.x使用8b / 10b编码方案,导致占用了20% (= 2/10)的原始信道带宽。

  • GT/s —— Giga transation per second (千兆传输/秒
    即每一秒内传输的次数。重点在于描述物理层通信协议的速率属性,可以不和链路宽度等关联。
  • Gbps —— Giga Bits Per Second (千兆位/秒)。
    GT/s 与Gbps 之间不存在成比例的换算关系。
  • PCIe 吞吐量(可用带宽)计算方法:
    吞吐量 = 传输速率 * 编码方案
    例如:PCI-e2.0 协议支持 5.0 GT/s,即每一条Lane 上支持每秒钟内传输 5G次;但这并不意味着 PCIe 2.0协议的每一条Lane支持 5Gbps 的速率。
    因为PCIe 2.0 的物理层协议中使用的是 8b/10b 的编码方案。 即每传输8个Bit,需要发送10个Bit;这多出的2个Bit并不是对上层有意义的信息。
    那么, PCIe 2.0协议的每一条Lane支持 5 * 8 / 10 = 4 Gbitps = 500 MB/s 的速率。
    以一个PCIe 2.0 x8的通道为例,x8的可用带宽为 4 * 8 = 32 Gbps = 4 GB/s。




查看 pcie 设备带宽(带宽上限和实际带宽)

lspci -vv | grep -i PCI-ID -A 40 

在这里插入图片描述

  • LnkCap: 链路能力;
    LnkCap 代表的是卡片本身支持的最高速度。
  • LnkSta: 链路状态;
    LnkSta 代表是实际跑的的速度, 如果正常应该要和 LnkCap 一样, 才能获得最大的带宽。如果发现 LnkSta 的速度比LnkCap 小, 那就要追一下是不是插槽本身的速度就有限制。

pcie 插槽插入单卡双口/单卡四口网卡

所以:Pcie 插槽的带宽 要 大于 单卡两口/多口的带宽之和
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


分析

在这里插入图片描述
一个网络报文从网卡接收到被应用处理,中间主要需要经历两个阶段:

  • 阶段一:网卡通过其DMA硬件将收到的报文写入到收包队列中(入队)

如果入队道路拥塞将会导致报文无法入队(入队)

  • 阶段二:应用从收包队列中读取报文(出队)

如果出队慢将导致队列溢出(出队)

注:DMA是硬件,目的将数据包从网卡送到操作系统(ring buffer),期间不需要CPU的参与,节省了CPU。

网卡初始化与收包

整体流程

  • DPDK对数据包的处理流程
    在这里插入图片描述

在这里插入图片描述

收包队列的构造

收包队列的构造主要是通过调用网卡队列设置函数rte_eth_rx_queue_setup(dpdk rte_ethdev.h)来完成。

收包队列的结构体为ixgbe_rx_queue,该结构体里包含两个重要的环形队列rx_ring和sw_ring,rx_ring和sw_ring的关系可以简单如下:

其中,报文数据的物理地址可以由报文数据的虚拟地址转化得到。

rx_ring

在这里插入图片描述
rx_ring是由一个动态申请的数组构建的环形队列,队列的元素是ixgbe_adv_rx_desc类型,队列的长度为(4096+4-1)。
在这里插入图片描述

pkt_addr:报文数据的物理地址,网卡DMA将报文数据通过该物理地址写入对应的内存空间。

DD位(Descriptor Done Status)用于标志标识一个描述符buf是否可用

  • 放入队列
    网卡每次来了新的数据包,就检查rx_ring当前这个buf的DD位是否为0,如果为0那么表示当前buf可以使用,就让DMA将数据包copy到这个buf中,然后设置DD为1。如果为1,即最上面的buf都不可用,那么网卡就认为rx_ring队列满了,直接会将这个包给丢弃掉(0->1)。
  • 从队列中取
    对于应用而言,DD位使用恰恰相反,在读取数据包时,先检查DD位是否为1,如果为1,表示网卡已经把数据包放到了内存中,可以读取,读取完后,再放入一个新的buf并把对应DD位设置为0。如果为0,就表示没有数据包可读。(1->0)

sw_ring

在这里插入图片描述
sw_ring是由一个动态申请的数组构建的环形队列,队列的元素是ixgbe_rx_entry类型,队列的大小可配,一般最大可配4096。
在这里插入图片描述

mbuf:报文mbuf结构指针,mbuf用于管理一个报文,主要包含报文相关信息和报文数据。

网卡启动

收包流程

收包由网卡入队和应用出队两个操作完成。

入队

在这里插入图片描述
入队的操作是由网卡DMA来完成的。

DMA(Direct Memory Access,直接存储器访问)是系统和网卡(外设)打交道的一种方式,该种方式允许在网卡(外部设备)和系统内存之间通过PCIe总线直接读写数据,这样能有效减轻CPU的工作

在这里插入图片描述
网卡收到报文后,先存于网卡本地的buffer-Rx(Rx FIFO)中,然后由DMA通过PCI总线将报文数据写入操作系统的内存中,即数据报文完成入队操作。(PS:PCIe总线可能成为网卡带宽的瓶颈)

出队

应用调用rte_eth_rx_burst(dpdk rte_ethdev.h)函数开始批量收包,最大收包数量由参数nb_pkts决定(比如设置为64)。其核心流程由ixgbe_recv_pkts(dpdk ixgbe_rxtx.c)实现。

从接口的收包队列rxq->rx_ring 的 rx_tail位置开始收,循环读取一个报文、填空一个报文(空报文数据),读取64个后,重新标记rx_tail的位置,完成出队操作,将收取的报文作返回供应用处理。

入队丢包可能性

入队问题主要集中在PCIe异常“降速”方面。因为报文从网卡到系统是通过DMA经过PCIe总线来传输的,PCIe总线的吞吐将直接影响入队的速率。

pcie 实际带宽和理论带宽不符合

若网口出现imissed,可通过lspci -vv命令查看PCIe理论能力与实际使用是否一致。

解决

一般是服务器PCIe插槽与网卡兼容性问题,可以更换网卡或者更换服务器PCIe插槽。如果有条件,可以找服务器厂商从bios等方面进行详细定位解决兼容性问题。

出队丢包可能性

出队问题主要集中在应用程序性能不高、程序设计不优和CPU错误降频等方面。

DPDK程序性能不高

DPDK程序的实际CPU使用率达到100%,不能及时处理队列报文,导致队列报文溢出,持续imissed++,此时出队平均速率是小于入队平均速率。

解决

inux系统下可以使用perf性能分析工具,做热点函数分析,perf安装命令yum install perf。perf常用的热点函数定位命令如下:

  • 进程级:perf top -p
  • 线程级:perf top -t

线程tid可以通过pidstat -t -p 或者 top -p PID -H 获取。

DPDK程序设计不优

DPDK程序的实际CPU使用率没有达到100%,但依然偶尔会丢包,断续imissed++。一般这是因为出队速率抖动引发溢出,即出队最低速率小于入队平均速率,而收包队列的规格(几K)不足以缓存拥塞的报文。

解决

  • 异步处理
    将复杂处理由同步处理(Run-to-completion)改为异步处理(Pipeline),降低抖动。
  • 加软队列
    增加一级容量更大的软队列,缓存抖动(一般业务有按规则分发的需要也需要构建一级软队列,软队列可能会或多或少增加报文处理的延时)。

比如:DPVS中设置单独的KNI处理线程来处理本机的流量。之前是Slave收到包,交给了Master来处理,而本身Master的任务就比较重,可能master正在进行大量配置的查询或者下发,此时可能影响到本机流量的处理。

CPU错误降频

如果CPU被降频,将直接影响出队性能。

现象

分析

在这里插入图片描述

解决

在这里插入图片描述

查看当前的CPU频率 与运行模式

在这里插入图片描述

在这里插入图片描述

如果当前运行在powersave模式下,可以将其修改为performance,提升CPU频率。

cpupower frequency-set -g performance。 

在这里插入图片描述

总结

出现 imiss,主要是由于 数据包被硬件丢弃。可能性分析如下:

  • 入队慢:
    pci-e 实际带宽慢。
  • 出队慢:
    1》程序性能不行;
    2》程序设计缺陷;
    3》cpu降频


参考

https://mp.weixin..com/s/jM7R-LXsLWbGXLlowxSw 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/137419.html

(0)
上一篇 2025-06-20 18:15
下一篇 2025-06-20 18:20

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信