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...


相关推荐
程序员岳焱1 小时前
Java 与 MySQL 性能优化:Java 实现百万数据分批次插入的最佳实践
后端·mysql·性能优化
麦兜*1 小时前
Spring Boot启动优化7板斧(延迟初始化、组件扫描精准打击、JVM参数调优):砍掉70%启动时间的魔鬼实践
java·jvm·spring boot·后端·spring·spring cloud·系统架构
大只鹅2 小时前
解决 Spring Boot 对 Elasticsearch 字段没有小驼峰映射的问题
spring boot·后端·elasticsearch
ai小鬼头2 小时前
AIStarter如何快速部署Stable Diffusion?**新手也能轻松上手的AI绘图
前端·后端·github
IT_10242 小时前
Spring Boot项目开发实战销售管理系统——数据库设计!
java·开发语言·数据库·spring boot·后端·oracle
bobz9653 小时前
动态规划
后端
stark张宇3 小时前
VMware 虚拟机装 Linux Centos 7.9 保姆级教程(附资源包)
linux·后端
亚力山大抵4 小时前
实验六-使用PyMySQL数据存储的Flask登录系统-实验七-集成Flask-SocketIO的实时通信系统
后端·python·flask
超级小忍4 小时前
Spring Boot 中常用的工具类库及其使用示例(完整版)
spring boot·后端
CHENWENFEIc5 小时前
SpringBoot论坛系统安全测试实战报告
spring boot·后端·程序人生·spring·系统安全·安全测试