DPDK收发包流程分析

news2024/11/17 1:44:55

一、 前言

       DPDK是intel工程师开发的一款用来快速处理数据包的框架,最初的目的是为了证明传统网络数据包处理性能低不是intel处理器导致的,而是传统数据的处理流程导致,后来随着dpdk的开源及其生态的快速发展,dpdk成为了高性能网络数据处理的优秀框架。本篇文章主要介绍DPDK接收与发送报文的流程,包括CPU与网卡DMA协同工作的整个交互流程、数据包在内存、CPU、网卡之间游走的过程。

                                                   【二、场景】

       DPDK从2013开始开源,经过前辈们的缝缝补补到现在为止DPDK框架比较成熟、使用比较方便,使得现在开发者在不需要深入了解底层数据包收发原理的情况下也可以做简单的项目开发。但是个人感觉做简单的项目尚且可以应付,如果需要做性能优化等类似的需求时就需要取全面的了解DPDK的收发包机制,因为收发包性能与驱动工作流程、前期初始化配置息息相关。话不多说,下面我们进入正题。

                                            【三、收发包处理流程】

  • 数据包接收的大体流程:
  1. 数据包到达网卡
  2. 网卡经过DMA操作将数据包从网卡拷贝到收包队列
  3. DPDK应用从收包队列中取包
  • 数据包发送的大体流程:
  1. DPDK应用将数据包送到发包队列
  2. 网卡经过DMA操作将网卡队列中的数据包拷贝到网卡
  3. 数据包从网卡发出
  • 收发包流程中的关键操作,主要是网卡如何与DPDK应用交互:
  1. 网卡的初始化配置操作有哪些,因为网卡要想正常工作肯定需要进行初始化配置一些属性
  2. 网卡的DMA操作怎么找到DMA 地址,进而将数据包拷贝到系统主存供DPDK读取
  3. 网卡把数据包成功放到队列后如何通知DPDK应用去队列中读取
  4. DPDK收发DPDK从队列中取完数据包后需要做哪些操作通知网卡为下一次收包做准备
  5. DPDK将数据包送到发送队列中需要做哪些预操作
  6. 网卡从发送队列中取包需要做哪些操作

                                        【四、收包软件处理流程】

DPDk在初始化阶段通过igb_alloc_rx_queue_mbufs 负责将描述符,mbuf, dma,接收队列给关联起来,如下图所示。初始化配置这块内容下篇讲

1、模块/硬件介绍

Network interface: 指以太网卡,它工作在OSI的下两层(物理层、数据链路层),工作在物理层的芯片称为PHY,工作在数据链路层的芯片称为MAC控制器,即Media Access Control,即媒体访问控制子层协议.该协议位于OSI七层协议中数据链路层的下半部分,但是目前好多网卡是将MAC和PHY功能做到了一颗芯片中,但是MAC和PHY的机制还是单独存在的,只是对外体现为一颗芯片。MAC控制器的功能主要是数据帧的构建、数据差错检查、传送控制、向网络层提供标准的数据接口等功能;PHY芯片的主要功能是将从PHY来的并行数据转换为穿行流数据,再按照物理层的编码规则把数字信号进行编码,最后再转换为模拟信号把数据发出去。

RX_FIFO: 数据接收缓冲区

TX_FIFO: 数据发送缓冲区

DMA Engine:Direct Memory Access,即直接寄存器访问,是一种高速的数据传输方式,允许在外部设备和存储器之间直接读写数据,数据的读写不消耗CPU资源。

DMA控制器通过一组描述符环形队列rx_ring)与CPU互相操作完成数据包的收发。CPU(cpu执行PMD驱动/程序)通过操作DMA寄存器来与DMA控制器进行部分通信与初始化配置,主要寄存器有Base、Size、Tail、Head。head寄存器用于DMA往rx_ring里插入时使用;tail是应用(PMD驱动)通过写寄存器通知给DMA控制器当前可用的最后一个描述符(head->next 为tail时表示当前rx_ring存满了,再来报文会被记录rx_missed_error)。

Rx_queue: 收包队列结构体:我们主要关注两个环形队列rx_ring、sw_ring

Rx_ring:一个地址连续环形队列,存储的是描述符,描述符中包含将来存放数据包的物理地址、DD标志(下面会介绍DD标志)等,上面图中只画了存放数据包的物理地址,物理地址供网卡DMA模块使用,也称为DMA地址(硬件使用物理地址,当网卡收到数据包后会通过DMA操作将数据包拷贝到物理地址,物理地址是通过虚拟地址转换得到的,下面分析源码时会介绍)

Sw_ring: 存储的是将来存放数据包的虚拟地址,虚拟地址供应用使用(软件应用使用虚拟地址,应用往虚拟地址读写数据包)

DD标志:用于标识一个描述符buf是否可用,无论网卡是工作在轮询方式下还是中断方式,判断数据包接收成功或者是否发送成功都需要检查描述符中的完成状态位(Description Done)DD,该状态位由DMA控制器在完成操作(从网卡FIFO接收队列到内存(收),或者从内存到网卡FIFO发送队列(发))后进行回写(设置为DD位为1(收),设置为0(发))

Mbuf:对应于Mbuf内存池中的元素,通过alloc或者free操作内存池获取或者释放mbuf对象,这里需要说的一点是mbuf池创建的时候是连续的,但是rx_ring和sw_ring里指向的数据地址不一定是连续的,下面分析收包流程时会介绍

PCIE总线:采用高速串行通信互联标准,自上而下分为事务传输层、数据链路层、物理层,网卡与CPU之间数据包的传输、CPU对网卡寄存器的MMIO操作都通过PCIE进行传输。

Tx_queue: 发包队列结构体:我们主要关注两个环形队列tx_ring、sw_ring.

tx_ring一个地址连续环形队列,存储的是描述符,描述符中包含将来存放数据包的物理地址、DD标志等,

DMA寄存器:CPU配置网卡的操作通过操作网卡的寄存器,网卡会通过DMA将报文放在系统内存中,另外,CPU(PMD驱动程序)配置网卡的操作也是通过操作网卡的寄存器(DMA寄存器)。存在几个问题:

网卡如何知道应该放在哪里呢?如何将网卡和系统内存关联起来?

这需要用到网卡的几个寄存器。

RDBAL(Receive Descriptor Base Address Low), RDBAH(Receive Descriptor Base Address High) RDLEN(Receive Descriptor Length) RDH(Receive Descriptor Head) RDT(Receive Descriptor Tail)。

PMD驱动初始化时会分配一块内存,将这块内存的起始物理地址(64位)写到寄存器。

RDBAL(保存起始物理地址的低32位)和RDBAH(保存物理地址的高32位),然后将这块内存的大小写到寄存器RDLEN中;这块内存称为硬件描述符队列(union ixgbe_adv_rx_desc 数组)。

硬件描述符队列大小 = 接收队列硬件描述符个数 * 接收队列硬件描述符大小。

一个接收队列硬件描述符大小为16字节( sizeof(union ixgbe_adv_rx_desc) ),个数可配置,一般为1024。

DD位的理解

DD标志,这个标志标识着一个描述符是否可用的情况。

  • 收包

网卡(DMA)在使用这个描述符前,先检查DD位是否为0,如果为0,那么就可以使用描述符,把数据拷贝到描述符指定的地址,之后把DD标志位置为1,否则表示不能使用这个描述符。

而对于PMD驱动而言,恰恰相反,在读取数据包时,先检查DD位是否为1,如果为1,表示网卡已经把数据放到了内存中,可以读取,读取完后,再把DD位设置为0,否则,就表示没有数据包可读。

网卡与内存关联

接收硬件描述符

接收硬件描述符,数据结构如下所示:

  • 接收接收描述符的格式分析

一个描述符(union ixgbe_adv_rx_desc)有两种格式;如下所示:

  • 接收接收描述符

读格式(union ixgbe_adv_rx_desc 中的read)

读格式是从网卡(DMA)角度来说的,由PMD驱动将mbuf的物理地址写到packet buffer address字段(pkt_addr),网卡(DMA)读取此字段获取内存物理地址,收到的报文就可以存到此内存。

回写格式(union ixgbe_adv_rx_desc 中的 wb「write-back」)

回写格式也是从网卡(DMA)角度来说,网卡(DMA)将报文写到指定的内存后,就会以下面的格式将报文的相关信息回写到描述符(union ixgbe_adv_rx_desc)中,最后设置DD位(第二个8字节的最低位);PMD驱动程序通过判断DD位是否为1来接收报文(DD位为1,说明DMA将报文放入到内存了,PMD驱动可以接收报文)。

总结:

接收队列硬件描述符队列就是一块内存。

网卡先以读格式,读取描述符,获取内存的物理地址,将报文写到内存;

然后以回写格式将报文额外信息写到描述符中;

PMD驱动程序可以以回写格式读取描述符,获取报文的长度,类型等信息。

收包流程

接收报文时需要将网卡和内存关联起来,即将要将要存放报文的地址告诉网卡,这是通过接收硬件描述符来实现的。

接收报文时需要将网卡和内存关联起来,即将要将要存放报文的地址告诉网卡,这是通过接收硬件描述符来实现的。

PMD驱动/程序收包

RDH/RDT寄存器

网卡和内存关联起来后,就可以收取报文了,此时又用到两个寄存器: RDH(Receive Descriptor Head)和RDT(Receive Descriptor Tail)。

RDH:

RDH为头指针,指向第一个可用描述符。

网卡收取报文并且DMA回写成功后,由网卡(DMA)来移动RDH到下一个可用描述符。

RDT:

RDT为尾指针,指向最后一个可用描述符。

RDH和RDT之间的描述符为网卡可用描述符,RDT由PMD驱动来移动。

PMD驱动从第一个描述符开始,轮询DD位是否为1,为1就认为此描述符对应的mbuf有报文,此时会申请新的mbuf,将新mbuf物理地址写到此描述符的pkt_addr,并将DD位置0,这样的话此描述符就又可用被网卡使用了;同时将老的有报文的mbuf返回给用户。

描述符再次可用后,PMD驱动就可以更新RDT指向此描述符,为了性能考虑不会每次都会更新RDT,而是等可用描述符超过一定阈值(rx_free_thresh)才更新一次(PMD驱动/CPU通过写RDT寄存器来更新)。

收包大致流程:

DMA从描述符队列(rx_ring数组)的可用位置(union ixgbe_adv_rx_desc类型)获取到mbuf的硬件地址;

然后将数据包从网卡FIFO写入到指定的硬件地址中(对应sw_ring数组的某个mbuf元素);设置对应描述符的DD位以及其他的信息(比如Rss hash,pkt-len等);(DD位为1表示当前描述符被占用了,接下来DMA将包放入到下一个可用描述符中指定的硬件地址中)

最后发送一个硬件中断(对于DPDK,屏幕了中断,PMD驱动程序通过轮询的方式检查是否有包到达)。

2、收包流程

Rx_ring收数据时的状态如下:


DMA控制器收到数据后往head写,当head=tail时表示当前队列为空,head->bext = tail表示当前队列已存满,dpdk启动刚初始化完后如下图所示:

1> dpdk启动刚初始化完后,如下图所示:


2> 收取数据包,网卡DMA 移动head


可以看出来cpu对tail寄存器的更新并不是在rx_ring描述符中填充完dma地址后立马就执行,而是等dma可用描述符低于一定阈值时才执行写寄存器更新tail

3> 应用程序(PMD驱动)取包:


4>驱动继续取包: 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1113492.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

游戏动态库缺失

缺哪个动态库就搜哪个,再下载下来。 百度网盘:链接:https://pan.baidu.com/s/1TlxLtL3hg_iCCvtCzT7bXw 提取码:8888 文件下载完之后要放到指定的位置 C:\Windows\System32

怎么在爬虫中使用ip代理服务器,爬虫代理IP的好处有哪些?

随着互联网的快速发展,网络爬虫已经成为数据采集、分析和整理的重要工具。然而,随着网络技术的不断发展,许多网站都会采取反爬虫措施,以避免数据被恶意获取。在这种情况下,代理IP服务器就成为了爬虫们的必本备文工将具…

Flink学习---15、FlinkCDC(CDC介绍、案例实操)

星光下的赶路人star的个人主页 未来总是藏在迷雾中让人胆怯,但当你踏入其中,便会云开雾散 文章目录 1、CDC简介1.1 什么是CDC1.2 CDC的种类1.3 Flink-CDC 2、FlinkCDC案例实操2.1 开启MySQL Binlog并重启MySQL2.2 FlinkSQL方式的应用2.2.1 导入依赖2.2.2…

jadx的使用

这篇文章主要介绍下jadx的使用。 1:下载安装 开源地址如下: https://github.com/skylot/jadx 当前最新的版本是1.4.7: https://github.com/skylot/jadx/releases/tag/v1.4.7 2:使用jadx mac/linux 使用jadx-gui.windows使用…

2023年中国光模块行业研究报告

第一章 行业概况 1.1 行业简介 光模块行业是光纤通信技术发展的重要组成部分,作为连接光纤通信网络的基础设备,光模块为数据传输提供了必要的硬件支持。光模块是光纤通信系统核心器件之一,它包括多种模块类别,例如光接收模块、光…

Random与random的区别

Random与random的区别 前言一、Rondom二、rondom三、使用Rondom的好处 前言 Rondom和raodom都可以表示随机数,下面是详细讲解 提示:以下是本篇文章正文内容,下面案例可供参考 一、Rondom Rondom是Java中的一个类,若需要生成随机…

在URP管线中添加ShaderMaterial自定义GUI的方法

编写GUI面板 1. 新建GUI子面板 using UnityEngine; using UnityEngine.Rendering;namespace UnityEditor.Rendering.Universal.ShaderGUI {internal class CP_XXXOutLineGUI{public static class Styles{}public struct LitProperties{public LitProperties(MaterialProperty…

速卖通,国际站测评补单用什么环境,买家账号不会被风控,F号

我们做自养号测评、补单首先要解决的就是安全性的问题,如果安全性解决的不了的话,其他的都不要再提了。目前我们的成号率可以稳定在9.8成以上,基本上0砍单封号 市面上的环境有: 1.虚拟机V2;三四年前的环境方案了&…

6. 加载栅格(raster)图层

文章目录 前言加载栅格(raster)图层gdalGeoTiffQGis导入tif代码添加 GeoPackageQGis导入代码导入 wms在线高德影像地图QGis添加在线高德影像代码添加 离线高德影像地图瓦片原理服务描述XML文件QGis导入离线地图代码导入 前言 本章讲述使用qgis c Api加载栅格地图数据并显示。 …

卡通人像制作就是这么简单

1、打开提示词生成器。 Prompt Generatorhttps://remaker.ai/userspace/prompt-generator/2、按下面截图设置。 3、复制英文提示。 4、打开画图链接。 https://poe.com/chat/https://poe.com/chat/ 5、输入提示词,按回车。 female,wide eyes,lipstick,fox ears,b…

解决一则诡异的javascript函数不执行的问题

有个vue 音乐播放器项目,由于之前腾讯的搜索接口没法用了,于是改成了别家的搜索接口。 但是由于返回数据结构不一样,代码重构的工作量还是挺大的:包括数据请求,数据处理,dom渲染,处理逻辑都进行…

C++算法:二叉树的序列化与反序列化

#题目 序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。 请设计一个算法来实现二叉树的序列化与反序列化。…

golang的json转pb验证

基于这篇文章的最后一个代码进行验证。 https://blog.csdn.net/mijichui2153/article/details/133894403?csdn_share_tail%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22133894403%22%2C%22source%22%3A%22mijichui2153%22%7D 1、准备 &…

gs_moment

ps:仅共学习,自用。

OpenGL —— 2.7、绘制多个自旋转的贴图正方体(附源码,glfw+glad)

源码效果 C源码 纹理图片 需下载stb_image.h这个解码图片的库,该库只有一个头文件。 具体代码: vertexShader.glsl #version 330 corelayout(location 0) in vec3 aPos; layout(location 1) in vec2 aUV;out vec2 outUV;uniform mat4 _modelMatrix; …

抽象数据库

在刚刚的文章中,完成了无范式到三级范式的过程 : 遵循原子性。即,表中字段的数据,不可以再拆分。 在满足第一范式的情况下,遵循唯一性,消除部分依赖。即,表中任意一个主键或任意一组联合主键&#xff0c…

计算几何+2sat:1020T3

http://cplusoj.com/d/senior/p/SS231019C 我们进行这样的转化 则0/1必选一个,2/3必选一个 那么就变成一个2sat问题 两三角形有交,则一个选,一个不能选 对角三角形一个选,一个不选。一个不选,一个选 三角形不合法…

体感互动游戏研发虚拟场景3D漫游

体感互动游戏是一种结合虚拟现实(VR)或增强现实(AR)技术的游戏,允许玩家以身体动作和姿势来与游戏互动。这种类型的游戏通常需要特殊的硬件设备,例如体感控制器、摄像头或传感器,以捕捉玩家的动…

spring cloud alibaba 集成seata

1.启动服务端 1.下载 seata-server-1.4.2 2.创建数据库 DROP DATABASE IF EXISTS ry-seata;CREATE DATABASE ry-seata DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0;USE ry-seata;-- ---------------------------…

Java操作Python数据交互最佳实践

Java操作Python最佳实践 1、Java与Python的互操作性2、Java调用Python脚本及数据交互2.1、准备工作2.2、执行一段Python代码2.3、执行Python文件脚本2.4、执行Python文件中的指定方法2.5、执行含有第三方库的Python文件3、附录1、Java与Python的互操作性 在当今的软件开发领域,…