DPDK dmadev lib学习

前言

dmadev lib顾名思义就是用来使用dma设备的框架,伴随着摩尔定律的失效,现在CPU的性能几乎很难进行提升了。那么提高性能的方式就只能是软件不够硬件来凑了,让许多工作从CPU卸载到硬件去。 dmadev lib库是DPDK中的一个软件库,提供管理和配置DMA poll mode drivers的软件,定义了统一的操作接口。支持一系列不同的DMA操作。

功能介绍

设计约束

库支持物理的(硬件)和虚拟的(软件)DMA设备。

DMA框架的组成如上图所示:

  1. DMA控制器有多个硬件的DMA通道(队列),每个硬件DMA通道呈现为一个dmadev。
  2. dmadev可以创建多个虚拟的DMA通道,每个虚拟DMA通道呈现为不通的transfer context, 比如virtual DMA channel 0 用作memory-to-memory场景,而virtual dma channel 1用作 memory-to-device场景。
  3. DMA操作必须提交给虚拟DMA通道。

设备管理

设备创建

物理的DMA controller在DPDK初始化时,由PCI扫描枚举出来,基于设备的BDF(bus、device、function)。其他物理DMA controller可以在DPDK命令行中指定。 dmadev由rte_dma_pmd_allocate函数根据物理DMA channel的个数创建。

设备标识

每个DMA(不论是物理还是虚拟的)设备由2个id唯一标识。

  1. 一个唯一的设备索引,用在DMA API接口中指派dma设备。
  2. 一个设备名,用在串口信息或者管理调试。

设备特性和能力

不同的dma设备可能支持不一样的特性,rte_dma_info_get API可以获取设备信息和支持的特性。 Silent mode是一种特殊的设备能力,这种设备不需要应用调用dequeue APIs。

出入队接口

DPDK主要基于轮询的方式操作,因此所有的pmd都会有出入队的接口。 Enqueue API 可以把操作传递到设备,这样的接口有rte_dma_copy和rte_dma_fill。如果入队成功,会返回一个ring_idx。ring_idx可以让应用知道到其环中定为操作的元信息。如果入队失败ring_idx是一个负值。 rte_dma_submit用于发送一个doorbell通知硬件。也可以在入队的时候,带上RTE_DMA_OP_FLAG_SUBMIT 标记自动发送doorbell通知硬件。

下面的代码描述如何入队多个拷贝操作到设备,并启动硬件进行操作。

c 复制代码
struct rte_mbuf *srcs[DMA_BURST_SZ], *dsts[DMA_BURST_SZ];
unsigned int i;

for (i = 0; i < RTE_DIM(srcs); i++) {
   if (rte_dma_copy(dev_id, vchan, rte_pktmbuf_iova(srcs[i]),
         rte_pktmbuf_iova(dsts[i]), COPY_LEN, 0) < 0) {
      PRINT_ERR("Error with rte_dma_copy for buffer %u\n", i);
      return -1;
   }
}
rte_dma_submit(dev_id, vchan);

rte_dma_completed 和rte_dma_completed_status接口用于出队获取操作的结果。rte_dma_completed用于获取成功的个数,rte_dma_completed_status返回个数以及每个操作的执行状态(存放到一个status数组中)。这两个接口还会返回最后一个操作的ring_idx。

查询设备统计

使用rte_dma_stats_get()接口获取dmadev的统计信息,包含每个设备的如下数据: Submitted: 提交的操作数量 Completed:已完成的操作数量(包含成功的和失败的) Errors:完成发送错误的数量 库也支持调试接口显示相关信息:

注意点

设备使用前需要进行配置,然后再开始使用:

c 复制代码
rte_dma_configure()
rte_dma_vchan_setup()
rte_dma_start()

修改配置

可以调用rte_dma_configure() or rte_dma_vchan_setup(), 但前提要先调用rte_dma_stop(),配置完后rte_dma_start()开始。设备停止状态下,不要往设备发送操作。

关闭设备

使用完毕需要调用rte_dma_close关闭设备。

提交操作

先入队再发送doorbell给硬件。

c 复制代码
rte_dma_copy()
rte_dma_copy_sg(
rte_dma_fill()
rte_dma_submit()

ring_idx说明

    1. 每个virtual dma channel的ring_idx是独立的
    1. ring_idx是单调递增的数,直到UINT16_MAX才回到0
    1. ring_idx初始时是0,如果设备停止了,需要重置ring_idx

操作地址

操作内部的地址类型为rte_iova_t。 dmadev支持两种类型的地址: 内存地址和设备地址。

    1. 内存地址:memory-to-memory操作的源目地址,memory-to-device的源地址, device-to-memory操作的目的地址,如果设备支持SVA,那么这种地址可以是VA,否则必须是IOVA。
    1. 设备地址:memory-to-device的目的地址,device-to-memory操作的源地址

其他

所有的API都是不加锁的,不支持多个线程并发访问,不考虑多个同时调用同一个dmadev。 同一个dmadev的virtual dma channel也不支持同时调用,因为这些channel共用同一个硬件的dma channel。

更多

初步了解一下dma引擎在DPDK中的使用框架。很多公司已经实现了其dma引擎,在大数据、虚拟化等方面开始应用了。


行动,才不会被动!

欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。

博客地址: fishmwei.github.io

掘金主页: juejin.cn/user/208432...


相关推荐
hdsoft_huge15 分钟前
1panel面板中部署SpringBoot和Vue前后端分离系统 【图文教程】
vue.js·spring boot·后端
lekami_兰44 分钟前
RabbitMQ 延迟队列实现指南:两种方案手把手教你搞定
后端·rabbitmq·延迟队列
程序员泠零澪回家种桔子1 小时前
Sentinel核心能力解析:限流与集群方案
后端·架构·sentinel
信码由缰1 小时前
Spring Boot 面试问题
spring boot·后端·面试
一路向北⁢1 小时前
Spring Boot 3 整合 SSE (Server-Sent Events) 企业级最佳实践(三)
java·spring boot·后端·sse
qq_297574672 小时前
SpringBoot项目长时间未访问,Tomcat临时文件夹被删除?解决方案来了
spring boot·后端·tomcat
一个有梦有戏的人2 小时前
Python3基础:函数基础,解锁模块化编程新技能
后端·python
逍遥德2 小时前
Sring事务详解之02.如何使用编程式事务?
java·服务器·数据库·后端·sql·spring
qq_2975746711 小时前
【实战教程】SpringBoot 实现多文件批量下载并打包为 ZIP 压缩包
java·spring boot·后端